summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.prebuilt_info/OWNERS1
-rw-r--r--Android.bp9
-rw-r--r--TEST_MAPPING62
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java2
-rw-r--r--apex/jobscheduler/framework/java/android/app/job/JobInfo.java3
-rw-r--r--apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java4
-rw-r--r--apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java626
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java98
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java8
-rw-r--r--apex/media/framework/api/system-current.txt4
-rw-r--r--apex/media/framework/java/android/media/MediaTranscodeManager.java49
-rw-r--r--api/Android.bp46
-rw-r--r--core/api/current.txt2597
-rw-r--r--core/api/module-lib-current.txt15
-rw-r--r--core/api/system-current.txt80
-rw-r--r--core/api/test-current.txt23
-rw-r--r--core/java/android/accessibilityservice/AccessibilityServiceInfo.java22
-rw-r--r--core/java/android/app/ActivityThread.java13
-rw-r--r--core/java/android/app/ApplicationPackageManager.java19
-rw-r--r--core/java/android/app/ContextImpl.java5
-rw-r--r--core/java/android/app/LoadedApk.java4
-rw-r--r--core/java/android/app/Notification.java275
-rw-r--r--core/java/android/app/WallpaperManager.java25
-rw-r--r--core/java/android/app/WindowTokenClient.java8
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java5
-rw-r--r--core/java/android/appwidget/AppWidgetHostView.java2
-rw-r--r--core/java/android/bluetooth/BluetoothA2dp.java6
-rw-r--r--core/java/android/content/Context.java9
-rw-r--r--core/java/android/content/ContextParams.java48
-rw-r--r--core/java/android/content/Intent.java27
-rw-r--r--core/java/android/content/pm/ActivityInfo.java51
-rw-r--r--core/java/android/graphics/fonts/FontFamilyUpdateRequest.java46
-rw-r--r--core/java/android/hardware/display/AmbientDisplayConfiguration.java15
-rw-r--r--core/java/android/hardware/display/DisplayManager.java3
-rw-r--r--core/java/android/hardware/face/FaceManager.java23
-rw-r--r--core/java/android/hardware/fingerprint/FingerprintManager.java11
-rw-r--r--core/java/android/hardware/hdmi/HdmiControlManager.java15
-rw-r--r--core/java/android/hardware/location/ContextHubManager.java11
-rw-r--r--core/java/android/inputmethodservice/IInputMethodWrapper.java7
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java44
-rw-r--r--core/java/android/net/EthernetNetworkSpecifier.java97
-rw-r--r--core/java/android/net/NetworkIdentity.java15
-rw-r--r--core/java/android/net/VpnManager.java7
-rw-r--r--core/java/android/net/vcn/VcnControlPlaneIkeConfig.java42
-rw-r--r--core/java/android/net/vcn/persistablebundleutils/CertUtils.java22
-rw-r--r--core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java513
-rw-r--r--core/java/android/os/FileUtils.java20
-rw-r--r--core/java/android/os/PowerManager.java7
-rw-r--r--core/java/android/os/StrictMode.java5
-rw-r--r--core/java/android/os/incremental/IIncrementalService.aidl10
-rw-r--r--core/java/android/os/incremental/IncrementalFileStorages.java7
-rw-r--r--core/java/android/os/storage/StorageManagerInternal.java5
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/java/android/service/autofill/AutofillServiceInfo.java35
-rw-r--r--core/java/android/service/rotationresolver/RotationResolutionRequest.java216
-rw-r--r--core/java/android/speech/IRecognitionServiceManager.aidl2
-rw-r--r--core/java/android/speech/SpeechRecognizer.java121
-rw-r--r--core/java/android/telephony/PhoneStateListener.java6
-rw-r--r--core/java/android/telephony/TelephonyCallback.java48
-rw-r--r--core/java/android/telephony/TelephonyRegistryManager.java5
-rw-r--r--core/java/android/util/FeatureFlagUtils.java2
-rw-r--r--core/java/android/view/Display.java270
-rw-r--r--core/java/android/view/DisplayInfo.java19
-rw-r--r--core/java/android/view/InputEventReceiver.java10
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureManager.java2
-rw-r--r--core/java/android/view/inputmethod/InputMethod.java2
-rw-r--r--core/java/android/view/inputmethod/InputMethodInfo.java51
-rw-r--r--core/java/android/view/textclassifier/TextClassificationConstants.java5
-rw-r--r--core/java/android/view/translation/UiTranslationController.java84
-rw-r--r--core/java/android/view/translation/UiTranslationManager.java8
-rw-r--r--core/java/android/widget/EdgeEffect.java183
-rw-r--r--core/java/android/widget/TextView.java19
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java2
-rw-r--r--core/java/com/android/internal/graphics/palette/Mean.java9
-rw-r--r--core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java23
-rw-r--r--core/java/com/android/internal/graphics/palette/WuQuantizer.java15
-rw-r--r--core/java/com/android/internal/jank/FrameTracker.java31
-rw-r--r--core/java/com/android/internal/os/BinderCallsStats.java24
-rw-r--r--core/java/com/android/internal/os/SelectedProcessCpuThreadReader.java57
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java6
-rw-r--r--core/java/com/android/internal/protolog/BaseProtoLogImpl.java12
-rw-r--r--core/java/com/android/internal/security/OWNERS3
-rw-r--r--core/java/com/android/internal/security/TEST_MAPPING (renamed from services/core/java/com/android/server/security/TEST_MAPPING)0
-rw-r--r--core/java/com/android/internal/security/VerityUtils.java (renamed from services/core/java/com/android/server/security/VerityUtils.java)14
-rw-r--r--core/java/com/android/internal/telephony/IPhoneStateListener.aidl3
-rw-r--r--core/java/com/android/internal/util/LatencyTracker.java2
-rw-r--r--core/java/com/android/internal/util/ScreenRecordHelper.java49
-rw-r--r--core/java/com/android/internal/view/IInputMethod.aidl3
-rw-r--r--core/java/com/android/internal/widget/ImageFloatingTextView.java67
-rw-r--r--core/jni/Android.bp7
-rw-r--r--core/jni/AndroidRuntime.cpp4
-rw-r--r--core/jni/android_media_AudioRecord.cpp25
-rw-r--r--core/jni/android_media_AudioSystem.cpp68
-rw-r--r--core/jni/android_media_AudioTrack.cpp14
-rw-r--r--core/jni/android_view_InputEventReceiver.cpp15
-rw-r--r--core/jni/android_view_InputEventSender.cpp28
-rw-r--r--core/jni/com_android_internal_os_KernelCpuBpfTracking.cpp8
-rw-r--r--core/jni/com_android_internal_os_KernelCpuTotalBpfMapReader.cpp4
-rw-r--r--core/jni/com_android_internal_os_KernelCpuUidBpfMapReader.cpp20
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp40
-rw-r--r--core/jni/com_android_internal_security_VerityUtils.cpp (renamed from services/core/jni/com_android_server_security_VerityUtils.cpp)14
-rw-r--r--core/jni/permission_utils.cpp71
-rw-r--r--core/jni/permission_utils.h27
-rw-r--r--core/proto/android/app/OWNERS2
-rw-r--r--core/proto/android/app/location_time_zone_manager.proto10
-rw-r--r--core/proto/android/app/time_zone_detector.proto59
-rw-r--r--core/res/AndroidManifest.xml16
-rw-r--r--core/res/res/layout/notification_template_text_multiline.xml2
-rw-r--r--core/res/res/values-af/strings.xml33
-rw-r--r--core/res/res/values-am/strings.xml33
-rw-r--r--core/res/res/values-ar/strings.xml35
-rw-r--r--core/res/res/values-as/strings.xml33
-rw-r--r--core/res/res/values-az/strings.xml33
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml33
-rw-r--r--core/res/res/values-be/strings.xml33
-rw-r--r--core/res/res/values-bg/strings.xml33
-rw-r--r--core/res/res/values-bn/strings.xml33
-rw-r--r--core/res/res/values-bs/strings.xml33
-rw-r--r--core/res/res/values-ca/strings.xml33
-rw-r--r--core/res/res/values-cs/strings.xml33
-rw-r--r--core/res/res/values-da/strings.xml33
-rw-r--r--core/res/res/values-de/strings.xml33
-rw-r--r--core/res/res/values-el/strings.xml33
-rw-r--r--core/res/res/values-en-rAU/strings.xml33
-rw-r--r--core/res/res/values-en-rCA/strings.xml33
-rw-r--r--core/res/res/values-en-rGB/strings.xml33
-rw-r--r--core/res/res/values-en-rIN/strings.xml33
-rw-r--r--core/res/res/values-es-rUS/strings.xml37
-rw-r--r--core/res/res/values-es/strings.xml33
-rw-r--r--core/res/res/values-et/strings.xml33
-rw-r--r--core/res/res/values-eu/strings.xml41
-rw-r--r--core/res/res/values-fa/strings.xml33
-rw-r--r--core/res/res/values-fi/strings.xml33
-rw-r--r--core/res/res/values-fr-rCA/strings.xml33
-rw-r--r--core/res/res/values-fr/strings.xml33
-rw-r--r--core/res/res/values-gl/strings.xml33
-rw-r--r--core/res/res/values-gu/strings.xml33
-rw-r--r--core/res/res/values-hi/strings.xml33
-rw-r--r--core/res/res/values-hr/strings.xml33
-rw-r--r--core/res/res/values-hu/strings.xml33
-rw-r--r--core/res/res/values-hy/strings.xml33
-rw-r--r--core/res/res/values-in/strings.xml33
-rw-r--r--core/res/res/values-is/strings.xml33
-rw-r--r--core/res/res/values-it/strings.xml33
-rw-r--r--core/res/res/values-iw/strings.xml33
-rw-r--r--core/res/res/values-ja/strings.xml33
-rw-r--r--core/res/res/values-ka/strings.xml33
-rw-r--r--core/res/res/values-kk/strings.xml33
-rw-r--r--core/res/res/values-km/strings.xml33
-rw-r--r--core/res/res/values-kn/strings.xml33
-rw-r--r--core/res/res/values-ko/strings.xml35
-rw-r--r--core/res/res/values-ky/strings.xml33
-rw-r--r--core/res/res/values-lo/strings.xml33
-rw-r--r--core/res/res/values-lt/strings.xml33
-rw-r--r--core/res/res/values-lv/strings.xml33
-rw-r--r--core/res/res/values-mk/strings.xml35
-rw-r--r--core/res/res/values-ml/strings.xml33
-rw-r--r--core/res/res/values-mn/strings.xml33
-rw-r--r--core/res/res/values-ms/strings.xml33
-rw-r--r--core/res/res/values-my/strings.xml33
-rw-r--r--core/res/res/values-nb/strings.xml33
-rw-r--r--core/res/res/values-ne/strings.xml33
-rw-r--r--core/res/res/values-nl/strings.xml33
-rw-r--r--core/res/res/values-or/strings.xml33
-rw-r--r--core/res/res/values-pl/strings.xml33
-rw-r--r--core/res/res/values-pt-rBR/strings.xml33
-rw-r--r--core/res/res/values-pt-rPT/strings.xml33
-rw-r--r--core/res/res/values-pt/strings.xml33
-rw-r--r--core/res/res/values-ro/strings.xml33
-rw-r--r--core/res/res/values-ru/strings.xml33
-rw-r--r--core/res/res/values-sk/strings.xml33
-rw-r--r--core/res/res/values-sl/strings.xml33
-rw-r--r--core/res/res/values-sq/strings.xml33
-rw-r--r--core/res/res/values-sr/strings.xml33
-rw-r--r--core/res/res/values-sv/strings.xml33
-rw-r--r--core/res/res/values-sw/strings.xml33
-rw-r--r--core/res/res/values-ta/strings.xml33
-rw-r--r--core/res/res/values-te/strings.xml33
-rw-r--r--core/res/res/values-th/strings.xml33
-rw-r--r--core/res/res/values-tl/strings.xml33
-rw-r--r--core/res/res/values-tr/strings.xml33
-rw-r--r--core/res/res/values-uk/strings.xml33
-rw-r--r--core/res/res/values-ur/strings.xml33
-rw-r--r--core/res/res/values-uz/strings.xml2
-rw-r--r--core/res/res/values-vi/strings.xml33
-rw-r--r--core/res/res/values-zh-rCN/strings.xml33
-rw-r--r--core/res/res/values-zh-rHK/strings.xml33
-rw-r--r--core/res/res/values-zh-rTW/strings.xml33
-rw-r--r--core/res/res/values-zu/strings.xml33
-rw-r--r--core/res/res/values/attrs.xml19
-rw-r--r--core/res/res/values/config.xml5
-rw-r--r--core/res/res/values/dimens.xml2
-rw-r--r--core/res/res/values/policy_exempt_apps.xml24
-rw-r--r--core/res/res/values/public.xml4
-rw-r--r--core/res/res/values/strings.xml12
-rw-r--r--core/res/res/values/symbols.xml8
-rw-r--r--core/res/res/values/vendor_policy_exempt_apps.xml24
-rw-r--r--core/tests/coretests/src/android/content/pm/PackageManagerTests.java9
-rw-r--r--core/tests/coretests/src/android/inputmethodservice/InputMethodServiceTest.java83
-rw-r--r--core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java4
-rw-r--r--core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java14
-rw-r--r--core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java65
-rw-r--r--core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java2
-rw-r--r--core/tests/mockingcoretests/src/android/view/DisplayTests.java531
-rw-r--r--data/etc/services.core.protolog.json24
-rw-r--r--data/keyboards/Vendor_0957_Product_0001.idc1
-rw-r--r--data/keyboards/Vendor_248a_Product_8266.idc24
-rw-r--r--graphics/java/android/graphics/drawable/RippleAnimationSession.java133
-rw-r--r--graphics/java/android/graphics/drawable/RippleDrawable.java73
-rw-r--r--graphics/java/android/graphics/drawable/RippleShader.java172
-rw-r--r--keystore/java/android/security/AndroidKeyStoreMaintenance.java8
-rw-r--r--keystore/java/android/security/keystore/AttestationUtils.java55
-rw-r--r--keystore/java/android/security/keystore/KeyGenParameterSpec.java10
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java36
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt8
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt2
-rw-r--r--libs/androidfw/Android.bp2
-rw-r--r--libs/hwui/Android.bp3
-rw-r--r--libs/hwui/utils/PaintUtils.h12
-rw-r--r--media/Android.bp3
-rw-r--r--media/aidl/android/media/permission/Identity.aidl8
-rw-r--r--media/java/android/media/AudioManager.java49
-rw-r--r--media/java/android/media/AudioRecord.java92
-rw-r--r--media/java/android/media/AudioSystem.java6
-rw-r--r--media/java/android/media/MediaPlayer.java12
-rw-r--r--media/java/android/media/MediaRecorder.java40
-rw-r--r--media/java/android/media/MediaRouter2.java211
-rw-r--r--media/java/android/media/MediaRouter2Manager.java30
-rw-r--r--media/java/android/media/audiofx/AudioEffect.java9
-rw-r--r--media/java/android/media/audiofx/Visualizer.java10
-rw-r--r--media/java/android/media/metrics/NetworkEvent.java5
-rw-r--r--media/java/android/media/metrics/PlaybackErrorEvent.java4
-rw-r--r--media/java/android/media/metrics/PlaybackMetrics.java4
-rw-r--r--media/java/android/media/metrics/PlaybackStateEvent.java4
-rw-r--r--media/java/android/media/metrics/TrackChangeEvent.java2
-rw-r--r--media/java/android/media/permission/PermissionUtil.java22
-rw-r--r--media/jni/Android.bp4
-rw-r--r--media/jni/android_media_MediaPlayer.cpp11
-rw-r--r--media/jni/android_media_MediaRecorder.cpp10
-rw-r--r--media/jni/audioeffect/Android.bp5
-rw-r--r--media/jni/audioeffect/Visualizer.cpp4
-rw-r--r--media/jni/audioeffect/Visualizer.h5
-rw-r--r--media/jni/audioeffect/android_media_AudioEffect.cpp11
-rw-r--r--media/jni/audioeffect/android_media_Visualizer.cpp9
-rw-r--r--media/jni/soundpool/Android.bp5
-rw-r--r--media/jni/soundpool/Stream.cpp11
-rw-r--r--packages/CompanionDeviceManager/res/values-af/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-am/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ar/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-as/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-az/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-be/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-bg/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-bn/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-bs/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ca/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-cs/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-da/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-de/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-el/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rAU/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rCA/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rGB/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rIN/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rXC/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-es-rUS/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-es/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-et/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-eu/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-fa/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-fi/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-fr/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-gl/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-gu/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-hi/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-hr/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-hu/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-hy/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-in/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-is/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-it/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-iw/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ja/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ka/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-kk/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-km/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-kn/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ko/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ky/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-lo/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-lt/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-lv/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-mk/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ml/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-mn/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-mr/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ms/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-my/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-nb/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ne/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-nl/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-or/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-pa/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-pl/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-pt/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ro/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ru/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-si/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-sk/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-sl/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-sq/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-sr/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-sv/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-sw/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ta/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-te/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-th/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-tl/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-tr/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-uk/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-ur/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-uz/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-vi/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values-zu/strings.xml12
-rw-r--r--packages/CompanionDeviceManager/res/values/strings.xml8
-rw-r--r--packages/Connectivity/framework/api/module-lib-current.txt8
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkRequest.java17
-rw-r--r--packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java97
-rw-r--r--packages/Connectivity/service/Android.bp19
-rw-r--r--packages/Connectivity/service/jarjar-rules.txt14
-rw-r--r--packages/CtsShim/build/shim/AndroidManifest.xml3
-rw-r--r--packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java38
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp4
-rw-r--r--packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down.xml (renamed from packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml)8
-rw-r--r--packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml16
-rw-r--r--packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_dropdown_background.xml33
-rw-r--r--packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_dropdown_view.xml25
-rw-r--r--packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml4
-rw-r--r--packages/SettingsLib/SettingsSpinner/res/values/dimens.xml (renamed from packages/SystemUI/res/drawable/controls_dialog_bg.xml)13
-rw-r--r--packages/SettingsLib/SettingsSpinner/res/values/styles.xml10
-rw-r--r--packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java9
-rw-r--r--packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java3
-rw-r--r--packages/SettingsLib/SettingsTheme/Android.bp4
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java5
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/SystemUI/AndroidManifest.xml15
-rw-r--r--packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml37
-rw-r--r--packages/SystemUI/res/drawable/qs_footer_action_chip_background_borderless.xml35
-rw-r--r--packages/SystemUI/res/layout/auth_biometric_contents.xml18
-rw-r--r--packages/SystemUI/res/layout/controls_detail_dialog.xml7
-rw-r--r--packages/SystemUI/res/layout/controls_fullscreen.xml (renamed from packages/SystemUI/res/layout/controls_in_dialog.xml)5
-rw-r--r--packages/SystemUI/res/layout/controls_with_favorites.xml15
-rw-r--r--packages/SystemUI/res/layout/people_space_activity.xml17
-rw-r--r--packages/SystemUI/res/layout/people_space_placeholder_layout.xml75
-rw-r--r--packages/SystemUI/res/layout/qs_carrier.xml14
-rw-r--r--packages/SystemUI/res/layout/qs_footer_impl.xml2
-rw-r--r--packages/SystemUI/res/layout/qs_footer_impl_two_lines.xml159
-rw-r--r--packages/SystemUI/res/layout/qs_panel.xml5
-rw-r--r--packages/SystemUI/res/values/colors.xml1
-rw-r--r--packages/SystemUI/res/values/config.xml8
-rw-r--r--packages/SystemUI/res/values/dimens.xml9
-rw-r--r--packages/SystemUI/res/values/flags.xml2
-rw-r--r--packages/SystemUI/res/values/strings.xml82
-rw-r--r--packages/SystemUI/res/values/styles.xml44
-rw-r--r--packages/SystemUI/res/xml/people_space_widget_info.xml5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/SwipeHelper.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java278
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java63
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt86
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialog.kt91
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt76
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeLog.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java94
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java283
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/AppWidgetOptionsHelper.java91
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java127
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleTileKey.java105
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt117
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/CropView.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java238
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java63
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java38
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java52
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java36
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java137
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt147
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt37
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java21
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java56
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java1
-rw-r--r--rs/java/android/renderscript/Allocation.java6
-rw-r--r--rs/java/android/renderscript/AllocationAdapter.java4
-rw-r--r--rs/java/android/renderscript/BaseObj.java4
-rw-r--r--rs/java/android/renderscript/Byte2.java4
-rw-r--r--rs/java/android/renderscript/Byte3.java4
-rw-r--r--rs/java/android/renderscript/Byte4.java4
-rw-r--r--rs/java/android/renderscript/Double2.java5
-rw-r--r--rs/java/android/renderscript/Double3.java5
-rw-r--r--rs/java/android/renderscript/Double4.java5
-rw-r--r--rs/java/android/renderscript/Element.java5
-rw-r--r--rs/java/android/renderscript/FieldPacker.java4
-rw-r--r--rs/java/android/renderscript/FileA3D.java1
-rw-r--r--rs/java/android/renderscript/Float2.java5
-rw-r--r--rs/java/android/renderscript/Float3.java5
-rw-r--r--rs/java/android/renderscript/Float4.java5
-rw-r--r--rs/java/android/renderscript/Font.java1
-rw-r--r--rs/java/android/renderscript/Int2.java5
-rw-r--r--rs/java/android/renderscript/Int3.java5
-rw-r--r--rs/java/android/renderscript/Int4.java5
-rw-r--r--rs/java/android/renderscript/Long2.java5
-rw-r--r--rs/java/android/renderscript/Long3.java5
-rw-r--r--rs/java/android/renderscript/Long4.java5
-rw-r--r--rs/java/android/renderscript/Matrix2f.java4
-rw-r--r--rs/java/android/renderscript/Matrix3f.java4
-rw-r--r--rs/java/android/renderscript/Matrix4f.java4
-rw-r--r--rs/java/android/renderscript/Mesh.java1
-rw-r--r--rs/java/android/renderscript/Program.java4
-rw-r--r--rs/java/android/renderscript/ProgramFragment.java1
-rw-r--r--rs/java/android/renderscript/ProgramFragmentFixedFunction.java1
-rw-r--r--rs/java/android/renderscript/ProgramRaster.java1
-rw-r--r--rs/java/android/renderscript/ProgramStore.java4
-rw-r--r--rs/java/android/renderscript/ProgramVertex.java2
-rw-r--r--rs/java/android/renderscript/ProgramVertexFixedFunction.java1
-rw-r--r--rs/java/android/renderscript/RSDriverException.java5
-rw-r--r--rs/java/android/renderscript/RSIllegalArgumentException.java5
-rw-r--r--rs/java/android/renderscript/RSInvalidStateException.java5
-rw-r--r--rs/java/android/renderscript/RSRuntimeException.java5
-rw-r--r--rs/java/android/renderscript/RSSurfaceView.java1
-rw-r--r--rs/java/android/renderscript/RSTextureView.java1
-rw-r--r--rs/java/android/renderscript/RenderScript.java5
-rw-r--r--rs/java/android/renderscript/RenderScriptCacheDir.java4
-rw-r--r--rs/java/android/renderscript/RenderScriptGL.java1
-rw-r--r--rs/java/android/renderscript/Sampler.java5
-rw-r--r--rs/java/android/renderscript/Script.java5
-rw-r--r--rs/java/android/renderscript/ScriptC.java5
-rw-r--r--rs/java/android/renderscript/ScriptGroup.java5
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsic.java5
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsic3DLUT.java4
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicBLAS.java4
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicBlend.java5
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicBlur.java5
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java5
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java4
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java4
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicHistogram.java5
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicLUT.java5
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicResize.java5
-rw-r--r--rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java5
-rw-r--r--rs/java/android/renderscript/Short2.java5
-rw-r--r--rs/java/android/renderscript/Short3.java5
-rw-r--r--rs/java/android/renderscript/Short4.java5
-rw-r--r--rs/java/android/renderscript/Type.java5
-rw-r--r--rs/jni/Android.mk2
-rw-r--r--services/api/Android.bp29
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java16
-rw-r--r--services/core/java/com/android/server/BootReceiver.java8
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java161
-rw-r--r--services/core/java/com/android/server/ConnectivityServiceInitializer.java5
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java7
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java43
-rw-r--r--services/core/java/com/android/server/TestNetworkService.java4
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java15
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java18
-rw-r--r--services/core/java/com/android/server/am/UserController.java54
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java34
-rw-r--r--services/core/java/com/android/server/appop/DiscreteRegistry.java97
-rw-r--r--services/core/java/com/android/server/appop/HistoricalRegistry.java9
-rw-r--r--services/core/java/com/android/server/biometrics/AuthService.java31
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java4
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java4
-rw-r--r--services/core/java/com/android/server/clipboard/ClipboardService.java16
-rw-r--r--services/core/java/com/android/server/connectivity/Nat464Xlat.java21
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java4
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplayMapper.java2
-rw-r--r--services/core/java/com/android/server/display/WifiDisplayAdapter.java7
-rw-r--r--services/core/java/com/android/server/graphics/fonts/FontManagerService.java2
-rw-r--r--services/core/java/com/android/server/hdmi/OneTouchPlayAction.java35
-rw-r--r--services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java17
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java11
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java8
-rw-r--r--services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java2
-rw-r--r--services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java6
-rw-r--r--services/core/java/com/android/server/locksettings/RebootEscrowManager.java57
-rw-r--r--services/core/java/com/android/server/locksettings/TEST_MAPPING11
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java8
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java8
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java5
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java12
-rw-r--r--services/core/java/com/android/server/pm/ApkChecksums.java2
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java26
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java84
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java434
-rw-r--r--services/core/java/com/android/server/power/FaceDownDetector.java77
-rw-r--r--services/core/java/com/android/server/power/Notifier.java7
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java7
-rw-r--r--services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java33
-rw-r--r--services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java11
-rw-r--r--services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java6
-rw-r--r--services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java7
-rw-r--r--services/core/java/com/android/server/security/FileIntegrityService.java1
-rw-r--r--services/core/java/com/android/server/security/OWNERS1
-rw-r--r--services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java31
-rw-r--r--services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java16
-rw-r--r--services/core/java/com/android/server/stats/OWNERS3
-rw-r--r--services/core/java/com/android/server/stats/pull/StatsPullAtomService.java21
-rw-r--r--services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java37
-rw-r--r--services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java4
-rw-r--r--services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java9
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java2
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java27
-rw-r--r--services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java4
-rw-r--r--services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java6
-rw-r--r--services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java52
-rw-r--r--services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java30
-rw-r--r--services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java53
-rw-r--r--services/core/java/com/android/server/vcn/Vcn.java4
-rw-r--r--services/core/java/com/android/server/vcn/VcnGatewayConnection.java29
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java45
-rw-r--r--services/core/java/com/android/server/wm/ConfigurationContainer.java3
-rw-r--r--services/core/java/com/android/server/wm/RemoteAnimationController.java11
-rw-r--r--services/core/java/com/android/server/wm/Task.java33
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java9
-rw-r--r--services/core/java/com/android/server/wm/WindowTracing.java57
-rw-r--r--services/core/jni/Android.bp1
-rw-r--r--services/core/jni/onload.cpp2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java13
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java21
-rw-r--r--services/incremental/Android.bp2
-rw-r--r--services/incremental/BinderIncrementalService.cpp6
-rw-r--r--services/incremental/BinderIncrementalService.h3
-rw-r--r--services/incremental/IncrementalService.cpp57
-rw-r--r--services/incremental/IncrementalService.h8
-rw-r--r--services/incremental/test/IncrementalServiceTest.cpp69
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java33
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java (renamed from services/tests/servicestests/src/com/android/server/power/FaceDownDetectorTest.java)148
-rw-r--r--services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java30
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java130
-rw-r--r--services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java25
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java420
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java343
-rw-r--r--services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java102
-rw-r--r--services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java43
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/rotationresolver/RotationResolverManagerPerUserServiceTest.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java31
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java24
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java72
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/location/TestSupport.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidatorTest.java54
-rw-r--r--services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS1
-rw-r--r--services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java17
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java310
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskTests.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java12
-rwxr-xr-xtelecomm/java/android/telecom/ConnectionService.java9
-rw-r--r--telephony/java/android/telephony/CarrierBandwidth.java8
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java46
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java3
-rw-r--r--telephony/java/android/telephony/data/DataServiceCallback.java8
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt74
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt91
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt59
-rw-r--r--tests/net/Android.bp2
-rw-r--r--tests/net/TEST_MAPPING17
-rw-r--r--tests/net/common/java/android/net/NetworkCapabilitiesTest.java7
-rw-r--r--tests/net/common/java/android/net/NetworkProviderTest.kt7
-rw-r--r--tests/net/integration/util/com/android/server/NetworkAgentWrapper.java29
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java158
-rw-r--r--tests/net/java/com/android/server/connectivity/LingerMonitorTest.java2
-rw-r--r--tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java4
-rw-r--r--tests/net/java/com/android/server/connectivity/Nat464XlatTest.java79
-rw-r--r--tests/vcn/assets/client-end-cert.pem21
-rw-r--r--tests/vcn/assets/client-private-key.key28
-rw-r--r--tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java7
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java189
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java30
-rw-r--r--tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java26
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java9
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java10
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java3
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java2
669 files changed, 14919 insertions, 6909 deletions
diff --git a/.prebuilt_info/OWNERS b/.prebuilt_info/OWNERS
new file mode 100644
index 000000000000..eb8b89b10e83
--- /dev/null
+++ b/.prebuilt_info/OWNERS
@@ -0,0 +1 @@
+per-file prebuilt_info_packages_CtsShim_*.asciipb = file:/packages/CtsShim/OWNERS
diff --git a/Android.bp b/Android.bp
index 3907734a171d..622b2c6120bd 100644
--- a/Android.bp
+++ b/Android.bp
@@ -584,7 +584,7 @@ java_library {
"android.hardware.vibrator-V2-java",
"android.security.apc-java",
"android.security.authorization-java",
- "android.security.usermanager-java",
+ "android.security.maintenance-java",
"android.security.vpnprofilestore-java",
"android.system.keystore2-V1-java",
"android.system.suspend.control.internal-java",
@@ -932,18 +932,21 @@ filegroup {
],
}
-// keep these files in sync with the package/Tethering/jarjar-rules.txt for the tethering module.
+// keep these files in sync with the package/Tethering/jarjar-rules.txt and
+// package/Connectivity/jarjar-rules.txt for the tethering module and connectivity module.
filegroup {
- name: "framework-tethering-shared-srcs",
+ name: "framework-connectivity-shared-srcs",
srcs: [
"core/java/android/util/IndentingPrintWriter.java",
"core/java/android/util/LocalLog.java",
+ // This should be android.util.IndentingPrintWriter, but it's not available in all branches.
"core/java/com/android/internal/util/IndentingPrintWriter.java",
"core/java/com/android/internal/util/IState.java",
"core/java/com/android/internal/util/MessageUtils.java",
"core/java/com/android/internal/util/State.java",
"core/java/com/android/internal/util/StateMachine.java",
"core/java/com/android/internal/util/TrafficStatsConstants.java",
+ "core/java/com/android/internal/util/WakeupMessage.java",
],
}
diff --git a/TEST_MAPPING b/TEST_MAPPING
index d08c52782fb3..9ceef6bbe8a3 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -82,5 +82,65 @@
{
"name": "ManagedProfileLifecycleStressTest"
}
- ]
+ ],
+ "auto-postsubmit": [
+ // Test tag for automotive targets. These are only running in postsubmit so as to harden the
+ // automotive targets to avoid introducing additional test flake and build time. The plan for
+ // presubmit testing for auto is to augment the existing tests to cover auto use cases as well.
+ // Additionally, this tag is used in targeted test suites to limit resource usage on the test
+ // infra during the hardening phase.
+ // TODO: this tag to be removed once the above is no longer an issue.
+ {
+ "name": "FrameworksUiServicesTests",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "ExtServicesUnitTests",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "TestablesTests",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "FrameworksCoreTests",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ }
+ ]
+ },
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ }
+ ]
+ }
+ ]
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java
index 4b0f719b13be..999860fdf4da 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreIdleJobService.java
@@ -42,7 +42,7 @@ public class BlobStoreIdleJobService extends JobService {
blobStoreManagerInternal.onIdleMaintenance();
jobFinished(params, false);
});
- return false;
+ return true;
}
@Override
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index b7a3f1083176..6967d819a448 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -59,6 +59,9 @@ import java.util.Objects;
* constraint on the JobInfo object that you are creating. Otherwise, the builder would throw an
* exception when building. From Android version {@link Build.VERSION_CODES#Q} and onwards, it is
* valid to schedule jobs with no constraints.
+ * <p> Prior to Android version {@link Build.VERSION_CODES#S}, jobs could only have a maximum of 100
+ * jobs scheduled at a time. Starting with Android version {@link Build.VERSION_CODES#S}, that limit
+ * has been increased to 150. Expedited jobs also count towards the limit.
* <p> In Android version {@link Build.VERSION_CODES#LOLLIPOP}, jobs had a maximum execution time
* of one minute. Starting with Android version {@link Build.VERSION_CODES#M} and ending with
* Android version {@link Build.VERSION_CODES#R}, jobs had a maximum execution time of 10 minutes.
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
index 0c4fcb4ec1b0..6e4a5a0c5784 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
@@ -22,6 +22,7 @@ import android.app.SystemServiceRegistry;
import android.content.Context;
import android.os.DeviceIdleManager;
import android.os.IDeviceIdleController;
+import android.os.PowerExemptionManager;
import android.os.PowerWhitelistManager;
/**
@@ -52,5 +53,8 @@ public class JobSchedulerFrameworkInitializer {
SystemServiceRegistry.registerContextAwareService(
Context.POWER_WHITELIST_MANAGER, PowerWhitelistManager.class,
PowerWhitelistManager::new);
+ SystemServiceRegistry.registerContextAwareService(
+ Context.POWER_EXEMPTION_SERVICE, PowerExemptionManager.class,
+ PowerExemptionManager::new);
}
}
diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
new file mode 100644
index 000000000000..8445335b568e
--- /dev/null
+++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
@@ -0,0 +1,626 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
+import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT;
+import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
+import static android.app.ActivityManager.PROCESS_STATE_TOP;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.content.Context;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Interface to access and modify the permanent and temporary power save allow list. The two lists
+ * are kept separately. Apps placed on the permanent allow list are only removed via an explicit
+ * {@link #removeFromAllowList(String)} call. Apps allow-listed by default by the system cannot be
+ * removed. Apps placed on the temporary allow list are removed from that allow list after a
+ * predetermined amount of time.
+ *
+ * @hide
+ */
+@SystemApi
+@SystemService(Context.POWER_EXEMPTION_SERVICE)
+public class PowerExemptionManager {
+ private final Context mContext;
+ // Proxy to DeviceIdleController for now
+ // TODO: migrate to PowerExemptionController
+ private final IDeviceIdleController mService;
+
+ /**
+ * Indicates that an unforeseen event has occurred and the app should be allow-listed to handle
+ * it.
+ */
+ public static final int EVENT_UNSPECIFIED = 0;
+
+ /**
+ * Indicates that an SMS event has occurred and the app should be allow-listed to handle it.
+ */
+ public static final int EVENT_SMS = 1;
+
+ /**
+ * Indicates that an MMS event has occurred and the app should be allow-listed to handle it.
+ */
+ public static final int EVENT_MMS = 2;
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"EVENT_"}, value = {
+ EVENT_UNSPECIFIED,
+ EVENT_SMS,
+ EVENT_MMS,
+ })
+ public @interface AllowListEvent {
+ }
+
+ /**
+ * Allow the temp allow list behavior, plus allow foreground service start from background.
+ */
+ public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED = 0;
+ /**
+ * Only allow the temp allow list behavior, not allow foreground service start from background.
+ */
+ public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1;
+
+ /**
+ * The list of temp allow list types.
+ * @hide
+ */
+ @IntDef(flag = true, prefix = { "TEMPORARY_ALLOW_LIST_TYPE_" }, value = {
+ TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+ TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TempAllowListType {}
+
+ /* Reason codes for BG-FGS-launch. */
+ /**
+ * BG-FGS-launch is denied.
+ * @hide
+ */
+ public static final int REASON_DENIED = -1;
+
+ /* Reason code range 0-9 are reserved for default reasons */
+ /**
+ * The default reason code if reason is unknown.
+ */
+ public static final int REASON_UNKNOWN = 0;
+ /**
+ * Use REASON_OTHER if there is no better choice.
+ */
+ public static final int REASON_OTHER = 1;
+
+ /* Reason code range 10-49 are reserved for BG-FGS-launch allowed proc states */
+ /** @hide */
+ public static final int REASON_PROC_STATE_PERSISTENT = 10;
+ /** @hide */
+ public static final int REASON_PROC_STATE_PERSISTENT_UI = 11;
+ /** @hide */
+ public static final int REASON_PROC_STATE_TOP = 12;
+ /** @hide */
+ public static final int REASON_PROC_STATE_BTOP = 13;
+ /** @hide */
+ public static final int REASON_PROC_STATE_FGS = 14;
+ /** @hide */
+ public static final int REASON_PROC_STATE_BFGS = 15;
+
+ /* Reason code range 50-99 are reserved for BG-FGS-launch allowed reasons */
+ /** @hide */
+ public static final int REASON_UID_VISIBLE = 50;
+ /** @hide */
+ public static final int REASON_SYSTEM_UID = 51;
+ /** @hide */
+ public static final int REASON_ACTIVITY_STARTER = 52;
+ /** @hide */
+ public static final int REASON_START_ACTIVITY_FLAG = 53;
+ /** @hide */
+ public static final int REASON_FGS_BINDING = 54;
+ /** @hide */
+ public static final int REASON_DEVICE_OWNER = 55;
+ /** @hide */
+ public static final int REASON_PROFILE_OWNER = 56;
+ /** @hide */
+ public static final int REASON_COMPANION_DEVICE_MANAGER = 57;
+ /**
+ * START_ACTIVITIES_FROM_BACKGROUND permission.
+ * @hide
+ */
+ public static final int REASON_BACKGROUND_ACTIVITY_PERMISSION = 58;
+ /**
+ * START_FOREGROUND_SERVICES_FROM_BACKGROUND permission.
+ * @hide
+ */
+ public static final int REASON_BACKGROUND_FGS_PERMISSION = 59;
+ /** @hide */
+ public static final int REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION = 60;
+ /** @hide */
+ public static final int REASON_INSTR_BACKGROUND_FGS_PERMISSION = 61;
+ /** @hide */
+ public static final int REASON_SYSTEM_ALERT_WINDOW_PERMISSION = 62;
+ /** @hide */
+ public static final int REASON_DEVICE_DEMO_MODE = 63;
+ /** @hide */
+ public static final int REASON_EXEMPTED_PACKAGE = 64;
+ /** @hide */
+ public static final int REASON_ALLOWLISTED_PACKAGE = 65;
+ /** @hide */
+ public static final int REASON_APPOP = 66;
+
+ /* BG-FGS-launch is allowed by temp-allow-list or system-allow-list.
+ Reason code for temp and system allow list starts here.
+ Reason code range 100-199 are reserved for public reasons. */
+ /**
+ * Set temp-allow-list for location geofence purpose.
+ */
+ public static final int REASON_GEOFENCING = 100;
+ /**
+ * Set temp-allow-list for server push messaging.
+ */
+ public static final int REASON_PUSH_MESSAGING = 101;
+ /**
+ * Set temp-allow-list for server push messaging over the quota.
+ */
+ public static final int REASON_PUSH_MESSAGING_OVER_QUOTA = 102;
+ /**
+ * Set temp-allow-list for activity recognition.
+ */
+ public static final int REASON_ACTIVITY_RECOGNITION = 103;
+
+ /* Reason code range 200-299 are reserved for broadcast actions */
+ /**
+ * Broadcast ACTION_BOOT_COMPLETED.
+ * @hide
+ */
+ public static final int REASON_BOOT_COMPLETED = 200;
+ /**
+ * Broadcast ACTION_PRE_BOOT_COMPLETED.
+ * @hide
+ */
+ public static final int REASON_PRE_BOOT_COMPLETED = 201;
+ /**
+ * Broadcast ACTION_LOCKED_BOOT_COMPLETED.
+ * @hide
+ */
+ public static final int REASON_LOCKED_BOOT_COMPLETED = 202;
+
+ /* Reason code range 300-399 are reserved for other internal reasons */
+ /**
+ * Device idle system allow list, including EXCEPT-IDLE
+ * @hide
+ */
+ public static final int REASON_SYSTEM_ALLOW_LISTED = 300;
+ /** @hide */
+ public static final int REASON_ALARM_MANAGER_ALARM_CLOCK = 301;
+ /**
+ * AlarmManagerService.
+ * @hide
+ */
+ public static final int REASON_ALARM_MANAGER_WHILE_IDLE = 302;
+ /**
+ * ActiveServices.
+ * @hide
+ */
+ public static final int REASON_SERVICE_LAUNCH = 303;
+ /**
+ * KeyChainSystemService.
+ * @hide
+ */
+ public static final int REASON_KEY_CHAIN = 304;
+ /**
+ * PackageManagerService.
+ * @hide
+ */
+ public static final int REASON_PACKAGE_VERIFIER = 305;
+ /**
+ * SyncManager.
+ * @hide
+ */
+ public static final int REASON_SYNC_MANAGER = 306;
+ /**
+ * DomainVerificationProxyV1.
+ * @hide
+ */
+ public static final int REASON_DOMAIN_VERIFICATION_V1 = 307;
+ /**
+ * DomainVerificationProxyV2.
+ * @hide
+ */
+ public static final int REASON_DOMAIN_VERIFICATION_V2 = 308;
+ /** @hide */
+ public static final int REASON_VPN = 309;
+ /**
+ * NotificationManagerService.
+ * @hide
+ */
+ public static final int REASON_NOTIFICATION_SERVICE = 310;
+ /**
+ * Broadcast ACTION_MY_PACKAGE_REPLACED.
+ * @hide
+ */
+ public static final int REASON_PACKAGE_REPLACED = 311;
+ /**
+ * LocationProviderManager.
+ * @hide
+ */
+ public static final int REASON_LOCATION_PROVIDER = 312;
+ /**
+ * MediaButtonReceiver.
+ * @hide
+ */
+ public static final int REASON_MEDIA_BUTTON = 313;
+ /**
+ * InboundSmsHandler.
+ * @hide
+ */
+ public static final int REASON_EVENT_SMS = 314;
+ /**
+ * InboundSmsHandler.
+ * @hide
+ */
+ public static final int REASON_EVENT_MMS = 315;
+ /**
+ * Shell app.
+ * @hide
+ */
+ public static final int REASON_SHELL = 316;
+
+ /**
+ * The list of BG-FGS-Launch and temp-allow-list reason code.
+ * @hide
+ */
+ @IntDef(flag = true, prefix = { "REASON_" }, value = {
+ // BG-FGS-Launch reasons.
+ REASON_DENIED,
+ REASON_UNKNOWN,
+ REASON_OTHER,
+ REASON_PROC_STATE_PERSISTENT,
+ REASON_PROC_STATE_PERSISTENT_UI,
+ REASON_PROC_STATE_TOP,
+ REASON_PROC_STATE_BTOP,
+ REASON_PROC_STATE_FGS,
+ REASON_PROC_STATE_BFGS,
+ REASON_UID_VISIBLE,
+ REASON_SYSTEM_UID,
+ REASON_ACTIVITY_STARTER,
+ REASON_START_ACTIVITY_FLAG,
+ REASON_FGS_BINDING,
+ REASON_DEVICE_OWNER,
+ REASON_PROFILE_OWNER,
+ REASON_COMPANION_DEVICE_MANAGER,
+ REASON_BACKGROUND_ACTIVITY_PERMISSION,
+ REASON_BACKGROUND_FGS_PERMISSION,
+ REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION,
+ REASON_INSTR_BACKGROUND_FGS_PERMISSION,
+ REASON_SYSTEM_ALERT_WINDOW_PERMISSION,
+ REASON_DEVICE_DEMO_MODE,
+ REASON_EXEMPTED_PACKAGE,
+ REASON_ALLOWLISTED_PACKAGE,
+ REASON_APPOP,
+ // temp and system allow list reasons.
+ REASON_GEOFENCING,
+ REASON_PUSH_MESSAGING,
+ REASON_PUSH_MESSAGING_OVER_QUOTA,
+ REASON_ACTIVITY_RECOGNITION,
+ REASON_BOOT_COMPLETED,
+ REASON_PRE_BOOT_COMPLETED,
+ REASON_LOCKED_BOOT_COMPLETED,
+ REASON_SYSTEM_ALLOW_LISTED,
+ REASON_ALARM_MANAGER_ALARM_CLOCK,
+ REASON_ALARM_MANAGER_WHILE_IDLE,
+ REASON_SERVICE_LAUNCH,
+ REASON_KEY_CHAIN,
+ REASON_PACKAGE_VERIFIER,
+ REASON_SYNC_MANAGER,
+ REASON_DOMAIN_VERIFICATION_V1,
+ REASON_DOMAIN_VERIFICATION_V2,
+ REASON_VPN,
+ REASON_NOTIFICATION_SERVICE,
+ REASON_PACKAGE_REPLACED,
+ REASON_LOCATION_PROVIDER,
+ REASON_MEDIA_BUTTON,
+ REASON_EVENT_SMS,
+ REASON_EVENT_MMS,
+ REASON_SHELL,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ReasonCode {}
+
+ /**
+ * @hide
+ */
+ public PowerExemptionManager(@NonNull Context context) {
+ mContext = context;
+ mService = context.getSystemService(DeviceIdleManager.class).getService();
+ }
+
+ /**
+ * Add the specified package to the permanent power save allow list.
+ */
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public void addToPermanentAllowList(@NonNull String packageName) {
+ addToPermanentAllowList(Collections.singletonList(packageName));
+ }
+
+ /**
+ * Add the specified packages to the permanent power save allow list.
+ */
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public void addToPermanentAllowList(@NonNull List<String> packageNames) {
+ try {
+ mService.addPowerSaveWhitelistApps(packageNames);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Get a list of app IDs of app that are allow-listed. This does not include temporarily
+ * allow-listed apps.
+ *
+ * @param includingIdle Set to true if the app should be allow-listed from device idle as well
+ * as other power save restrictions
+ * @hide
+ */
+ @NonNull
+ public int[] getAllowListedAppIds(boolean includingIdle) {
+ try {
+ if (includingIdle) {
+ return mService.getAppIdWhitelist();
+ } else {
+ return mService.getAppIdWhitelistExceptIdle();
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns true if the app is allow-listed from power save restrictions. This does not include
+ * temporarily allow-listed apps.
+ *
+ * @param includingIdle Set to true if the app should be allow-listed from device
+ * idle as well as other power save restrictions
+ * @hide
+ */
+ public boolean isAllowListed(@NonNull String packageName, boolean includingIdle) {
+ try {
+ if (includingIdle) {
+ return mService.isPowerSaveWhitelistApp(packageName);
+ } else {
+ return mService.isPowerSaveWhitelistExceptIdleApp(packageName);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Remove an app from the permanent power save allow list. Only apps that were added via
+ * {@link #addToPermanentAllowList(String)} or {@link #addToPermanentAllowList(List)} will be
+ * removed. Apps allow-listed by default by the system cannot be removed.
+ *
+ * @param packageName The app to remove from the allow list
+ */
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public void removeFromAllowList(@NonNull String packageName) {
+ try {
+ mService.removePowerSaveWhitelistApp(packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Add an app to the temporary allow list for a short amount of time.
+ *
+ * @param packageName The package to add to the temp allow list
+ * @param durationMs How long to keep the app on the temp allow list for (in milliseconds)
+ * @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure.
+ * @param reason a optional human readable reason string, could be null or empty string.
+ */
+ @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
+ public void addToTemporaryAllowList(@NonNull String packageName, long durationMs,
+ @ReasonCode int reasonCode, @Nullable String reason) {
+ try {
+ mService.addPowerSaveTempWhitelistApp(packageName, durationMs, mContext.getUserId(),
+ reasonCode, reason);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Add an app to the temporary allow list for a short amount of time for a specific reason.
+ * The temporary allow list is kept separately from the permanent allow list and apps are
+ * automatically removed from the temporary allow list after a predetermined amount of time.
+ *
+ * @param packageName The package to add to the temp allow list
+ * @param event The reason to add the app to the temp allow list
+ * @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure.
+ * @param reason A human-readable reason explaining why the app is temp allow-listed. Only
+ * used for logging purposes. Could be null or empty string.
+ * @return The duration (in milliseconds) that the app is allow-listed for
+ */
+ @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
+ public long addToTemporaryAllowListForEvent(@NonNull String packageName,
+ @AllowListEvent int event, @ReasonCode int reasonCode, @Nullable String reason) {
+ try {
+ switch (event) {
+ case EVENT_MMS:
+ return mService.addPowerSaveTempWhitelistAppForMms(
+ packageName, mContext.getUserId(), reasonCode, reason);
+ case EVENT_SMS:
+ return mService.addPowerSaveTempWhitelistAppForSms(
+ packageName, mContext.getUserId(), reasonCode, reason);
+ case EVENT_UNSPECIFIED:
+ default:
+ return mService.whitelistAppTemporarily(
+ packageName, mContext.getUserId(), reasonCode, reason);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static @ReasonCode int getReasonCodeFromProcState(int procState) {
+ if (procState <= PROCESS_STATE_PERSISTENT) {
+ return REASON_PROC_STATE_PERSISTENT;
+ } else if (procState <= PROCESS_STATE_PERSISTENT_UI) {
+ return REASON_PROC_STATE_PERSISTENT_UI;
+ } else if (procState <= PROCESS_STATE_TOP) {
+ return REASON_PROC_STATE_TOP;
+ } else if (procState <= PROCESS_STATE_BOUND_TOP) {
+ return REASON_PROC_STATE_BTOP;
+ } else if (procState <= PROCESS_STATE_FOREGROUND_SERVICE) {
+ return REASON_PROC_STATE_FGS;
+ } else if (procState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+ return REASON_PROC_STATE_BFGS;
+ } else {
+ return REASON_DENIED;
+ }
+ }
+
+ /**
+ * Return string name of the integer reason code.
+ * @hide
+ * @param reasonCode
+ * @return string name of the reason code.
+ */
+ public static String reasonCodeToString(@ReasonCode int reasonCode) {
+ switch (reasonCode) {
+ case REASON_DENIED:
+ return "DENIED";
+ case REASON_UNKNOWN:
+ return "UNKNOWN";
+ case REASON_OTHER:
+ return "OTHER";
+ case REASON_PROC_STATE_PERSISTENT:
+ return "PROC_STATE_PERSISTENT";
+ case REASON_PROC_STATE_PERSISTENT_UI:
+ return "PROC_STATE_PERSISTENT_UI";
+ case REASON_PROC_STATE_TOP:
+ return "PROC_STATE_TOP";
+ case REASON_PROC_STATE_BTOP:
+ return "PROC_STATE_BTOP";
+ case REASON_PROC_STATE_FGS:
+ return "PROC_STATE_FGS";
+ case REASON_PROC_STATE_BFGS:
+ return "PROC_STATE_BFGS";
+ case REASON_UID_VISIBLE:
+ return "UID_VISIBLE";
+ case REASON_SYSTEM_UID:
+ return "SYSTEM_UID";
+ case REASON_ACTIVITY_STARTER:
+ return "ACTIVITY_STARTER";
+ case REASON_START_ACTIVITY_FLAG:
+ return "START_ACTIVITY_FLAG";
+ case REASON_FGS_BINDING:
+ return "FGS_BINDING";
+ case REASON_DEVICE_OWNER:
+ return "DEVICE_OWNER";
+ case REASON_PROFILE_OWNER:
+ return "PROFILE_OWNER";
+ case REASON_COMPANION_DEVICE_MANAGER:
+ return "COMPANION_DEVICE_MANAGER";
+ case REASON_BACKGROUND_ACTIVITY_PERMISSION:
+ return "BACKGROUND_ACTIVITY_PERMISSION";
+ case REASON_BACKGROUND_FGS_PERMISSION:
+ return "BACKGROUND_FGS_PERMISSION";
+ case REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION:
+ return "INSTR_BACKGROUND_ACTIVITY_PERMISSION";
+ case REASON_INSTR_BACKGROUND_FGS_PERMISSION:
+ return "INSTR_BACKGROUND_FGS_PERMISSION";
+ case REASON_SYSTEM_ALERT_WINDOW_PERMISSION:
+ return "SYSTEM_ALERT_WINDOW_PERMISSION";
+ case REASON_DEVICE_DEMO_MODE:
+ return "DEVICE_DEMO_MODE";
+ case REASON_EXEMPTED_PACKAGE:
+ return "EXEMPTED_PACKAGE";
+ case REASON_ALLOWLISTED_PACKAGE:
+ return "ALLOWLISTED_PACKAGE";
+ case REASON_APPOP:
+ return "APPOP";
+ case REASON_GEOFENCING:
+ return "GEOFENCING";
+ case REASON_PUSH_MESSAGING:
+ return "PUSH_MESSAGING";
+ case REASON_PUSH_MESSAGING_OVER_QUOTA:
+ return "PUSH_MESSAGING_OVER_QUOTA";
+ case REASON_ACTIVITY_RECOGNITION:
+ return "ACTIVITY_RECOGNITION";
+ case REASON_BOOT_COMPLETED:
+ return "BOOT_COMPLETED";
+ case REASON_PRE_BOOT_COMPLETED:
+ return "PRE_BOOT_COMPLETED";
+ case REASON_LOCKED_BOOT_COMPLETED:
+ return "LOCKED_BOOT_COMPLETED";
+ case REASON_SYSTEM_ALLOW_LISTED:
+ return "SYSTEM_ALLOW_LISTED";
+ case REASON_ALARM_MANAGER_ALARM_CLOCK:
+ return "ALARM_MANAGER_ALARM_CLOCK";
+ case REASON_ALARM_MANAGER_WHILE_IDLE:
+ return "ALARM_MANAGER_WHILE_IDLE";
+ case REASON_SERVICE_LAUNCH:
+ return "SERVICE_LAUNCH";
+ case REASON_KEY_CHAIN:
+ return "KEY_CHAIN";
+ case REASON_PACKAGE_VERIFIER:
+ return "PACKAGE_VERIFIER";
+ case REASON_SYNC_MANAGER:
+ return "SYNC_MANAGER";
+ case REASON_DOMAIN_VERIFICATION_V1:
+ return "DOMAIN_VERIFICATION_V1";
+ case REASON_DOMAIN_VERIFICATION_V2:
+ return "DOMAIN_VERIFICATION_V2";
+ case REASON_VPN:
+ return "VPN";
+ case REASON_NOTIFICATION_SERVICE:
+ return "NOTIFICATION_SERVICE";
+ case REASON_PACKAGE_REPLACED:
+ return "PACKAGE_REPLACED";
+ case REASON_LOCATION_PROVIDER:
+ return "LOCATION_PROVIDER";
+ case REASON_MEDIA_BUTTON:
+ return "MEDIA_BUTTON";
+ case REASON_EVENT_SMS:
+ return "EVENT_SMS";
+ case REASON_EVENT_MMS:
+ return "EVENT_MMS";
+ case REASON_SHELL:
+ return "SHELL";
+ default:
+ return "(unknown:" + reasonCode + ")";
+ }
+ }
+}
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 2b2918c0a6f0..33f6e0651abc 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -24,6 +24,7 @@ import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT;
import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
import static android.app.AlarmManager.FLAG_IDLE_UNTIL;
import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE;
+import static android.app.AlarmManager.INTERVAL_DAY;
import static android.app.AlarmManager.INTERVAL_HOUR;
import static android.app.AlarmManager.RTC;
import static android.app.AlarmManager.RTC_WAKEUP;
@@ -88,7 +89,6 @@ import android.provider.Settings;
import android.system.Os;
import android.text.TextUtils;
import android.text.format.DateFormat;
-import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
@@ -168,8 +168,7 @@ public class AlarmManagerService extends SystemService {
static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
static final int TICK_HISTORY_DEPTH = 10;
- static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
- static final long INDEFINITE_DELAY = 365 * MILLIS_IN_DAY;
+ static final long INDEFINITE_DELAY = 365 * INTERVAL_DAY;
// Indices into the KEYS_APP_STANDBY_QUOTAS array.
static final int ACTIVE_INDEX = 0;
@@ -423,13 +422,17 @@ public class AlarmManagerService extends SystemService {
@VisibleForTesting
static final String KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA = "allow_while_idle_compat_quota";
- private static final String KEY_ALLOW_WHILE_IDLE_WINDOW = "allow_while_idle_window";
+
+ @VisibleForTesting
+ static final String KEY_ALLOW_WHILE_IDLE_WINDOW = "allow_while_idle_window";
+ @VisibleForTesting
+ static final String KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW = "allow_while_idle_compat_window";
private static final String KEY_CRASH_NON_CLOCK_APPS = "crash_non_clock_apps";
private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
- private static final long DEFAULT_MAX_INTERVAL = 365 * DateUtils.DAY_IN_MILLIS;
+ private static final long DEFAULT_MAX_INTERVAL = 365 * INTERVAL_DAY;
private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10 * 1000;
private static final long DEFAULT_LISTENER_TIMEOUT = 5 * 1000;
private static final int DEFAULT_MAX_ALARMS_PER_UID = 500;
@@ -445,19 +448,21 @@ public class AlarmManagerService extends SystemService {
0 // Never
};
private static final int DEFAULT_APP_STANDBY_RESTRICTED_QUOTA = 1;
- private static final long DEFAULT_APP_STANDBY_RESTRICTED_WINDOW = MILLIS_IN_DAY;
+ private static final long DEFAULT_APP_STANDBY_RESTRICTED_WINDOW = INTERVAL_DAY;
private static final boolean DEFAULT_LAZY_BATCHING = true;
private static final boolean DEFAULT_TIME_TICK_ALLOWED_WHILE_IDLE = true;
/**
- * Default quota for pre-S apps. Enough to accommodate the existing policy of an alarm
+ * Default quota for pre-S apps. The same as allowing an alarm slot once
* every ALLOW_WHILE_IDLE_LONG_DELAY, which was 9 minutes.
*/
- private static final int DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA = 7;
+ private static final int DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA = 1;
private static final int DEFAULT_ALLOW_WHILE_IDLE_QUOTA = 72;
private static final long DEFAULT_ALLOW_WHILE_IDLE_WINDOW = 60 * 60 * 1000; // 1 hour.
+ private static final long DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW = 9 * 60 * 1000; // 9 mins.
+
// TODO (b/171306433): Change to true by default.
private static final boolean DEFAULT_CRASH_NON_CLOCK_APPS = false;
@@ -495,9 +500,14 @@ public class AlarmManagerService extends SystemService {
public int ALLOW_WHILE_IDLE_COMPAT_QUOTA = DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA;
/**
- * The window used for enforcing {@link #ALLOW_WHILE_IDLE_QUOTA} and
- * {@link #ALLOW_WHILE_IDLE_COMPAT_QUOTA}. Can be configured, but only recommended for
- * testing.
+ * The window used for enforcing {@link #ALLOW_WHILE_IDLE_COMPAT_QUOTA}.
+ * Can be configured, but only recommended for testing.
+ */
+ public long ALLOW_WHILE_IDLE_COMPAT_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW;
+
+ /**
+ * The window used for enforcing {@link #ALLOW_WHILE_IDLE_COMPAT_QUOTA}.
+ * Can be configured, but only recommended for testing.
*/
public long ALLOW_WHILE_IDLE_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_WINDOW;
@@ -561,7 +571,7 @@ public class AlarmManagerService extends SystemService {
ALLOW_WHILE_IDLE_QUOTA = properties.getInt(KEY_ALLOW_WHILE_IDLE_QUOTA,
DEFAULT_ALLOW_WHILE_IDLE_QUOTA);
if (ALLOW_WHILE_IDLE_QUOTA <= 0) {
- Slog.w(TAG, "Cannot have allow-while-idle quota lower than 1.");
+ Slog.w(TAG, "Must have positive allow_while_idle quota");
ALLOW_WHILE_IDLE_QUOTA = 1;
}
break;
@@ -570,22 +580,38 @@ public class AlarmManagerService extends SystemService {
KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA,
DEFAULT_ALLOW_WHILE_IDLE_COMPAT_QUOTA);
if (ALLOW_WHILE_IDLE_COMPAT_QUOTA <= 0) {
- Slog.w(TAG, "Cannot have quota lower than 1.");
+ Slog.w(TAG, "Must have positive allow_while_idle_compat quota");
ALLOW_WHILE_IDLE_COMPAT_QUOTA = 1;
}
break;
case KEY_ALLOW_WHILE_IDLE_WINDOW:
ALLOW_WHILE_IDLE_WINDOW = properties.getLong(
KEY_ALLOW_WHILE_IDLE_WINDOW, DEFAULT_ALLOW_WHILE_IDLE_WINDOW);
- if (ALLOW_WHILE_IDLE_WINDOW > DEFAULT_ALLOW_WHILE_IDLE_WINDOW) {
+
+ if (ALLOW_WHILE_IDLE_WINDOW > INTERVAL_HOUR) {
Slog.w(TAG, "Cannot have allow_while_idle_window > "
- + DEFAULT_ALLOW_WHILE_IDLE_WINDOW);
- ALLOW_WHILE_IDLE_WINDOW = DEFAULT_ALLOW_WHILE_IDLE_WINDOW;
- } else if (ALLOW_WHILE_IDLE_WINDOW < DEFAULT_ALLOW_WHILE_IDLE_WINDOW) {
+ + INTERVAL_HOUR);
+ ALLOW_WHILE_IDLE_WINDOW = INTERVAL_HOUR;
+ } else if (ALLOW_WHILE_IDLE_WINDOW != DEFAULT_ALLOW_WHILE_IDLE_WINDOW) {
Slog.w(TAG, "Using a non-default allow_while_idle_window = "
+ ALLOW_WHILE_IDLE_WINDOW);
}
break;
+ case KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW:
+ ALLOW_WHILE_IDLE_COMPAT_WINDOW = properties.getLong(
+ KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW,
+ DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW);
+
+ if (ALLOW_WHILE_IDLE_COMPAT_WINDOW > INTERVAL_HOUR) {
+ Slog.w(TAG, "Cannot have allow_while_idle_compat_window > "
+ + INTERVAL_HOUR);
+ ALLOW_WHILE_IDLE_COMPAT_WINDOW = INTERVAL_HOUR;
+ } else if (ALLOW_WHILE_IDLE_COMPAT_WINDOW
+ != DEFAULT_ALLOW_WHILE_IDLE_COMPAT_WINDOW) {
+ Slog.w(TAG, "Using a non-default allow_while_idle_compat_window = "
+ + ALLOW_WHILE_IDLE_COMPAT_WINDOW);
+ }
+ break;
case KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION:
ALLOW_WHILE_IDLE_WHITELIST_DURATION = properties.getLong(
KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION,
@@ -717,6 +743,9 @@ public class AlarmManagerService extends SystemService {
TimeUtils.formatDuration(LISTENER_TIMEOUT, pw);
pw.println();
+ pw.print(KEY_ALLOW_WHILE_IDLE_QUOTA, ALLOW_WHILE_IDLE_QUOTA);
+ pw.println();
+
pw.print(KEY_ALLOW_WHILE_IDLE_WINDOW);
pw.print("=");
TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WINDOW, pw);
@@ -725,7 +754,9 @@ public class AlarmManagerService extends SystemService {
pw.print(KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, ALLOW_WHILE_IDLE_COMPAT_QUOTA);
pw.println();
- pw.print(KEY_ALLOW_WHILE_IDLE_QUOTA, ALLOW_WHILE_IDLE_QUOTA);
+ pw.print(KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW);
+ pw.print("=");
+ TimeUtils.formatDuration(ALLOW_WHILE_IDLE_COMPAT_WINDOW, pw);
pw.println();
pw.print(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION);
@@ -1330,8 +1361,7 @@ public class AlarmManagerService extends SystemService {
mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);
mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW);
- mAllowWhileIdleHistory = new AppWakeupHistory(
- Constants.DEFAULT_ALLOW_WHILE_IDLE_WINDOW);
+ mAllowWhileIdleHistory = new AppWakeupHistory(INTERVAL_HOUR);
mNextWakeup = mNextNonWakeup = 0;
@@ -1730,9 +1760,15 @@ public class AlarmManagerService extends SystemService {
} else if (isAllowedWhileIdleRestricted(alarm)) {
// Allowed but limited.
final int userId = UserHandle.getUserId(alarm.creatorUid);
- final int quota = ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0)
- ? mConstants.ALLOW_WHILE_IDLE_QUOTA
- : mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
+ final int quota;
+ final long window;
+ if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) {
+ quota = mConstants.ALLOW_WHILE_IDLE_QUOTA;
+ window = mConstants.ALLOW_WHILE_IDLE_WINDOW;
+ } else {
+ quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
+ window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW;
+ }
final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow(
alarm.sourcePackage, userId);
if (dispatchesInWindow < quota) {
@@ -1740,7 +1776,7 @@ public class AlarmManagerService extends SystemService {
batterySaverPolicyElapsed = nowElapsed;
} else {
batterySaverPolicyElapsed = mAllowWhileIdleHistory.getNthLastWakeupForPackage(
- alarm.sourcePackage, userId, quota) + mConstants.ALLOW_WHILE_IDLE_WINDOW;
+ alarm.sourcePackage, userId, quota) + window;
}
} else {
// Not allowed.
@@ -1778,9 +1814,15 @@ public class AlarmManagerService extends SystemService {
} else if (isAllowedWhileIdleRestricted(alarm)) {
// Allowed but limited.
final int userId = UserHandle.getUserId(alarm.creatorUid);
- final int quota = ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0)
- ? mConstants.ALLOW_WHILE_IDLE_QUOTA
- : mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
+ final int quota;
+ final long window;
+ if ((alarm.flags & FLAG_ALLOW_WHILE_IDLE) != 0) {
+ quota = mConstants.ALLOW_WHILE_IDLE_QUOTA;
+ window = mConstants.ALLOW_WHILE_IDLE_WINDOW;
+ } else {
+ quota = mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA;
+ window = mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW;
+ }
final int dispatchesInWindow = mAllowWhileIdleHistory.getTotalWakeupsInWindow(
alarm.sourcePackage, userId);
if (dispatchesInWindow < quota) {
@@ -1788,7 +1830,7 @@ public class AlarmManagerService extends SystemService {
deviceIdlePolicyTime = nowElapsed;
} else {
final long whenInQuota = mAllowWhileIdleHistory.getNthLastWakeupForPackage(
- alarm.sourcePackage, userId, quota) + mConstants.ALLOW_WHILE_IDLE_WINDOW;
+ alarm.sourcePackage, userId, quota) + window;
deviceIdlePolicyTime = Math.min(whenInQuota, mPendingIdleUntil.getWhenElapsed());
}
} else {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 515cb747a99e..82f2f69bbde5 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -147,10 +147,8 @@ public class JobSchedulerService extends com.android.server.SystemService
/** The maximum number of concurrent jobs we run at one time. */
static final int MAX_JOB_CONTEXTS_COUNT = 16;
- /** Enforce a per-app limit on scheduled jobs? */
- private static final boolean ENFORCE_MAX_JOBS = true;
- /** The maximum number of jobs that we allow an unprivileged app to schedule */
- private static final int MAX_JOBS_PER_APP = 100;
+ /** The maximum number of jobs that we allow an app to schedule */
+ private static final int MAX_JOBS_PER_APP = 150;
/** The number of the most recently completed jobs to keep track of for debugging purposes. */
private static final int NUM_COMPLETED_JOB_HISTORY = 20;
@@ -1011,7 +1009,7 @@ public class JobSchedulerService extends com.android.server.SystemService
if (DEBUG) Slog.d(TAG, "SCHEDULE: " + jobStatus.toShortString());
// Jobs on behalf of others don't apply to the per-app job cap
- if (ENFORCE_MAX_JOBS && packageName == null) {
+ if (packageName == null) {
if (mJobs.countJobsForUid(uId) > MAX_JOBS_PER_APP) {
Slog.w(TAG, "Too many jobs for uid " + uId);
throw new IllegalStateException("Apps may not schedule more than "
diff --git a/apex/media/framework/api/system-current.txt b/apex/media/framework/api/system-current.txt
index af2d2f75b823..6158e2ece55f 100644
--- a/apex/media/framework/api/system-current.txt
+++ b/apex/media/framework/api/system-current.txt
@@ -47,12 +47,16 @@ package android.media {
public static final class MediaTranscodeManager.TranscodingSession {
method public void cancel();
+ method public int getErrorCode();
method @IntRange(from=0, to=100) public int getProgress();
method public int getResult();
method public int getSessionId();
method public int getStatus();
method public void setOnProgressUpdateListener(@NonNull java.util.concurrent.Executor, @Nullable android.media.MediaTranscodeManager.TranscodingSession.OnProgressUpdateListener);
method public void setOnProgressUpdateListener(int, @NonNull java.util.concurrent.Executor, @Nullable android.media.MediaTranscodeManager.TranscodingSession.OnProgressUpdateListener);
+ field public static final int ERROR_DROPPED_BY_SERVICE = 1; // 0x1
+ field public static final int ERROR_NONE = 0; // 0x0
+ field public static final int ERROR_SERVICE_DIED = 2; // 0x2
field public static final int RESULT_CANCELED = 4; // 0x4
field public static final int RESULT_ERROR = 3; // 0x3
field public static final int RESULT_NONE = 1; // 0x1
diff --git a/apex/media/framework/java/android/media/MediaTranscodeManager.java b/apex/media/framework/java/android/media/MediaTranscodeManager.java
index b29bed978a21..30d1896a23ac 100644
--- a/apex/media/framework/java/android/media/MediaTranscodeManager.java
+++ b/apex/media/framework/java/android/media/MediaTranscodeManager.java
@@ -217,7 +217,8 @@ public final class MediaTranscodeManager {
// Updates the session status and result.
session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED,
- TranscodingSession.RESULT_SUCCESS);
+ TranscodingSession.RESULT_SUCCESS,
+ TranscodingSession.ERROR_NONE);
// Notifies client the session is done.
if (session.mListener != null && session.mListenerExecutor != null) {
@@ -241,7 +242,7 @@ public final class MediaTranscodeManager {
// Updates the session status and result.
session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED,
- TranscodingSession.RESULT_ERROR);
+ TranscodingSession.RESULT_ERROR, errorCode);
// Notifies client the session failed.
if (session.mListener != null && session.mListenerExecutor != null) {
@@ -330,7 +331,8 @@ public final class MediaTranscodeManager {
if (session.getStatus() == TranscodingSession.STATUS_RUNNING) {
session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED,
- TranscodingSession.RESULT_ERROR);
+ TranscodingSession.RESULT_ERROR,
+ TranscodingSession.ERROR_SERVICE_DIED);
// Remove the session from pending sessions.
mPendingTranscodingSessions.remove(entry.getKey());
@@ -1239,6 +1241,33 @@ public final class MediaTranscodeManager {
@Retention(RetentionPolicy.SOURCE)
public @interface Result {}
+
+ // The error code exposed here should be in sync with:
+ // frameworks/av/media/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl
+ /** @hide */
+ @IntDef(prefix = { "TRANSCODING_SESSION_ERROR_" }, value = {
+ ERROR_NONE,
+ ERROR_DROPPED_BY_SERVICE,
+ ERROR_SERVICE_DIED})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TranscodingSessionErrorCode{}
+ /**
+ * Constant indicating that no error occurred.
+ */
+ public static final int ERROR_NONE = 0;
+
+ /**
+ * Constant indicating that the session is dropped by Transcoding service due to hitting
+ * the limit, e.g. too many back to back transcoding happen in a short time frame.
+ */
+ public static final int ERROR_DROPPED_BY_SERVICE = 1;
+
+ /**
+ * Constant indicating the backing transcoding service is died. Client should enqueue the
+ * the request again.
+ */
+ public static final int ERROR_SERVICE_DIED = 2;
+
/** Listener that gets notified when the progress changes. */
@FunctionalInterface
public interface OnProgressUpdateListener {
@@ -1272,6 +1301,8 @@ public final class MediaTranscodeManager {
@GuardedBy("mLock")
private @Result int mResult = RESULT_NONE;
@GuardedBy("mLock")
+ private @TranscodingSessionErrorCode int mErrorCode = ERROR_NONE;
+ @GuardedBy("mLock")
private boolean mHasRetried = false;
// The original request that associated with this session.
private final TranscodingRequest mRequest;
@@ -1325,10 +1356,20 @@ public final class MediaTranscodeManager {
}
private void updateStatusAndResult(@Status int sessionStatus,
- @Result int sessionResult) {
+ @Result int sessionResult, @TranscodingSessionErrorCode int errorCode) {
synchronized (mLock) {
mStatus = sessionStatus;
mResult = sessionResult;
+ mErrorCode = errorCode;
+ }
+ }
+
+ /**
+ * Retrieve the error code associated with the RESULT_ERROR.
+ */
+ public @TranscodingSessionErrorCode int getErrorCode() {
+ synchronized (mLock) {
+ return mErrorCode;
}
}
diff --git a/api/Android.bp b/api/Android.bp
index 1d4698e7c512..1fdf1771bb13 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -347,3 +347,49 @@ genrule {
out: ["combined-removed-dex.txt"],
cmd: "$(location gen_combined_removed_dex.sh) $(location metalava) $(genDir) $(in) > $(out)",
}
+
+genrule {
+ name: "services-system-server-current.txt",
+ srcs: [
+ ":service-permission{.system-server.api.txt}",
+ ":non-updatable-system-server-current.txt",
+ ],
+ out: ["system-server-current.txt"],
+ tools: ["metalava"],
+ cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)",
+ dists: [
+ {
+ targets: ["droidcore"],
+ dir: "api",
+ dest: "system-server-current.txt",
+ },
+ {
+ targets: ["sdk", "win_sdk"],
+ dir: "apistubs/android/system-server/api",
+ dest: "merge-android.txt",
+ },
+ ],
+}
+
+genrule {
+ name: "services-system-server-removed.txt",
+ srcs: [
+ ":service-permission{.system-server.removed-api.txt}",
+ ":non-updatable-system-server-removed.txt",
+ ],
+ out: ["system-server-removed.txt"],
+ tools: ["metalava"],
+ cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)",
+ dists: [
+ {
+ targets: ["droidcore"],
+ dir: "api",
+ dest: "system-server-removed.txt",
+ },
+ {
+ targets: ["sdk", "win_sdk"],
+ dir: "apistubs/android/system-server/api",
+ dest: "merge-removed.txt",
+ },
+ ],
+}
diff --git a/core/api/current.txt b/core/api/current.txt
index 613d4b6ce214..54aa3564188c 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -158,6 +158,7 @@ package android {
field public static final String SET_WALLPAPER_HINTS = "android.permission.SET_WALLPAPER_HINTS";
field public static final String SIGNAL_PERSISTENT_PROCESSES = "android.permission.SIGNAL_PERSISTENT_PROCESSES";
field @Deprecated public static final String SMS_FINANCIAL_TRANSACTIONS = "android.permission.SMS_FINANCIAL_TRANSACTIONS";
+ field public static final String START_FOREGROUND_SERVICES_FROM_BACKGROUND = "android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND";
field public static final String START_VIEW_PERMISSION_USAGE = "android.permission.START_VIEW_PERMISSION_USAGE";
field public static final String STATUS_BAR = "android.permission.STATUS_BAR";
field public static final String SYSTEM_ALERT_WINDOW = "android.permission.SYSTEM_ALERT_WINDOW";
@@ -505,7 +506,7 @@ package android {
field public static final int dashGap = 16843175; // 0x10101a7
field public static final int dashWidth = 16843174; // 0x10101a6
field public static final int data = 16842798; // 0x101002e
- field public static final int dataExtractionRules = 16844350; // 0x101063e
+ field public static final int dataExtractionRules = 16844349; // 0x101063d
field public static final int datePickerDialogTheme = 16843948; // 0x10104ac
field public static final int datePickerMode = 16843955; // 0x10104b3
field public static final int datePickerStyle = 16843612; // 0x101035c
@@ -527,8 +528,8 @@ package android {
field public static final int detailSocialSummary = 16843428; // 0x10102a4
field public static final int detailsElementBackground = 16843598; // 0x101034e
field public static final int dial = 16843010; // 0x1010102
- field public static final int dialTint = 16844342; // 0x1010636
- field public static final int dialTintMode = 16844343; // 0x1010637
+ field public static final int dialTint = 16844341; // 0x1010635
+ field public static final int dialTintMode = 16844342; // 0x1010636
field public static final int dialogCornerRadius = 16844145; // 0x1010571
field public static final int dialogIcon = 16843252; // 0x10101f4
field public static final int dialogLayout = 16843255; // 0x10101f7
@@ -726,14 +727,14 @@ package android {
field public static final int groupIndicator = 16843019; // 0x101010b
field public static final int gwpAsanMode = 16844310; // 0x1010616
field public static final int hand_hour = 16843011; // 0x1010103
- field public static final int hand_hourTint = 16844344; // 0x1010638
- field public static final int hand_hourTintMode = 16844345; // 0x1010639
+ field public static final int hand_hourTint = 16844343; // 0x1010637
+ field public static final int hand_hourTintMode = 16844344; // 0x1010638
field public static final int hand_minute = 16843012; // 0x1010104
- field public static final int hand_minuteTint = 16844346; // 0x101063a
- field public static final int hand_minuteTintMode = 16844347; // 0x101063b
+ field public static final int hand_minuteTint = 16844345; // 0x1010639
+ field public static final int hand_minuteTintMode = 16844346; // 0x101063a
field public static final int hand_second = 16844323; // 0x1010623
- field public static final int hand_secondTint = 16844348; // 0x101063c
- field public static final int hand_secondTintMode = 16844349; // 0x101063d
+ field public static final int hand_secondTint = 16844347; // 0x101063b
+ field public static final int hand_secondTintMode = 16844348; // 0x101063c
field public static final int handle = 16843354; // 0x101025a
field public static final int handleProfiling = 16842786; // 0x1010022
field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
@@ -817,6 +818,7 @@ package android {
field public static final int installLocation = 16843447; // 0x10102b7
field public static final int interactiveUiTimeout = 16844181; // 0x1010595
field public static final int interpolator = 16843073; // 0x1010141
+ field public static final int isAccessibilityTool = 16844352; // 0x1010640
field public static final int isAlwaysSyncable = 16843571; // 0x1010333
field public static final int isAsciiCapable = 16843753; // 0x10103e9
field public static final int isAuxiliary = 16843647; // 0x101037f
@@ -968,8 +970,8 @@ package android {
field public static final int maxLines = 16843091; // 0x1010153
field public static final int maxLongVersionCode = 16844163; // 0x1010583
field public static final int maxRecents = 16843846; // 0x1010446
- field public static final int maxResizeHeight = 16844339; // 0x1010633
- field public static final int maxResizeWidth = 16844338; // 0x1010632
+ field public static final int maxResizeHeight = 16844338; // 0x1010632
+ field public static final int maxResizeWidth = 16844337; // 0x1010631
field public static final int maxRows = 16843059; // 0x1010133
field public static final int maxSdkVersion = 16843377; // 0x1010271
field public static final int maxWidth = 16843039; // 0x101011f
@@ -1072,7 +1074,7 @@ package android {
field public static final int panelTextAppearance = 16842850; // 0x1010062
field public static final int parentActivityName = 16843687; // 0x10103a7
field @Deprecated public static final int password = 16843100; // 0x101015c
- field public static final int passwordsActivity = 16844351; // 0x101063f
+ field public static final int passwordsActivity = 16844350; // 0x101063e
field public static final int path = 16842794; // 0x101002a
field public static final int pathAdvancedPattern = 16844320; // 0x1010620
field public static final int pathData = 16843781; // 0x1010405
@@ -1197,7 +1199,6 @@ package android {
field public static final int right = 16843183; // 0x10101af
field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
field public static final int ringtoneType = 16843257; // 0x10101f9
- field public static final int rippleStyle = 16844337; // 0x1010631
field public static final int rollbackDataPolicy = 16844311; // 0x1010617
field public static final int rotation = 16843558; // 0x1010326
field public static final int rotationAnimation = 16844090; // 0x101053a
@@ -1259,7 +1260,7 @@ package android {
field public static final int segmentedButtonStyle = 16843568; // 0x1010330
field public static final int selectAllOnFocus = 16843102; // 0x101015e
field public static final int selectable = 16843238; // 0x10101e6
- field public static final int selectableAsDefault = 16844352; // 0x1010640
+ field public static final int selectableAsDefault = 16844351; // 0x101063f
field public static final int selectableItemBackground = 16843534; // 0x101030e
field public static final int selectableItemBackgroundBorderless = 16843868; // 0x101045c
field @Deprecated public static final int selectedDateVerticalBar = 16843591; // 0x1010347
@@ -1406,8 +1407,8 @@ package android {
field public static final int tabWidgetStyle = 16842883; // 0x1010083
field public static final int tag = 16842961; // 0x10100d1
field public static final int targetActivity = 16843266; // 0x1010202
- field public static final int targetCellHeight = 16844341; // 0x1010635
- field public static final int targetCellWidth = 16844340; // 0x1010634
+ field public static final int targetCellHeight = 16844340; // 0x1010634
+ field public static final int targetCellWidth = 16844339; // 0x1010633
field public static final int targetClass = 16842799; // 0x101002f
field @Deprecated public static final int targetDescriptions = 16843680; // 0x10103a0
field public static final int targetId = 16843740; // 0x10103dc
@@ -3101,6 +3102,7 @@ package android.accessibilityservice {
method public int getNonInteractiveUiTimeoutMillis();
method public android.content.pm.ResolveInfo getResolveInfo();
method public String getSettingsActivityName();
+ method public boolean isAccessibilityTool();
method public String loadDescription(android.content.pm.PackageManager);
method public CharSequence loadSummary(android.content.pm.PackageManager);
method public void setInteractiveUiTimeoutMillis(@IntRange(from=0) int);
@@ -3852,7 +3854,7 @@ package android.app {
method @Deprecated public void onTabUnselected(android.app.ActionBar.Tab, android.app.FragmentTransaction);
}
- public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
ctor public Activity();
method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
method public void closeContextMenu();
@@ -4768,9 +4770,9 @@ package android.app {
}
public class Dialog implements android.content.DialogInterface android.view.KeyEvent.Callback android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
- ctor public Dialog(@NonNull android.content.Context);
- ctor public Dialog(@NonNull android.content.Context, @StyleRes int);
- ctor protected Dialog(@NonNull android.content.Context, boolean, @Nullable android.content.DialogInterface.OnCancelListener);
+ ctor public Dialog(@NonNull @UiContext android.content.Context);
+ ctor public Dialog(@NonNull @UiContext android.content.Context, @StyleRes int);
+ ctor protected Dialog(@NonNull @UiContext android.content.Context, boolean, @Nullable android.content.DialogInterface.OnCancelListener);
method public void addContentView(@NonNull android.view.View, @Nullable android.view.ViewGroup.LayoutParams);
method public void cancel();
method public void closeOptionsMenu();
@@ -4784,7 +4786,7 @@ package android.app {
method public boolean dispatchTrackballEvent(@NonNull android.view.MotionEvent);
method public <T extends android.view.View> T findViewById(@IdRes int);
method @Nullable public android.app.ActionBar getActionBar();
- method @NonNull public final android.content.Context getContext();
+ method @NonNull @UiContext public final android.content.Context getContext();
method @Nullable public android.view.View getCurrentFocus();
method @NonNull public android.view.LayoutInflater getLayoutInflater();
method @Nullable public final android.app.Activity getOwnerActivity();
@@ -10343,10 +10345,10 @@ package android.content {
method @NonNull public android.content.Context createContext(@NonNull android.content.ContextParams);
method public abstract android.content.Context createContextForSplit(String) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.content.Context createDeviceProtectedStorageContext();
- method public abstract android.content.Context createDisplayContext(@NonNull android.view.Display);
+ method @DisplayContext public abstract android.content.Context createDisplayContext(@NonNull android.view.Display);
method public abstract android.content.Context createPackageContext(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
- method @NonNull public android.content.Context createWindowContext(int, @Nullable android.os.Bundle);
- method @NonNull public android.content.Context createWindowContext(@NonNull android.view.Display, int, @Nullable android.os.Bundle);
+ method @NonNull @UiContext public android.content.Context createWindowContext(int, @Nullable android.os.Bundle);
+ method @NonNull @UiContext public android.content.Context createWindowContext(@NonNull android.view.Display, int, @Nullable android.os.Bundle);
method public abstract String[] databaseList();
method public abstract boolean deleteDatabase(String);
method public abstract boolean deleteFile(String);
@@ -10511,7 +10513,7 @@ package android.content {
field public static final String JOB_SCHEDULER_SERVICE = "jobscheduler";
field public static final String KEYGUARD_SERVICE = "keyguard";
field public static final String LAUNCHER_APPS_SERVICE = "launcherapps";
- field public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
+ field @UiContext public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
field public static final String LOCATION_SERVICE = "location";
field public static final String MEDIA_COMMUNICATION_SERVICE = "media_communication";
field public static final String MEDIA_METRICS_SERVICE = "media_metrics";
@@ -10556,12 +10558,12 @@ package android.content {
field public static final String VIBRATOR_MANAGER_SERVICE = "vibrator_manager";
field public static final String VIBRATOR_SERVICE = "vibrator";
field public static final String VPN_MANAGEMENT_SERVICE = "vpn_management";
- field public static final String WALLPAPER_SERVICE = "wallpaper";
+ field @UiContext public static final String WALLPAPER_SERVICE = "wallpaper";
field public static final String WIFI_AWARE_SERVICE = "wifiaware";
field public static final String WIFI_P2P_SERVICE = "wifip2p";
field public static final String WIFI_RTT_RANGING_SERVICE = "wifirtt";
field public static final String WIFI_SERVICE = "wifi";
- field public static final String WINDOW_SERVICE = "window";
+ field @UiContext public static final String WINDOW_SERVICE = "window";
}
public final class ContextParams {
@@ -10572,9 +10574,10 @@ package android.content {
public static final class ContextParams.Builder {
ctor public ContextParams.Builder();
+ ctor public ContextParams.Builder(@NonNull android.content.ContextParams);
method @NonNull public android.content.ContextParams build();
- method @NonNull public android.content.ContextParams.Builder setAttributionTag(@NonNull String);
- method @NonNull public android.content.ContextParams.Builder setReceiverPackage(@NonNull String, @Nullable String);
+ method @NonNull public android.content.ContextParams.Builder setAttributionTag(@Nullable String);
+ method @NonNull public android.content.ContextParams.Builder setReceiverPackage(@Nullable String, @Nullable String);
}
public class ContextWrapper extends android.content.Context {
@@ -16683,13 +16686,9 @@ package android.graphics.drawable {
public class RippleDrawable extends android.graphics.drawable.LayerDrawable {
ctor public RippleDrawable(@NonNull android.content.res.ColorStateList, @Nullable android.graphics.drawable.Drawable, @Nullable android.graphics.drawable.Drawable);
method public int getRadius();
- method public int getRippleStyle();
method public void setColor(android.content.res.ColorStateList);
method public void setRadius(int);
- method public void setRippleStyle(int) throws java.lang.IllegalArgumentException;
field public static final int RADIUS_AUTO = -1; // 0xffffffff
- field public static final int STYLE_PATTERNED = 1; // 0x1
- field public static final int STYLE_SOLID = 0; // 0x0
}
public class RotateDrawable extends android.graphics.drawable.DrawableWrapper {
@@ -19054,7 +19053,7 @@ package android.inputmethodservice {
method public void startInternalChanges();
}
- public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
+ @UiContext public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
ctor public InputMethodService();
method @Deprecated public boolean enableHardwareAcceleration();
method public int getBackDisposition();
@@ -20565,6 +20564,7 @@ package android.media {
method @NonNull public android.media.AudioRecord.Builder setAudioPlaybackCaptureConfig(@NonNull android.media.AudioPlaybackCaptureConfiguration);
method public android.media.AudioRecord.Builder setAudioSource(int) throws java.lang.IllegalArgumentException;
method public android.media.AudioRecord.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException;
+ method @NonNull public android.media.AudioRecord.Builder setContext(@NonNull android.content.Context);
method @NonNull public android.media.AudioRecord.Builder setPrivacySensitive(boolean);
}
@@ -22739,7 +22739,8 @@ package android.media {
}
public class MediaRecorder implements android.media.AudioRecordingMonitor android.media.AudioRouting android.media.MicrophoneDirection {
- ctor public MediaRecorder();
+ ctor @Deprecated public MediaRecorder();
+ ctor public MediaRecorder(@NonNull android.content.Context);
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method protected void finalize();
method public java.util.List<android.media.MicrophoneInfo> getActiveMicrophones() throws java.io.IOException;
@@ -26551,236 +26552,236 @@ package android.net.nsd {
package android.net.rtp {
- public class AudioCodec {
- method public static android.net.rtp.AudioCodec getCodec(int, String, String);
- method public static android.net.rtp.AudioCodec[] getCodecs();
- field public static final android.net.rtp.AudioCodec AMR;
- field public static final android.net.rtp.AudioCodec GSM;
- field public static final android.net.rtp.AudioCodec GSM_EFR;
- field public static final android.net.rtp.AudioCodec PCMA;
- field public static final android.net.rtp.AudioCodec PCMU;
- field public final String fmtp;
- field public final String rtpmap;
- field public final int type;
+ @Deprecated public class AudioCodec {
+ method @Deprecated public static android.net.rtp.AudioCodec getCodec(int, String, String);
+ method @Deprecated public static android.net.rtp.AudioCodec[] getCodecs();
+ field @Deprecated public static final android.net.rtp.AudioCodec AMR;
+ field @Deprecated public static final android.net.rtp.AudioCodec GSM;
+ field @Deprecated public static final android.net.rtp.AudioCodec GSM_EFR;
+ field @Deprecated public static final android.net.rtp.AudioCodec PCMA;
+ field @Deprecated public static final android.net.rtp.AudioCodec PCMU;
+ field @Deprecated public final String fmtp;
+ field @Deprecated public final String rtpmap;
+ field @Deprecated public final int type;
}
- public class AudioGroup {
+ @Deprecated public class AudioGroup {
ctor @Deprecated public AudioGroup();
- ctor public AudioGroup(@NonNull android.content.Context);
- method public void clear();
- method public int getMode();
- method public android.net.rtp.AudioStream[] getStreams();
- method public void sendDtmf(int);
- method public void setMode(int);
- field public static final int MODE_ECHO_SUPPRESSION = 3; // 0x3
- field public static final int MODE_MUTED = 1; // 0x1
- field public static final int MODE_NORMAL = 2; // 0x2
- field public static final int MODE_ON_HOLD = 0; // 0x0
- }
-
- public class AudioStream extends android.net.rtp.RtpStream {
- ctor public AudioStream(java.net.InetAddress) throws java.net.SocketException;
- method public android.net.rtp.AudioCodec getCodec();
- method public int getDtmfType();
- method public android.net.rtp.AudioGroup getGroup();
- method public final boolean isBusy();
- method public void join(android.net.rtp.AudioGroup);
- method public void setCodec(android.net.rtp.AudioCodec);
- method public void setDtmfType(int);
- }
-
- public class RtpStream {
- method public void associate(java.net.InetAddress, int);
- method public java.net.InetAddress getLocalAddress();
- method public int getLocalPort();
- method public int getMode();
- method public java.net.InetAddress getRemoteAddress();
- method public int getRemotePort();
- method public boolean isBusy();
- method public void release();
- method public void setMode(int);
- field public static final int MODE_NORMAL = 0; // 0x0
- field public static final int MODE_RECEIVE_ONLY = 2; // 0x2
- field public static final int MODE_SEND_ONLY = 1; // 0x1
+ ctor @Deprecated public AudioGroup(@NonNull android.content.Context);
+ method @Deprecated public void clear();
+ method @Deprecated public int getMode();
+ method @Deprecated public android.net.rtp.AudioStream[] getStreams();
+ method @Deprecated public void sendDtmf(int);
+ method @Deprecated public void setMode(int);
+ field @Deprecated public static final int MODE_ECHO_SUPPRESSION = 3; // 0x3
+ field @Deprecated public static final int MODE_MUTED = 1; // 0x1
+ field @Deprecated public static final int MODE_NORMAL = 2; // 0x2
+ field @Deprecated public static final int MODE_ON_HOLD = 0; // 0x0
+ }
+
+ @Deprecated public class AudioStream extends android.net.rtp.RtpStream {
+ ctor @Deprecated public AudioStream(java.net.InetAddress) throws java.net.SocketException;
+ method @Deprecated public android.net.rtp.AudioCodec getCodec();
+ method @Deprecated public int getDtmfType();
+ method @Deprecated public android.net.rtp.AudioGroup getGroup();
+ method @Deprecated public final boolean isBusy();
+ method @Deprecated public void join(android.net.rtp.AudioGroup);
+ method @Deprecated public void setCodec(android.net.rtp.AudioCodec);
+ method @Deprecated public void setDtmfType(int);
+ }
+
+ @Deprecated public class RtpStream {
+ method @Deprecated public void associate(java.net.InetAddress, int);
+ method @Deprecated public java.net.InetAddress getLocalAddress();
+ method @Deprecated public int getLocalPort();
+ method @Deprecated public int getMode();
+ method @Deprecated public java.net.InetAddress getRemoteAddress();
+ method @Deprecated public int getRemotePort();
+ method @Deprecated public boolean isBusy();
+ method @Deprecated public void release();
+ method @Deprecated public void setMode(int);
+ field @Deprecated public static final int MODE_NORMAL = 0; // 0x0
+ field @Deprecated public static final int MODE_RECEIVE_ONLY = 2; // 0x2
+ field @Deprecated public static final int MODE_SEND_ONLY = 1; // 0x1
}
}
package android.net.sip {
- public class SipAudioCall {
- ctor public SipAudioCall(android.content.Context, android.net.sip.SipProfile);
- method public void answerCall(int) throws android.net.sip.SipException;
- method public void attachCall(android.net.sip.SipSession, String) throws android.net.sip.SipException;
- method public void close();
- method public void continueCall(int) throws android.net.sip.SipException;
- method public void endCall() throws android.net.sip.SipException;
- method public android.net.sip.SipProfile getLocalProfile();
- method public android.net.sip.SipProfile getPeerProfile();
- method public int getState();
- method public void holdCall(int) throws android.net.sip.SipException;
- method public boolean isInCall();
- method public boolean isMuted();
- method public boolean isOnHold();
- method public void makeCall(android.net.sip.SipProfile, android.net.sip.SipSession, int) throws android.net.sip.SipException;
- method public void sendDtmf(int);
- method public void sendDtmf(int, android.os.Message);
- method public void setListener(android.net.sip.SipAudioCall.Listener);
- method public void setListener(android.net.sip.SipAudioCall.Listener, boolean);
- method public void setSpeakerMode(boolean);
- method public void startAudio();
- method public void toggleMute();
- }
-
- public static class SipAudioCall.Listener {
- ctor public SipAudioCall.Listener();
- method public void onCallBusy(android.net.sip.SipAudioCall);
- method public void onCallEnded(android.net.sip.SipAudioCall);
- method public void onCallEstablished(android.net.sip.SipAudioCall);
- method public void onCallHeld(android.net.sip.SipAudioCall);
- method public void onCalling(android.net.sip.SipAudioCall);
- method public void onChanged(android.net.sip.SipAudioCall);
- method public void onError(android.net.sip.SipAudioCall, int, String);
- method public void onReadyToCall(android.net.sip.SipAudioCall);
- method public void onRinging(android.net.sip.SipAudioCall, android.net.sip.SipProfile);
- method public void onRingingBack(android.net.sip.SipAudioCall);
- }
-
- public class SipErrorCode {
- method public static String toString(int);
- field public static final int CLIENT_ERROR = -4; // 0xfffffffc
- field public static final int CROSS_DOMAIN_AUTHENTICATION = -11; // 0xfffffff5
- field public static final int DATA_CONNECTION_LOST = -10; // 0xfffffff6
- field public static final int INVALID_CREDENTIALS = -8; // 0xfffffff8
- field public static final int INVALID_REMOTE_URI = -6; // 0xfffffffa
- field public static final int IN_PROGRESS = -9; // 0xfffffff7
- field public static final int NO_ERROR = 0; // 0x0
- field public static final int PEER_NOT_REACHABLE = -7; // 0xfffffff9
- field public static final int SERVER_ERROR = -2; // 0xfffffffe
- field public static final int SERVER_UNREACHABLE = -12; // 0xfffffff4
- field public static final int SOCKET_ERROR = -1; // 0xffffffff
- field public static final int TIME_OUT = -5; // 0xfffffffb
- field public static final int TRANSACTION_TERMINTED = -3; // 0xfffffffd
- }
-
- public class SipException extends java.lang.Exception {
- ctor public SipException();
- ctor public SipException(String);
- ctor public SipException(String, Throwable);
- }
-
- public class SipManager {
- method public void close(String) throws android.net.sip.SipException;
- method public android.net.sip.SipSession createSipSession(android.net.sip.SipProfile, android.net.sip.SipSession.Listener) throws android.net.sip.SipException;
- method public static String getCallId(android.content.Intent);
- method public static String getOfferSessionDescription(android.content.Intent);
- method public android.net.sip.SipSession getSessionFor(android.content.Intent) throws android.net.sip.SipException;
- method public static boolean isApiSupported(android.content.Context);
- method public static boolean isIncomingCallIntent(android.content.Intent);
- method public boolean isOpened(String) throws android.net.sip.SipException;
- method public boolean isRegistered(String) throws android.net.sip.SipException;
- method public static boolean isSipWifiOnly(android.content.Context);
- method public static boolean isVoipSupported(android.content.Context);
- method public android.net.sip.SipAudioCall makeAudioCall(android.net.sip.SipProfile, android.net.sip.SipProfile, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
- method public android.net.sip.SipAudioCall makeAudioCall(String, String, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
- method public static android.net.sip.SipManager newInstance(android.content.Context);
- method public void open(android.net.sip.SipProfile) throws android.net.sip.SipException;
- method public void open(android.net.sip.SipProfile, android.app.PendingIntent, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
- method public void register(android.net.sip.SipProfile, int, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
- method public void setRegistrationListener(String, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
- method public android.net.sip.SipAudioCall takeAudioCall(android.content.Intent, android.net.sip.SipAudioCall.Listener) throws android.net.sip.SipException;
- method public void unregister(android.net.sip.SipProfile, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
- field public static final String EXTRA_CALL_ID = "android:sipCallID";
- field public static final String EXTRA_OFFER_SD = "android:sipOfferSD";
- field public static final int INCOMING_CALL_RESULT_CODE = 101; // 0x65
- }
-
- public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
- method public int describeContents();
- method public String getAuthUserName();
- method public boolean getAutoRegistration();
- method public String getDisplayName();
- method public String getPassword();
- method public int getPort();
- method public String getProfileName();
- method public String getProtocol();
- method public String getProxyAddress();
- method public boolean getSendKeepAlive();
- method public String getSipDomain();
- method public String getUriString();
- method public String getUserName();
- method public void setCallingUid(int);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.sip.SipProfile> CREATOR;
- }
-
- public static class SipProfile.Builder {
- ctor public SipProfile.Builder(android.net.sip.SipProfile);
- ctor public SipProfile.Builder(String) throws java.text.ParseException;
- ctor public SipProfile.Builder(String, String) throws java.text.ParseException;
- method public android.net.sip.SipProfile build();
- method public android.net.sip.SipProfile.Builder setAuthUserName(String);
- method public android.net.sip.SipProfile.Builder setAutoRegistration(boolean);
- method public android.net.sip.SipProfile.Builder setDisplayName(String);
- method public android.net.sip.SipProfile.Builder setOutboundProxy(String);
- method public android.net.sip.SipProfile.Builder setPassword(String);
- method public android.net.sip.SipProfile.Builder setPort(int) throws java.lang.IllegalArgumentException;
- method public android.net.sip.SipProfile.Builder setProfileName(String);
- method public android.net.sip.SipProfile.Builder setProtocol(String) throws java.lang.IllegalArgumentException;
- method public android.net.sip.SipProfile.Builder setSendKeepAlive(boolean);
- }
-
- public interface SipRegistrationListener {
- method public void onRegistering(String);
- method public void onRegistrationDone(String, long);
- method public void onRegistrationFailed(String, int, String);
- }
-
- public final class SipSession {
- method public void answerCall(String, int);
- method public void changeCall(String, int);
- method public void endCall();
- method public String getCallId();
- method public String getLocalIp();
- method public android.net.sip.SipProfile getLocalProfile();
- method public android.net.sip.SipProfile getPeerProfile();
- method public int getState();
- method public boolean isInCall();
- method public void makeCall(android.net.sip.SipProfile, String, int);
- method public void register(int);
- method public void setListener(android.net.sip.SipSession.Listener);
- method public void unregister();
- }
-
- public static class SipSession.Listener {
- ctor public SipSession.Listener();
- method public void onCallBusy(android.net.sip.SipSession);
- method public void onCallChangeFailed(android.net.sip.SipSession, int, String);
- method public void onCallEnded(android.net.sip.SipSession);
- method public void onCallEstablished(android.net.sip.SipSession, String);
- method public void onCalling(android.net.sip.SipSession);
- method public void onError(android.net.sip.SipSession, int, String);
- method public void onRegistering(android.net.sip.SipSession);
- method public void onRegistrationDone(android.net.sip.SipSession, int);
- method public void onRegistrationFailed(android.net.sip.SipSession, int, String);
- method public void onRegistrationTimeout(android.net.sip.SipSession);
- method public void onRinging(android.net.sip.SipSession, android.net.sip.SipProfile, String);
- method public void onRingingBack(android.net.sip.SipSession);
- }
-
- public static class SipSession.State {
- method public static String toString(int);
- field public static final int DEREGISTERING = 2; // 0x2
- field public static final int INCOMING_CALL = 3; // 0x3
- field public static final int INCOMING_CALL_ANSWERING = 4; // 0x4
- field public static final int IN_CALL = 8; // 0x8
- field public static final int NOT_DEFINED = 101; // 0x65
- field public static final int OUTGOING_CALL = 5; // 0x5
- field public static final int OUTGOING_CALL_CANCELING = 7; // 0x7
- field public static final int OUTGOING_CALL_RING_BACK = 6; // 0x6
- field public static final int PINGING = 9; // 0x9
- field public static final int READY_TO_CALL = 0; // 0x0
- field public static final int REGISTERING = 1; // 0x1
+ @Deprecated public class SipAudioCall {
+ ctor @Deprecated public SipAudioCall(android.content.Context, android.net.sip.SipProfile);
+ method @Deprecated public void answerCall(int) throws android.net.sip.SipException;
+ method @Deprecated public void attachCall(android.net.sip.SipSession, String) throws android.net.sip.SipException;
+ method @Deprecated public void close();
+ method @Deprecated public void continueCall(int) throws android.net.sip.SipException;
+ method @Deprecated public void endCall() throws android.net.sip.SipException;
+ method @Deprecated public android.net.sip.SipProfile getLocalProfile();
+ method @Deprecated public android.net.sip.SipProfile getPeerProfile();
+ method @Deprecated public int getState();
+ method @Deprecated public void holdCall(int) throws android.net.sip.SipException;
+ method @Deprecated public boolean isInCall();
+ method @Deprecated public boolean isMuted();
+ method @Deprecated public boolean isOnHold();
+ method @Deprecated public void makeCall(android.net.sip.SipProfile, android.net.sip.SipSession, int) throws android.net.sip.SipException;
+ method @Deprecated public void sendDtmf(int);
+ method @Deprecated public void sendDtmf(int, android.os.Message);
+ method @Deprecated public void setListener(android.net.sip.SipAudioCall.Listener);
+ method @Deprecated public void setListener(android.net.sip.SipAudioCall.Listener, boolean);
+ method @Deprecated public void setSpeakerMode(boolean);
+ method @Deprecated public void startAudio();
+ method @Deprecated public void toggleMute();
+ }
+
+ @Deprecated public static class SipAudioCall.Listener {
+ ctor @Deprecated public SipAudioCall.Listener();
+ method @Deprecated public void onCallBusy(android.net.sip.SipAudioCall);
+ method @Deprecated public void onCallEnded(android.net.sip.SipAudioCall);
+ method @Deprecated public void onCallEstablished(android.net.sip.SipAudioCall);
+ method @Deprecated public void onCallHeld(android.net.sip.SipAudioCall);
+ method @Deprecated public void onCalling(android.net.sip.SipAudioCall);
+ method @Deprecated public void onChanged(android.net.sip.SipAudioCall);
+ method @Deprecated public void onError(android.net.sip.SipAudioCall, int, String);
+ method @Deprecated public void onReadyToCall(android.net.sip.SipAudioCall);
+ method @Deprecated public void onRinging(android.net.sip.SipAudioCall, android.net.sip.SipProfile);
+ method @Deprecated public void onRingingBack(android.net.sip.SipAudioCall);
+ }
+
+ @Deprecated public class SipErrorCode {
+ method @Deprecated public static String toString(int);
+ field @Deprecated public static final int CLIENT_ERROR = -4; // 0xfffffffc
+ field @Deprecated public static final int CROSS_DOMAIN_AUTHENTICATION = -11; // 0xfffffff5
+ field @Deprecated public static final int DATA_CONNECTION_LOST = -10; // 0xfffffff6
+ field @Deprecated public static final int INVALID_CREDENTIALS = -8; // 0xfffffff8
+ field @Deprecated public static final int INVALID_REMOTE_URI = -6; // 0xfffffffa
+ field @Deprecated public static final int IN_PROGRESS = -9; // 0xfffffff7
+ field @Deprecated public static final int NO_ERROR = 0; // 0x0
+ field @Deprecated public static final int PEER_NOT_REACHABLE = -7; // 0xfffffff9
+ field @Deprecated public static final int SERVER_ERROR = -2; // 0xfffffffe
+ field @Deprecated public static final int SERVER_UNREACHABLE = -12; // 0xfffffff4
+ field @Deprecated public static final int SOCKET_ERROR = -1; // 0xffffffff
+ field @Deprecated public static final int TIME_OUT = -5; // 0xfffffffb
+ field @Deprecated public static final int TRANSACTION_TERMINTED = -3; // 0xfffffffd
+ }
+
+ @Deprecated public class SipException extends java.lang.Exception {
+ ctor @Deprecated public SipException();
+ ctor @Deprecated public SipException(String);
+ ctor @Deprecated public SipException(String, Throwable);
+ }
+
+ @Deprecated public class SipManager {
+ method @Deprecated public void close(String) throws android.net.sip.SipException;
+ method @Deprecated public android.net.sip.SipSession createSipSession(android.net.sip.SipProfile, android.net.sip.SipSession.Listener) throws android.net.sip.SipException;
+ method @Deprecated public static String getCallId(android.content.Intent);
+ method @Deprecated public static String getOfferSessionDescription(android.content.Intent);
+ method @Deprecated public android.net.sip.SipSession getSessionFor(android.content.Intent) throws android.net.sip.SipException;
+ method @Deprecated public static boolean isApiSupported(android.content.Context);
+ method @Deprecated public static boolean isIncomingCallIntent(android.content.Intent);
+ method @Deprecated public boolean isOpened(String) throws android.net.sip.SipException;
+ method @Deprecated public boolean isRegistered(String) throws android.net.sip.SipException;
+ method @Deprecated public static boolean isSipWifiOnly(android.content.Context);
+ method @Deprecated public static boolean isVoipSupported(android.content.Context);
+ method @Deprecated public android.net.sip.SipAudioCall makeAudioCall(android.net.sip.SipProfile, android.net.sip.SipProfile, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
+ method @Deprecated public android.net.sip.SipAudioCall makeAudioCall(String, String, android.net.sip.SipAudioCall.Listener, int) throws android.net.sip.SipException;
+ method @Deprecated public static android.net.sip.SipManager newInstance(android.content.Context);
+ method @Deprecated public void open(android.net.sip.SipProfile) throws android.net.sip.SipException;
+ method @Deprecated public void open(android.net.sip.SipProfile, android.app.PendingIntent, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+ method @Deprecated public void register(android.net.sip.SipProfile, int, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+ method @Deprecated public void setRegistrationListener(String, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+ method @Deprecated public android.net.sip.SipAudioCall takeAudioCall(android.content.Intent, android.net.sip.SipAudioCall.Listener) throws android.net.sip.SipException;
+ method @Deprecated public void unregister(android.net.sip.SipProfile, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+ field @Deprecated public static final String EXTRA_CALL_ID = "android:sipCallID";
+ field @Deprecated public static final String EXTRA_OFFER_SD = "android:sipOfferSD";
+ field @Deprecated public static final int INCOMING_CALL_RESULT_CODE = 101; // 0x65
+ }
+
+ @Deprecated public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
+ method @Deprecated public int describeContents();
+ method @Deprecated public String getAuthUserName();
+ method @Deprecated public boolean getAutoRegistration();
+ method @Deprecated public String getDisplayName();
+ method @Deprecated public String getPassword();
+ method @Deprecated public int getPort();
+ method @Deprecated public String getProfileName();
+ method @Deprecated public String getProtocol();
+ method @Deprecated public String getProxyAddress();
+ method @Deprecated public boolean getSendKeepAlive();
+ method @Deprecated public String getSipDomain();
+ method @Deprecated public String getUriString();
+ method @Deprecated public String getUserName();
+ method @Deprecated public void setCallingUid(int);
+ method @Deprecated public void writeToParcel(android.os.Parcel, int);
+ field @Deprecated public static final android.os.Parcelable.Creator<android.net.sip.SipProfile> CREATOR;
+ }
+
+ @Deprecated public static class SipProfile.Builder {
+ ctor @Deprecated public SipProfile.Builder(android.net.sip.SipProfile);
+ ctor @Deprecated public SipProfile.Builder(String) throws java.text.ParseException;
+ ctor @Deprecated public SipProfile.Builder(String, String) throws java.text.ParseException;
+ method @Deprecated public android.net.sip.SipProfile build();
+ method @Deprecated public android.net.sip.SipProfile.Builder setAuthUserName(String);
+ method @Deprecated public android.net.sip.SipProfile.Builder setAutoRegistration(boolean);
+ method @Deprecated public android.net.sip.SipProfile.Builder setDisplayName(String);
+ method @Deprecated public android.net.sip.SipProfile.Builder setOutboundProxy(String);
+ method @Deprecated public android.net.sip.SipProfile.Builder setPassword(String);
+ method @Deprecated public android.net.sip.SipProfile.Builder setPort(int) throws java.lang.IllegalArgumentException;
+ method @Deprecated public android.net.sip.SipProfile.Builder setProfileName(String);
+ method @Deprecated public android.net.sip.SipProfile.Builder setProtocol(String) throws java.lang.IllegalArgumentException;
+ method @Deprecated public android.net.sip.SipProfile.Builder setSendKeepAlive(boolean);
+ }
+
+ @Deprecated public interface SipRegistrationListener {
+ method @Deprecated public void onRegistering(String);
+ method @Deprecated public void onRegistrationDone(String, long);
+ method @Deprecated public void onRegistrationFailed(String, int, String);
+ }
+
+ @Deprecated public final class SipSession {
+ method @Deprecated public void answerCall(String, int);
+ method @Deprecated public void changeCall(String, int);
+ method @Deprecated public void endCall();
+ method @Deprecated public String getCallId();
+ method @Deprecated public String getLocalIp();
+ method @Deprecated public android.net.sip.SipProfile getLocalProfile();
+ method @Deprecated public android.net.sip.SipProfile getPeerProfile();
+ method @Deprecated public int getState();
+ method @Deprecated public boolean isInCall();
+ method @Deprecated public void makeCall(android.net.sip.SipProfile, String, int);
+ method @Deprecated public void register(int);
+ method @Deprecated public void setListener(android.net.sip.SipSession.Listener);
+ method @Deprecated public void unregister();
+ }
+
+ @Deprecated public static class SipSession.Listener {
+ ctor @Deprecated public SipSession.Listener();
+ method @Deprecated public void onCallBusy(android.net.sip.SipSession);
+ method @Deprecated public void onCallChangeFailed(android.net.sip.SipSession, int, String);
+ method @Deprecated public void onCallEnded(android.net.sip.SipSession);
+ method @Deprecated public void onCallEstablished(android.net.sip.SipSession, String);
+ method @Deprecated public void onCalling(android.net.sip.SipSession);
+ method @Deprecated public void onError(android.net.sip.SipSession, int, String);
+ method @Deprecated public void onRegistering(android.net.sip.SipSession);
+ method @Deprecated public void onRegistrationDone(android.net.sip.SipSession, int);
+ method @Deprecated public void onRegistrationFailed(android.net.sip.SipSession, int, String);
+ method @Deprecated public void onRegistrationTimeout(android.net.sip.SipSession);
+ method @Deprecated public void onRinging(android.net.sip.SipSession, android.net.sip.SipProfile, String);
+ method @Deprecated public void onRingingBack(android.net.sip.SipSession);
+ }
+
+ @Deprecated public static class SipSession.State {
+ method @Deprecated public static String toString(int);
+ field @Deprecated public static final int DEREGISTERING = 2; // 0x2
+ field @Deprecated public static final int INCOMING_CALL = 3; // 0x3
+ field @Deprecated public static final int INCOMING_CALL_ANSWERING = 4; // 0x4
+ field @Deprecated public static final int IN_CALL = 8; // 0x8
+ field @Deprecated public static final int NOT_DEFINED = 101; // 0x65
+ field @Deprecated public static final int OUTGOING_CALL = 5; // 0x5
+ field @Deprecated public static final int OUTGOING_CALL_CANCELING = 7; // 0x7
+ field @Deprecated public static final int OUTGOING_CALL_RING_BACK = 6; // 0x6
+ field @Deprecated public static final int PINGING = 9; // 0x9
+ field @Deprecated public static final int READY_TO_CALL = 0; // 0x0
+ field @Deprecated public static final int REGISTERING = 1; // 0x1
}
}
@@ -35647,721 +35648,721 @@ package android.provider {
package android.renderscript {
- public class Allocation extends android.renderscript.BaseObj {
- method public void copy1DRangeFrom(int, int, Object);
- method public void copy1DRangeFrom(int, int, int[]);
- method public void copy1DRangeFrom(int, int, short[]);
- method public void copy1DRangeFrom(int, int, byte[]);
- method public void copy1DRangeFrom(int, int, float[]);
- method public void copy1DRangeFrom(int, int, android.renderscript.Allocation, int);
- method public void copy1DRangeFromUnchecked(int, int, Object);
- method public void copy1DRangeFromUnchecked(int, int, int[]);
- method public void copy1DRangeFromUnchecked(int, int, short[]);
- method public void copy1DRangeFromUnchecked(int, int, byte[]);
- method public void copy1DRangeFromUnchecked(int, int, float[]);
- method public void copy1DRangeTo(int, int, Object);
- method public void copy1DRangeTo(int, int, int[]);
- method public void copy1DRangeTo(int, int, short[]);
- method public void copy1DRangeTo(int, int, byte[]);
- method public void copy1DRangeTo(int, int, float[]);
- method public void copy1DRangeToUnchecked(int, int, Object);
- method public void copy1DRangeToUnchecked(int, int, int[]);
- method public void copy1DRangeToUnchecked(int, int, short[]);
- method public void copy1DRangeToUnchecked(int, int, byte[]);
- method public void copy1DRangeToUnchecked(int, int, float[]);
- method public void copy2DRangeFrom(int, int, int, int, Object);
- method public void copy2DRangeFrom(int, int, int, int, byte[]);
- method public void copy2DRangeFrom(int, int, int, int, short[]);
- method public void copy2DRangeFrom(int, int, int, int, int[]);
- method public void copy2DRangeFrom(int, int, int, int, float[]);
- method public void copy2DRangeFrom(int, int, int, int, android.renderscript.Allocation, int, int);
- method public void copy2DRangeFrom(int, int, android.graphics.Bitmap);
- method public void copy2DRangeTo(int, int, int, int, Object);
- method public void copy2DRangeTo(int, int, int, int, byte[]);
- method public void copy2DRangeTo(int, int, int, int, short[]);
- method public void copy2DRangeTo(int, int, int, int, int[]);
- method public void copy2DRangeTo(int, int, int, int, float[]);
- method public void copy3DRangeFrom(int, int, int, int, int, int, Object);
- method public void copy3DRangeFrom(int, int, int, int, int, int, android.renderscript.Allocation, int, int, int);
- method public void copy3DRangeTo(int, int, int, int, int, int, Object);
- method public void copyFrom(android.renderscript.BaseObj[]);
- method public void copyFrom(Object);
- method public void copyFrom(int[]);
- method public void copyFrom(short[]);
- method public void copyFrom(byte[]);
- method public void copyFrom(float[]);
- method public void copyFrom(android.graphics.Bitmap);
- method public void copyFrom(android.renderscript.Allocation);
- method public void copyFromUnchecked(Object);
- method public void copyFromUnchecked(int[]);
- method public void copyFromUnchecked(short[]);
- method public void copyFromUnchecked(byte[]);
- method public void copyFromUnchecked(float[]);
- method public void copyTo(android.graphics.Bitmap);
- method public void copyTo(Object);
- method public void copyTo(byte[]);
- method public void copyTo(short[]);
- method public void copyTo(int[]);
- method public void copyTo(float[]);
- method public static android.renderscript.Allocation[] createAllocations(android.renderscript.RenderScript, android.renderscript.Type, int, int);
- method public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
- method public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap);
- method public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
- method public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int);
- method public static android.renderscript.Allocation createFromString(android.renderscript.RenderScript, String, int);
- method public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int, int);
- method public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int);
- method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, android.renderscript.Allocation.MipmapControl, int);
- method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, int);
- method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type);
- method public void generateMipmaps();
- method public java.nio.ByteBuffer getByteBuffer();
- method public int getBytesSize();
- method public android.renderscript.Element getElement();
- method public long getStride();
- method public android.view.Surface getSurface();
- method public long getTimeStamp();
- method public android.renderscript.Type getType();
- method public int getUsage();
- method public void ioReceive();
- method public void ioSend();
+ @Deprecated public class Allocation extends android.renderscript.BaseObj {
+ method @Deprecated public void copy1DRangeFrom(int, int, Object);
+ method @Deprecated public void copy1DRangeFrom(int, int, int[]);
+ method @Deprecated public void copy1DRangeFrom(int, int, short[]);
+ method @Deprecated public void copy1DRangeFrom(int, int, byte[]);
+ method @Deprecated public void copy1DRangeFrom(int, int, float[]);
+ method @Deprecated public void copy1DRangeFrom(int, int, android.renderscript.Allocation, int);
+ method @Deprecated public void copy1DRangeFromUnchecked(int, int, Object);
+ method @Deprecated public void copy1DRangeFromUnchecked(int, int, int[]);
+ method @Deprecated public void copy1DRangeFromUnchecked(int, int, short[]);
+ method @Deprecated public void copy1DRangeFromUnchecked(int, int, byte[]);
+ method @Deprecated public void copy1DRangeFromUnchecked(int, int, float[]);
+ method @Deprecated public void copy1DRangeTo(int, int, Object);
+ method @Deprecated public void copy1DRangeTo(int, int, int[]);
+ method @Deprecated public void copy1DRangeTo(int, int, short[]);
+ method @Deprecated public void copy1DRangeTo(int, int, byte[]);
+ method @Deprecated public void copy1DRangeTo(int, int, float[]);
+ method @Deprecated public void copy1DRangeToUnchecked(int, int, Object);
+ method @Deprecated public void copy1DRangeToUnchecked(int, int, int[]);
+ method @Deprecated public void copy1DRangeToUnchecked(int, int, short[]);
+ method @Deprecated public void copy1DRangeToUnchecked(int, int, byte[]);
+ method @Deprecated public void copy1DRangeToUnchecked(int, int, float[]);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, Object);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, byte[]);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, short[]);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, int[]);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, float[]);
+ method @Deprecated public void copy2DRangeFrom(int, int, int, int, android.renderscript.Allocation, int, int);
+ method @Deprecated public void copy2DRangeFrom(int, int, android.graphics.Bitmap);
+ method @Deprecated public void copy2DRangeTo(int, int, int, int, Object);
+ method @Deprecated public void copy2DRangeTo(int, int, int, int, byte[]);
+ method @Deprecated public void copy2DRangeTo(int, int, int, int, short[]);
+ method @Deprecated public void copy2DRangeTo(int, int, int, int, int[]);
+ method @Deprecated public void copy2DRangeTo(int, int, int, int, float[]);
+ method @Deprecated public void copy3DRangeFrom(int, int, int, int, int, int, Object);
+ method @Deprecated public void copy3DRangeFrom(int, int, int, int, int, int, android.renderscript.Allocation, int, int, int);
+ method @Deprecated public void copy3DRangeTo(int, int, int, int, int, int, Object);
+ method @Deprecated public void copyFrom(android.renderscript.BaseObj[]);
+ method @Deprecated public void copyFrom(Object);
+ method @Deprecated public void copyFrom(int[]);
+ method @Deprecated public void copyFrom(short[]);
+ method @Deprecated public void copyFrom(byte[]);
+ method @Deprecated public void copyFrom(float[]);
+ method @Deprecated public void copyFrom(android.graphics.Bitmap);
+ method @Deprecated public void copyFrom(android.renderscript.Allocation);
+ method @Deprecated public void copyFromUnchecked(Object);
+ method @Deprecated public void copyFromUnchecked(int[]);
+ method @Deprecated public void copyFromUnchecked(short[]);
+ method @Deprecated public void copyFromUnchecked(byte[]);
+ method @Deprecated public void copyFromUnchecked(float[]);
+ method @Deprecated public void copyTo(android.graphics.Bitmap);
+ method @Deprecated public void copyTo(Object);
+ method @Deprecated public void copyTo(byte[]);
+ method @Deprecated public void copyTo(short[]);
+ method @Deprecated public void copyTo(int[]);
+ method @Deprecated public void copyTo(float[]);
+ method @Deprecated public static android.renderscript.Allocation[] createAllocations(android.renderscript.RenderScript, android.renderscript.Type, int, int);
+ method @Deprecated public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+ method @Deprecated public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
+ method @Deprecated public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+ method @Deprecated public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap);
+ method @Deprecated public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+ method @Deprecated public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
+ method @Deprecated public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int, android.renderscript.Allocation.MipmapControl, int);
+ method @Deprecated public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int);
+ method @Deprecated public static android.renderscript.Allocation createFromString(android.renderscript.RenderScript, String, int);
+ method @Deprecated public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int, int);
+ method @Deprecated public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int);
+ method @Deprecated public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, android.renderscript.Allocation.MipmapControl, int);
+ method @Deprecated public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, int);
+ method @Deprecated public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type);
+ method @Deprecated public void generateMipmaps();
+ method @Deprecated public java.nio.ByteBuffer getByteBuffer();
+ method @Deprecated public int getBytesSize();
+ method @Deprecated public android.renderscript.Element getElement();
+ method @Deprecated public long getStride();
+ method @Deprecated public android.view.Surface getSurface();
+ method @Deprecated public long getTimeStamp();
+ method @Deprecated public android.renderscript.Type getType();
+ method @Deprecated public int getUsage();
+ method @Deprecated public void ioReceive();
+ method @Deprecated public void ioSend();
method @Deprecated public void resize(int);
- method public void setAutoPadding(boolean);
- method public void setFromFieldPacker(int, android.renderscript.FieldPacker);
- method public void setFromFieldPacker(int, int, android.renderscript.FieldPacker);
- method public void setFromFieldPacker(int, int, int, int, android.renderscript.FieldPacker);
- method public void setOnBufferAvailableListener(android.renderscript.Allocation.OnBufferAvailableListener);
- method public void setSurface(android.view.Surface);
- method public void syncAll(int);
- field public static final int USAGE_GRAPHICS_CONSTANTS = 8; // 0x8
- field public static final int USAGE_GRAPHICS_RENDER_TARGET = 16; // 0x10
- field public static final int USAGE_GRAPHICS_TEXTURE = 2; // 0x2
- field public static final int USAGE_GRAPHICS_VERTEX = 4; // 0x4
- field public static final int USAGE_IO_INPUT = 32; // 0x20
- field public static final int USAGE_IO_OUTPUT = 64; // 0x40
- field public static final int USAGE_SCRIPT = 1; // 0x1
- field public static final int USAGE_SHARED = 128; // 0x80
- }
-
- public enum Allocation.MipmapControl {
- enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_FULL;
- enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_NONE;
- enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_ON_SYNC_TO_TEXTURE;
- }
-
- public static interface Allocation.OnBufferAvailableListener {
- method public void onBufferAvailable(android.renderscript.Allocation);
- }
-
- public class AllocationAdapter extends android.renderscript.Allocation {
- method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
- method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
- method public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
- method public void resize(int);
- method public void setFace(android.renderscript.Type.CubemapFace);
- method public void setLOD(int);
- method public void setX(int);
- method public void setY(int);
- method public void setZ(int);
- }
-
- public class BaseObj {
- method public void destroy();
- method public String getName();
- method public void setName(String);
+ method @Deprecated public void setAutoPadding(boolean);
+ method @Deprecated public void setFromFieldPacker(int, android.renderscript.FieldPacker);
+ method @Deprecated public void setFromFieldPacker(int, int, android.renderscript.FieldPacker);
+ method @Deprecated public void setFromFieldPacker(int, int, int, int, android.renderscript.FieldPacker);
+ method @Deprecated public void setOnBufferAvailableListener(android.renderscript.Allocation.OnBufferAvailableListener);
+ method @Deprecated public void setSurface(android.view.Surface);
+ method @Deprecated public void syncAll(int);
+ field @Deprecated public static final int USAGE_GRAPHICS_CONSTANTS = 8; // 0x8
+ field @Deprecated public static final int USAGE_GRAPHICS_RENDER_TARGET = 16; // 0x10
+ field @Deprecated public static final int USAGE_GRAPHICS_TEXTURE = 2; // 0x2
+ field @Deprecated public static final int USAGE_GRAPHICS_VERTEX = 4; // 0x4
+ field @Deprecated public static final int USAGE_IO_INPUT = 32; // 0x20
+ field @Deprecated public static final int USAGE_IO_OUTPUT = 64; // 0x40
+ field @Deprecated public static final int USAGE_SCRIPT = 1; // 0x1
+ field @Deprecated public static final int USAGE_SHARED = 128; // 0x80
+ }
+
+ @Deprecated public enum Allocation.MipmapControl {
+ enum_constant @Deprecated public static final android.renderscript.Allocation.MipmapControl MIPMAP_FULL;
+ enum_constant @Deprecated public static final android.renderscript.Allocation.MipmapControl MIPMAP_NONE;
+ enum_constant @Deprecated public static final android.renderscript.Allocation.MipmapControl MIPMAP_ON_SYNC_TO_TEXTURE;
+ }
+
+ @Deprecated public static interface Allocation.OnBufferAvailableListener {
+ method @Deprecated public void onBufferAvailable(android.renderscript.Allocation);
+ }
+
+ @Deprecated public class AllocationAdapter extends android.renderscript.Allocation {
+ method @Deprecated public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
+ method @Deprecated public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
+ method @Deprecated public static android.renderscript.AllocationAdapter createTyped(android.renderscript.RenderScript, android.renderscript.Allocation, android.renderscript.Type);
+ method @Deprecated public void resize(int);
+ method @Deprecated public void setFace(android.renderscript.Type.CubemapFace);
+ method @Deprecated public void setLOD(int);
+ method @Deprecated public void setX(int);
+ method @Deprecated public void setY(int);
+ method @Deprecated public void setZ(int);
}
- public class Byte2 {
- ctor public Byte2();
- ctor public Byte2(byte, byte);
- field public byte x;
- field public byte y;
- }
-
- public class Byte3 {
- ctor public Byte3();
- ctor public Byte3(byte, byte, byte);
- field public byte x;
- field public byte y;
- field public byte z;
- }
-
- public class Byte4 {
- ctor public Byte4();
- ctor public Byte4(byte, byte, byte, byte);
- field public byte w;
- field public byte x;
- field public byte y;
- field public byte z;
- }
-
- public class Double2 {
- ctor public Double2();
- ctor public Double2(double, double);
- field public double x;
- field public double y;
- }
-
- public class Double3 {
- ctor public Double3();
- ctor public Double3(double, double, double);
- field public double x;
- field public double y;
- field public double z;
- }
-
- public class Double4 {
- ctor public Double4();
- ctor public Double4(double, double, double, double);
- field public double w;
- field public double x;
- field public double y;
- field public double z;
- }
-
- public class Element extends android.renderscript.BaseObj {
- method public static android.renderscript.Element ALLOCATION(android.renderscript.RenderScript);
- method public static android.renderscript.Element A_8(android.renderscript.RenderScript);
- method public static android.renderscript.Element BOOLEAN(android.renderscript.RenderScript);
- method public static android.renderscript.Element ELEMENT(android.renderscript.RenderScript);
- method public static android.renderscript.Element F16(android.renderscript.RenderScript);
- method public static android.renderscript.Element F16_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element F16_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element F16_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element F32_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element F64_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element FONT(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I16_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I32_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I64_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element I8_4(android.renderscript.RenderScript);
+ @Deprecated public class BaseObj {
+ method @Deprecated public void destroy();
+ method @Deprecated public String getName();
+ method @Deprecated public void setName(String);
+ }
+
+ @Deprecated public class Byte2 {
+ ctor @Deprecated public Byte2();
+ ctor @Deprecated public Byte2(byte, byte);
+ field @Deprecated public byte x;
+ field @Deprecated public byte y;
+ }
+
+ @Deprecated public class Byte3 {
+ ctor @Deprecated public Byte3();
+ ctor @Deprecated public Byte3(byte, byte, byte);
+ field @Deprecated public byte x;
+ field @Deprecated public byte y;
+ field @Deprecated public byte z;
+ }
+
+ @Deprecated public class Byte4 {
+ ctor @Deprecated public Byte4();
+ ctor @Deprecated public Byte4(byte, byte, byte, byte);
+ field @Deprecated public byte w;
+ field @Deprecated public byte x;
+ field @Deprecated public byte y;
+ field @Deprecated public byte z;
+ }
+
+ @Deprecated public class Double2 {
+ ctor @Deprecated public Double2();
+ ctor @Deprecated public Double2(double, double);
+ field @Deprecated public double x;
+ field @Deprecated public double y;
+ }
+
+ @Deprecated public class Double3 {
+ ctor @Deprecated public Double3();
+ ctor @Deprecated public Double3(double, double, double);
+ field @Deprecated public double x;
+ field @Deprecated public double y;
+ field @Deprecated public double z;
+ }
+
+ @Deprecated public class Double4 {
+ ctor @Deprecated public Double4();
+ ctor @Deprecated public Double4(double, double, double, double);
+ field @Deprecated public double w;
+ field @Deprecated public double x;
+ field @Deprecated public double y;
+ field @Deprecated public double z;
+ }
+
+ @Deprecated public class Element extends android.renderscript.BaseObj {
+ method @Deprecated public static android.renderscript.Element ALLOCATION(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element A_8(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element BOOLEAN(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element ELEMENT(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F16(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F16_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F16_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F16_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F32(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F32_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F32_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F32_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F64(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F64_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F64_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element F64_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element FONT(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I16(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I16_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I16_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I16_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I32(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I32_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I32_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I32_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I64(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I64_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I64_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I64_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I8(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I8_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I8_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element I8_4(android.renderscript.RenderScript);
method @Deprecated public static android.renderscript.Element MATRIX4X4(android.renderscript.RenderScript);
- method public static android.renderscript.Element MATRIX_2X2(android.renderscript.RenderScript);
- method public static android.renderscript.Element MATRIX_3X3(android.renderscript.RenderScript);
- method public static android.renderscript.Element MATRIX_4X4(android.renderscript.RenderScript);
- method public static android.renderscript.Element MESH(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_FRAGMENT(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_RASTER(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_STORE(android.renderscript.RenderScript);
- method public static android.renderscript.Element PROGRAM_VERTEX(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGBA_4444(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGBA_5551(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGBA_8888(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGB_565(android.renderscript.RenderScript);
- method public static android.renderscript.Element RGB_888(android.renderscript.RenderScript);
- method public static android.renderscript.Element SAMPLER(android.renderscript.RenderScript);
- method public static android.renderscript.Element SCRIPT(android.renderscript.RenderScript);
- method public static android.renderscript.Element TYPE(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U16_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U32_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U64_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8_2(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8_3(android.renderscript.RenderScript);
- method public static android.renderscript.Element U8_4(android.renderscript.RenderScript);
- method public static android.renderscript.Element YUV(android.renderscript.RenderScript);
- method public static android.renderscript.Element createPixel(android.renderscript.RenderScript, android.renderscript.Element.DataType, android.renderscript.Element.DataKind);
- method public static android.renderscript.Element createVector(android.renderscript.RenderScript, android.renderscript.Element.DataType, int);
- method public int getBytesSize();
- method public android.renderscript.Element.DataKind getDataKind();
- method public android.renderscript.Element.DataType getDataType();
- method public android.renderscript.Element getSubElement(int);
- method public int getSubElementArraySize(int);
- method public int getSubElementCount();
- method public String getSubElementName(int);
- method public int getSubElementOffsetBytes(int);
- method public int getVectorSize();
- method public boolean isCompatible(android.renderscript.Element);
- method public boolean isComplex();
- }
-
- public static class Element.Builder {
- ctor public Element.Builder(android.renderscript.RenderScript);
- method public android.renderscript.Element.Builder add(android.renderscript.Element, String, int);
- method public android.renderscript.Element.Builder add(android.renderscript.Element, String);
- method public android.renderscript.Element create();
- }
-
- public enum Element.DataKind {
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_A;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_DEPTH;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_L;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_LA;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_RGB;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_RGBA;
- enum_constant public static final android.renderscript.Element.DataKind PIXEL_YUV;
- enum_constant public static final android.renderscript.Element.DataKind USER;
- }
-
- public enum Element.DataType {
- enum_constant public static final android.renderscript.Element.DataType BOOLEAN;
- enum_constant public static final android.renderscript.Element.DataType FLOAT_16;
- enum_constant public static final android.renderscript.Element.DataType FLOAT_32;
- enum_constant public static final android.renderscript.Element.DataType FLOAT_64;
- enum_constant public static final android.renderscript.Element.DataType MATRIX_2X2;
- enum_constant public static final android.renderscript.Element.DataType MATRIX_3X3;
- enum_constant public static final android.renderscript.Element.DataType MATRIX_4X4;
- enum_constant public static final android.renderscript.Element.DataType NONE;
- enum_constant public static final android.renderscript.Element.DataType RS_ALLOCATION;
- enum_constant public static final android.renderscript.Element.DataType RS_ELEMENT;
- enum_constant public static final android.renderscript.Element.DataType RS_FONT;
- enum_constant public static final android.renderscript.Element.DataType RS_MESH;
- enum_constant public static final android.renderscript.Element.DataType RS_PROGRAM_FRAGMENT;
- enum_constant public static final android.renderscript.Element.DataType RS_PROGRAM_RASTER;
- enum_constant public static final android.renderscript.Element.DataType RS_PROGRAM_STORE;
- enum_constant public static final android.renderscript.Element.DataType RS_PROGRAM_VERTEX;
- enum_constant public static final android.renderscript.Element.DataType RS_SAMPLER;
- enum_constant public static final android.renderscript.Element.DataType RS_SCRIPT;
- enum_constant public static final android.renderscript.Element.DataType RS_TYPE;
- enum_constant public static final android.renderscript.Element.DataType SIGNED_16;
- enum_constant public static final android.renderscript.Element.DataType SIGNED_32;
- enum_constant public static final android.renderscript.Element.DataType SIGNED_64;
- enum_constant public static final android.renderscript.Element.DataType SIGNED_8;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_16;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_32;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_4_4_4_4;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_5_5_5_1;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_5_6_5;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_64;
- enum_constant public static final android.renderscript.Element.DataType UNSIGNED_8;
- }
-
- public class FieldPacker {
- ctor public FieldPacker(int);
- ctor public FieldPacker(byte[]);
- method public void addBoolean(boolean);
- method public void addF32(float);
- method public void addF32(android.renderscript.Float2);
- method public void addF32(android.renderscript.Float3);
- method public void addF32(android.renderscript.Float4);
- method public void addF64(double);
- method public void addF64(android.renderscript.Double2);
- method public void addF64(android.renderscript.Double3);
- method public void addF64(android.renderscript.Double4);
- method public void addI16(short);
- method public void addI16(android.renderscript.Short2);
- method public void addI16(android.renderscript.Short3);
- method public void addI16(android.renderscript.Short4);
- method public void addI32(int);
- method public void addI32(android.renderscript.Int2);
- method public void addI32(android.renderscript.Int3);
- method public void addI32(android.renderscript.Int4);
- method public void addI64(long);
- method public void addI64(android.renderscript.Long2);
- method public void addI64(android.renderscript.Long3);
- method public void addI64(android.renderscript.Long4);
- method public void addI8(byte);
- method public void addI8(android.renderscript.Byte2);
- method public void addI8(android.renderscript.Byte3);
- method public void addI8(android.renderscript.Byte4);
- method public void addMatrix(android.renderscript.Matrix4f);
- method public void addMatrix(android.renderscript.Matrix3f);
- method public void addMatrix(android.renderscript.Matrix2f);
- method public void addObj(android.renderscript.BaseObj);
- method public void addU16(int);
- method public void addU16(android.renderscript.Int2);
- method public void addU16(android.renderscript.Int3);
- method public void addU16(android.renderscript.Int4);
- method public void addU32(long);
- method public void addU32(android.renderscript.Long2);
- method public void addU32(android.renderscript.Long3);
- method public void addU32(android.renderscript.Long4);
- method public void addU64(long);
- method public void addU64(android.renderscript.Long2);
- method public void addU64(android.renderscript.Long3);
- method public void addU64(android.renderscript.Long4);
- method public void addU8(short);
- method public void addU8(android.renderscript.Short2);
- method public void addU8(android.renderscript.Short3);
- method public void addU8(android.renderscript.Short4);
- method public void align(int);
- method public final byte[] getData();
- method public void reset();
- method public void reset(int);
- method public void skip(int);
- method public boolean subBoolean();
- method public android.renderscript.Byte2 subByte2();
- method public android.renderscript.Byte3 subByte3();
- method public android.renderscript.Byte4 subByte4();
- method public android.renderscript.Double2 subDouble2();
- method public android.renderscript.Double3 subDouble3();
- method public android.renderscript.Double4 subDouble4();
- method public float subF32();
- method public double subF64();
- method public android.renderscript.Float2 subFloat2();
- method public android.renderscript.Float3 subFloat3();
- method public android.renderscript.Float4 subFloat4();
- method public short subI16();
- method public int subI32();
- method public long subI64();
- method public byte subI8();
- method public android.renderscript.Int2 subInt2();
- method public android.renderscript.Int3 subInt3();
- method public android.renderscript.Int4 subInt4();
- method public android.renderscript.Long2 subLong2();
- method public android.renderscript.Long3 subLong3();
- method public android.renderscript.Long4 subLong4();
- method public android.renderscript.Matrix2f subMatrix2f();
- method public android.renderscript.Matrix3f subMatrix3f();
- method public android.renderscript.Matrix4f subMatrix4f();
- method public android.renderscript.Short2 subShort2();
- method public android.renderscript.Short3 subShort3();
- method public android.renderscript.Short4 subShort4();
- method public void subalign(int);
- }
-
- public class Float2 {
- ctor public Float2();
- ctor public Float2(float, float);
- field public float x;
- field public float y;
- }
-
- public class Float3 {
- ctor public Float3();
- ctor public Float3(float, float, float);
- field public float x;
- field public float y;
- field public float z;
- }
-
- public class Float4 {
- ctor public Float4();
- ctor public Float4(float, float, float, float);
- field public float w;
- field public float x;
- field public float y;
- field public float z;
- }
-
- public class Int2 {
- ctor public Int2();
- ctor public Int2(int, int);
- field public int x;
- field public int y;
- }
-
- public class Int3 {
- ctor public Int3();
- ctor public Int3(int, int, int);
- field public int x;
- field public int y;
- field public int z;
- }
-
- public class Int4 {
- ctor public Int4();
- ctor public Int4(int, int, int, int);
- field public int w;
- field public int x;
- field public int y;
- field public int z;
- }
-
- public class Long2 {
- ctor public Long2();
- ctor public Long2(long, long);
- field public long x;
- field public long y;
- }
-
- public class Long3 {
- ctor public Long3();
- ctor public Long3(long, long, long);
- field public long x;
- field public long y;
- field public long z;
- }
-
- public class Long4 {
- ctor public Long4();
- ctor public Long4(long, long, long, long);
- field public long w;
- field public long x;
- field public long y;
- field public long z;
- }
-
- public class Matrix2f {
- ctor public Matrix2f();
- ctor public Matrix2f(float[]);
- method public float get(int, int);
- method public float[] getArray();
- method public void load(android.renderscript.Matrix2f);
- method public void loadIdentity();
- method public void loadMultiply(android.renderscript.Matrix2f, android.renderscript.Matrix2f);
- method public void loadRotate(float);
- method public void loadScale(float, float);
- method public void multiply(android.renderscript.Matrix2f);
- method public void rotate(float);
- method public void scale(float, float);
- method public void set(int, int, float);
- method public void transpose();
- }
-
- public class Matrix3f {
- ctor public Matrix3f();
- ctor public Matrix3f(float[]);
- method public float get(int, int);
- method public float[] getArray();
- method public void load(android.renderscript.Matrix3f);
- method public void loadIdentity();
- method public void loadMultiply(android.renderscript.Matrix3f, android.renderscript.Matrix3f);
- method public void loadRotate(float, float, float, float);
- method public void loadRotate(float);
- method public void loadScale(float, float);
- method public void loadScale(float, float, float);
- method public void loadTranslate(float, float);
- method public void multiply(android.renderscript.Matrix3f);
- method public void rotate(float, float, float, float);
- method public void rotate(float);
- method public void scale(float, float);
- method public void scale(float, float, float);
- method public void set(int, int, float);
- method public void translate(float, float);
- method public void transpose();
- }
-
- public class Matrix4f {
- ctor public Matrix4f();
- ctor public Matrix4f(float[]);
- method public float get(int, int);
- method public float[] getArray();
- method public boolean inverse();
- method public boolean inverseTranspose();
- method public void load(android.renderscript.Matrix4f);
- method public void loadFrustum(float, float, float, float, float, float);
- method public void loadIdentity();
- method public void loadMultiply(android.renderscript.Matrix4f, android.renderscript.Matrix4f);
- method public void loadOrtho(float, float, float, float, float, float);
- method public void loadOrthoWindow(int, int);
- method public void loadPerspective(float, float, float, float);
- method public void loadProjectionNormalized(int, int);
- method public void loadRotate(float, float, float, float);
- method public void loadScale(float, float, float);
- method public void loadTranslate(float, float, float);
- method public void multiply(android.renderscript.Matrix4f);
- method public void rotate(float, float, float, float);
- method public void scale(float, float, float);
- method public void set(int, int, float);
- method public void translate(float, float, float);
- method public void transpose();
- }
-
- public class RSDriverException extends android.renderscript.RSRuntimeException {
- ctor public RSDriverException(String);
- }
-
- public class RSIllegalArgumentException extends android.renderscript.RSRuntimeException {
- ctor public RSIllegalArgumentException(String);
- }
-
- public class RSInvalidStateException extends android.renderscript.RSRuntimeException {
- ctor public RSInvalidStateException(String);
- }
-
- public class RSRuntimeException extends java.lang.RuntimeException {
- ctor public RSRuntimeException(String);
- }
-
- public class RenderScript {
- method public void contextDump();
- method public static android.renderscript.RenderScript create(android.content.Context);
- method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType);
- method public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType, int);
- method public static android.renderscript.RenderScript createMultiContext(android.content.Context, android.renderscript.RenderScript.ContextType, int, int);
- method public void destroy();
- method public void finish();
- method public final android.content.Context getApplicationContext();
- method public android.renderscript.RenderScript.RSErrorHandler getErrorHandler();
- method public android.renderscript.RenderScript.RSMessageHandler getMessageHandler();
- method public static long getMinorVersion();
- method public static void releaseAllContexts();
- method public void sendMessage(int, int[]);
- method public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
- method public void setMessageHandler(android.renderscript.RenderScript.RSMessageHandler);
- method public void setPriority(android.renderscript.RenderScript.Priority);
- field public static final int CREATE_FLAG_LOW_LATENCY = 2; // 0x2
- field public static final int CREATE_FLAG_LOW_POWER = 4; // 0x4
- field public static final int CREATE_FLAG_NONE = 0; // 0x0
- }
-
- public enum RenderScript.ContextType {
- enum_constant public static final android.renderscript.RenderScript.ContextType DEBUG;
- enum_constant public static final android.renderscript.RenderScript.ContextType NORMAL;
- enum_constant public static final android.renderscript.RenderScript.ContextType PROFILE;
- }
-
- public enum RenderScript.Priority {
- enum_constant public static final android.renderscript.RenderScript.Priority LOW;
- enum_constant public static final android.renderscript.RenderScript.Priority NORMAL;
- }
-
- public static class RenderScript.RSErrorHandler implements java.lang.Runnable {
- ctor public RenderScript.RSErrorHandler();
- method public void run();
- field protected String mErrorMessage;
- field protected int mErrorNum;
- }
-
- public static class RenderScript.RSMessageHandler implements java.lang.Runnable {
- ctor public RenderScript.RSMessageHandler();
- method public void run();
- field protected int[] mData;
- field protected int mID;
- field protected int mLength;
- }
-
- public class Sampler extends android.renderscript.BaseObj {
- method public static android.renderscript.Sampler CLAMP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler CLAMP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler CLAMP_NEAREST(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler MIRRORED_REPEAT_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler MIRRORED_REPEAT_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler MIRRORED_REPEAT_NEAREST(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler WRAP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler WRAP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
- method public static android.renderscript.Sampler WRAP_NEAREST(android.renderscript.RenderScript);
- method public float getAnisotropy();
- method public android.renderscript.Sampler.Value getMagnification();
- method public android.renderscript.Sampler.Value getMinification();
- method public android.renderscript.Sampler.Value getWrapS();
- method public android.renderscript.Sampler.Value getWrapT();
- }
-
- public static class Sampler.Builder {
- ctor public Sampler.Builder(android.renderscript.RenderScript);
- method public android.renderscript.Sampler create();
- method public void setAnisotropy(float);
- method public void setMagnification(android.renderscript.Sampler.Value);
- method public void setMinification(android.renderscript.Sampler.Value);
- method public void setWrapS(android.renderscript.Sampler.Value);
- method public void setWrapT(android.renderscript.Sampler.Value);
- }
-
- public enum Sampler.Value {
- enum_constant public static final android.renderscript.Sampler.Value CLAMP;
- enum_constant public static final android.renderscript.Sampler.Value LINEAR;
- enum_constant public static final android.renderscript.Sampler.Value LINEAR_MIP_LINEAR;
- enum_constant public static final android.renderscript.Sampler.Value LINEAR_MIP_NEAREST;
- enum_constant public static final android.renderscript.Sampler.Value MIRRORED_REPEAT;
- enum_constant public static final android.renderscript.Sampler.Value NEAREST;
- enum_constant public static final android.renderscript.Sampler.Value WRAP;
- }
-
- public class Script extends android.renderscript.BaseObj {
- method public void bindAllocation(android.renderscript.Allocation, int);
- method protected android.renderscript.Script.FieldID createFieldID(int, android.renderscript.Element);
- method protected android.renderscript.Script.InvokeID createInvokeID(int);
- method protected android.renderscript.Script.KernelID createKernelID(int, int, android.renderscript.Element, android.renderscript.Element);
- method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
- method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
- method protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker);
- method protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
- method public boolean getVarB(int);
- method public double getVarD(int);
- method public float getVarF(int);
- method public int getVarI(int);
- method public long getVarJ(int);
- method public void getVarV(int, android.renderscript.FieldPacker);
- method protected void invoke(int);
- method protected void invoke(int, android.renderscript.FieldPacker);
- method protected void reduce(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void setTimeZone(String);
- method public void setVar(int, float);
- method public void setVar(int, double);
- method public void setVar(int, int);
- method public void setVar(int, long);
- method public void setVar(int, boolean);
- method public void setVar(int, android.renderscript.BaseObj);
- method public void setVar(int, android.renderscript.FieldPacker);
- method public void setVar(int, android.renderscript.FieldPacker, android.renderscript.Element, int[]);
- }
-
- public static class Script.Builder {
- }
-
- public static class Script.FieldBase {
- ctor protected Script.FieldBase();
- method public android.renderscript.Allocation getAllocation();
- method public android.renderscript.Element getElement();
- method public android.renderscript.Type getType();
- method protected void init(android.renderscript.RenderScript, int);
- method protected void init(android.renderscript.RenderScript, int, int);
- method public void updateAllocation();
- field protected android.renderscript.Allocation mAllocation;
- field protected android.renderscript.Element mElement;
- }
-
- public static final class Script.FieldID extends android.renderscript.BaseObj {
- }
-
- public static final class Script.InvokeID extends android.renderscript.BaseObj {
- }
-
- public static final class Script.KernelID extends android.renderscript.BaseObj {
+ method @Deprecated public static android.renderscript.Element MATRIX_2X2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element MATRIX_3X3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element MATRIX_4X4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element MESH(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element PROGRAM_FRAGMENT(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element PROGRAM_RASTER(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element PROGRAM_STORE(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element PROGRAM_VERTEX(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element RGBA_4444(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element RGBA_5551(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element RGBA_8888(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element RGB_565(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element RGB_888(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element SAMPLER(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element SCRIPT(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element TYPE(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U16(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U16_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U16_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U16_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U32(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U32_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U32_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U32_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U64(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U64_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U64_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U64_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U8(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U8_2(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U8_3(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element U8_4(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element YUV(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Element createPixel(android.renderscript.RenderScript, android.renderscript.Element.DataType, android.renderscript.Element.DataKind);
+ method @Deprecated public static android.renderscript.Element createVector(android.renderscript.RenderScript, android.renderscript.Element.DataType, int);
+ method @Deprecated public int getBytesSize();
+ method @Deprecated public android.renderscript.Element.DataKind getDataKind();
+ method @Deprecated public android.renderscript.Element.DataType getDataType();
+ method @Deprecated public android.renderscript.Element getSubElement(int);
+ method @Deprecated public int getSubElementArraySize(int);
+ method @Deprecated public int getSubElementCount();
+ method @Deprecated public String getSubElementName(int);
+ method @Deprecated public int getSubElementOffsetBytes(int);
+ method @Deprecated public int getVectorSize();
+ method @Deprecated public boolean isCompatible(android.renderscript.Element);
+ method @Deprecated public boolean isComplex();
+ }
+
+ @Deprecated public static class Element.Builder {
+ ctor @Deprecated public Element.Builder(android.renderscript.RenderScript);
+ method @Deprecated public android.renderscript.Element.Builder add(android.renderscript.Element, String, int);
+ method @Deprecated public android.renderscript.Element.Builder add(android.renderscript.Element, String);
+ method @Deprecated public android.renderscript.Element create();
+ }
+
+ @Deprecated public enum Element.DataKind {
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_A;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_DEPTH;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_L;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_LA;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_RGB;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_RGBA;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind PIXEL_YUV;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataKind USER;
+ }
+
+ @Deprecated public enum Element.DataType {
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType BOOLEAN;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType FLOAT_16;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType FLOAT_32;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType FLOAT_64;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType MATRIX_2X2;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType MATRIX_3X3;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType MATRIX_4X4;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType NONE;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_ALLOCATION;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_ELEMENT;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_FONT;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_MESH;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_PROGRAM_FRAGMENT;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_PROGRAM_RASTER;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_PROGRAM_STORE;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_PROGRAM_VERTEX;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_SAMPLER;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_SCRIPT;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType RS_TYPE;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType SIGNED_16;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType SIGNED_32;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType SIGNED_64;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType SIGNED_8;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_16;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_32;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_4_4_4_4;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_5_5_5_1;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_5_6_5;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_64;
+ enum_constant @Deprecated public static final android.renderscript.Element.DataType UNSIGNED_8;
+ }
+
+ @Deprecated public class FieldPacker {
+ ctor @Deprecated public FieldPacker(int);
+ ctor @Deprecated public FieldPacker(byte[]);
+ method @Deprecated public void addBoolean(boolean);
+ method @Deprecated public void addF32(float);
+ method @Deprecated public void addF32(android.renderscript.Float2);
+ method @Deprecated public void addF32(android.renderscript.Float3);
+ method @Deprecated public void addF32(android.renderscript.Float4);
+ method @Deprecated public void addF64(double);
+ method @Deprecated public void addF64(android.renderscript.Double2);
+ method @Deprecated public void addF64(android.renderscript.Double3);
+ method @Deprecated public void addF64(android.renderscript.Double4);
+ method @Deprecated public void addI16(short);
+ method @Deprecated public void addI16(android.renderscript.Short2);
+ method @Deprecated public void addI16(android.renderscript.Short3);
+ method @Deprecated public void addI16(android.renderscript.Short4);
+ method @Deprecated public void addI32(int);
+ method @Deprecated public void addI32(android.renderscript.Int2);
+ method @Deprecated public void addI32(android.renderscript.Int3);
+ method @Deprecated public void addI32(android.renderscript.Int4);
+ method @Deprecated public void addI64(long);
+ method @Deprecated public void addI64(android.renderscript.Long2);
+ method @Deprecated public void addI64(android.renderscript.Long3);
+ method @Deprecated public void addI64(android.renderscript.Long4);
+ method @Deprecated public void addI8(byte);
+ method @Deprecated public void addI8(android.renderscript.Byte2);
+ method @Deprecated public void addI8(android.renderscript.Byte3);
+ method @Deprecated public void addI8(android.renderscript.Byte4);
+ method @Deprecated public void addMatrix(android.renderscript.Matrix4f);
+ method @Deprecated public void addMatrix(android.renderscript.Matrix3f);
+ method @Deprecated public void addMatrix(android.renderscript.Matrix2f);
+ method @Deprecated public void addObj(android.renderscript.BaseObj);
+ method @Deprecated public void addU16(int);
+ method @Deprecated public void addU16(android.renderscript.Int2);
+ method @Deprecated public void addU16(android.renderscript.Int3);
+ method @Deprecated public void addU16(android.renderscript.Int4);
+ method @Deprecated public void addU32(long);
+ method @Deprecated public void addU32(android.renderscript.Long2);
+ method @Deprecated public void addU32(android.renderscript.Long3);
+ method @Deprecated public void addU32(android.renderscript.Long4);
+ method @Deprecated public void addU64(long);
+ method @Deprecated public void addU64(android.renderscript.Long2);
+ method @Deprecated public void addU64(android.renderscript.Long3);
+ method @Deprecated public void addU64(android.renderscript.Long4);
+ method @Deprecated public void addU8(short);
+ method @Deprecated public void addU8(android.renderscript.Short2);
+ method @Deprecated public void addU8(android.renderscript.Short3);
+ method @Deprecated public void addU8(android.renderscript.Short4);
+ method @Deprecated public void align(int);
+ method @Deprecated public final byte[] getData();
+ method @Deprecated public void reset();
+ method @Deprecated public void reset(int);
+ method @Deprecated public void skip(int);
+ method @Deprecated public boolean subBoolean();
+ method @Deprecated public android.renderscript.Byte2 subByte2();
+ method @Deprecated public android.renderscript.Byte3 subByte3();
+ method @Deprecated public android.renderscript.Byte4 subByte4();
+ method @Deprecated public android.renderscript.Double2 subDouble2();
+ method @Deprecated public android.renderscript.Double3 subDouble3();
+ method @Deprecated public android.renderscript.Double4 subDouble4();
+ method @Deprecated public float subF32();
+ method @Deprecated public double subF64();
+ method @Deprecated public android.renderscript.Float2 subFloat2();
+ method @Deprecated public android.renderscript.Float3 subFloat3();
+ method @Deprecated public android.renderscript.Float4 subFloat4();
+ method @Deprecated public short subI16();
+ method @Deprecated public int subI32();
+ method @Deprecated public long subI64();
+ method @Deprecated public byte subI8();
+ method @Deprecated public android.renderscript.Int2 subInt2();
+ method @Deprecated public android.renderscript.Int3 subInt3();
+ method @Deprecated public android.renderscript.Int4 subInt4();
+ method @Deprecated public android.renderscript.Long2 subLong2();
+ method @Deprecated public android.renderscript.Long3 subLong3();
+ method @Deprecated public android.renderscript.Long4 subLong4();
+ method @Deprecated public android.renderscript.Matrix2f subMatrix2f();
+ method @Deprecated public android.renderscript.Matrix3f subMatrix3f();
+ method @Deprecated public android.renderscript.Matrix4f subMatrix4f();
+ method @Deprecated public android.renderscript.Short2 subShort2();
+ method @Deprecated public android.renderscript.Short3 subShort3();
+ method @Deprecated public android.renderscript.Short4 subShort4();
+ method @Deprecated public void subalign(int);
+ }
+
+ @Deprecated public class Float2 {
+ ctor @Deprecated public Float2();
+ ctor @Deprecated public Float2(float, float);
+ field @Deprecated public float x;
+ field @Deprecated public float y;
+ }
+
+ @Deprecated public class Float3 {
+ ctor @Deprecated public Float3();
+ ctor @Deprecated public Float3(float, float, float);
+ field @Deprecated public float x;
+ field @Deprecated public float y;
+ field @Deprecated public float z;
+ }
+
+ @Deprecated public class Float4 {
+ ctor @Deprecated public Float4();
+ ctor @Deprecated public Float4(float, float, float, float);
+ field @Deprecated public float w;
+ field @Deprecated public float x;
+ field @Deprecated public float y;
+ field @Deprecated public float z;
+ }
+
+ @Deprecated public class Int2 {
+ ctor @Deprecated public Int2();
+ ctor @Deprecated public Int2(int, int);
+ field @Deprecated public int x;
+ field @Deprecated public int y;
}
- public static final class Script.LaunchOptions {
- ctor public Script.LaunchOptions();
- method public int getXEnd();
- method public int getXStart();
- method public int getYEnd();
- method public int getYStart();
- method public int getZEnd();
- method public int getZStart();
- method public android.renderscript.Script.LaunchOptions setX(int, int);
- method public android.renderscript.Script.LaunchOptions setY(int, int);
- method public android.renderscript.Script.LaunchOptions setZ(int, int);
+ @Deprecated public class Int3 {
+ ctor @Deprecated public Int3();
+ ctor @Deprecated public Int3(int, int, int);
+ field @Deprecated public int x;
+ field @Deprecated public int y;
+ field @Deprecated public int z;
}
- public class ScriptC extends android.renderscript.Script {
- ctor protected ScriptC(int, android.renderscript.RenderScript);
- ctor protected ScriptC(long, android.renderscript.RenderScript);
- ctor protected ScriptC(android.renderscript.RenderScript, android.content.res.Resources, int);
- ctor protected ScriptC(android.renderscript.RenderScript, String, byte[], byte[]);
+ @Deprecated public class Int4 {
+ ctor @Deprecated public Int4();
+ ctor @Deprecated public Int4(int, int, int, int);
+ field @Deprecated public int w;
+ field @Deprecated public int x;
+ field @Deprecated public int y;
+ field @Deprecated public int z;
+ }
+
+ @Deprecated public class Long2 {
+ ctor @Deprecated public Long2();
+ ctor @Deprecated public Long2(long, long);
+ field @Deprecated public long x;
+ field @Deprecated public long y;
+ }
+
+ @Deprecated public class Long3 {
+ ctor @Deprecated public Long3();
+ ctor @Deprecated public Long3(long, long, long);
+ field @Deprecated public long x;
+ field @Deprecated public long y;
+ field @Deprecated public long z;
+ }
+
+ @Deprecated public class Long4 {
+ ctor @Deprecated public Long4();
+ ctor @Deprecated public Long4(long, long, long, long);
+ field @Deprecated public long w;
+ field @Deprecated public long x;
+ field @Deprecated public long y;
+ field @Deprecated public long z;
+ }
+
+ @Deprecated public class Matrix2f {
+ ctor @Deprecated public Matrix2f();
+ ctor @Deprecated public Matrix2f(float[]);
+ method @Deprecated public float get(int, int);
+ method @Deprecated public float[] getArray();
+ method @Deprecated public void load(android.renderscript.Matrix2f);
+ method @Deprecated public void loadIdentity();
+ method @Deprecated public void loadMultiply(android.renderscript.Matrix2f, android.renderscript.Matrix2f);
+ method @Deprecated public void loadRotate(float);
+ method @Deprecated public void loadScale(float, float);
+ method @Deprecated public void multiply(android.renderscript.Matrix2f);
+ method @Deprecated public void rotate(float);
+ method @Deprecated public void scale(float, float);
+ method @Deprecated public void set(int, int, float);
+ method @Deprecated public void transpose();
+ }
+
+ @Deprecated public class Matrix3f {
+ ctor @Deprecated public Matrix3f();
+ ctor @Deprecated public Matrix3f(float[]);
+ method @Deprecated public float get(int, int);
+ method @Deprecated public float[] getArray();
+ method @Deprecated public void load(android.renderscript.Matrix3f);
+ method @Deprecated public void loadIdentity();
+ method @Deprecated public void loadMultiply(android.renderscript.Matrix3f, android.renderscript.Matrix3f);
+ method @Deprecated public void loadRotate(float, float, float, float);
+ method @Deprecated public void loadRotate(float);
+ method @Deprecated public void loadScale(float, float);
+ method @Deprecated public void loadScale(float, float, float);
+ method @Deprecated public void loadTranslate(float, float);
+ method @Deprecated public void multiply(android.renderscript.Matrix3f);
+ method @Deprecated public void rotate(float, float, float, float);
+ method @Deprecated public void rotate(float);
+ method @Deprecated public void scale(float, float);
+ method @Deprecated public void scale(float, float, float);
+ method @Deprecated public void set(int, int, float);
+ method @Deprecated public void translate(float, float);
+ method @Deprecated public void transpose();
+ }
+
+ @Deprecated public class Matrix4f {
+ ctor @Deprecated public Matrix4f();
+ ctor @Deprecated public Matrix4f(float[]);
+ method @Deprecated public float get(int, int);
+ method @Deprecated public float[] getArray();
+ method @Deprecated public boolean inverse();
+ method @Deprecated public boolean inverseTranspose();
+ method @Deprecated public void load(android.renderscript.Matrix4f);
+ method @Deprecated public void loadFrustum(float, float, float, float, float, float);
+ method @Deprecated public void loadIdentity();
+ method @Deprecated public void loadMultiply(android.renderscript.Matrix4f, android.renderscript.Matrix4f);
+ method @Deprecated public void loadOrtho(float, float, float, float, float, float);
+ method @Deprecated public void loadOrthoWindow(int, int);
+ method @Deprecated public void loadPerspective(float, float, float, float);
+ method @Deprecated public void loadProjectionNormalized(int, int);
+ method @Deprecated public void loadRotate(float, float, float, float);
+ method @Deprecated public void loadScale(float, float, float);
+ method @Deprecated public void loadTranslate(float, float, float);
+ method @Deprecated public void multiply(android.renderscript.Matrix4f);
+ method @Deprecated public void rotate(float, float, float, float);
+ method @Deprecated public void scale(float, float, float);
+ method @Deprecated public void set(int, int, float);
+ method @Deprecated public void translate(float, float, float);
+ method @Deprecated public void transpose();
+ }
+
+ @Deprecated public class RSDriverException extends android.renderscript.RSRuntimeException {
+ ctor @Deprecated public RSDriverException(String);
+ }
+
+ @Deprecated public class RSIllegalArgumentException extends android.renderscript.RSRuntimeException {
+ ctor @Deprecated public RSIllegalArgumentException(String);
+ }
+
+ @Deprecated public class RSInvalidStateException extends android.renderscript.RSRuntimeException {
+ ctor @Deprecated public RSInvalidStateException(String);
+ }
+
+ @Deprecated public class RSRuntimeException extends java.lang.RuntimeException {
+ ctor @Deprecated public RSRuntimeException(String);
+ }
+
+ @Deprecated public class RenderScript {
+ method @Deprecated public void contextDump();
+ method @Deprecated public static android.renderscript.RenderScript create(android.content.Context);
+ method @Deprecated public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType);
+ method @Deprecated public static android.renderscript.RenderScript create(android.content.Context, android.renderscript.RenderScript.ContextType, int);
+ method @Deprecated public static android.renderscript.RenderScript createMultiContext(android.content.Context, android.renderscript.RenderScript.ContextType, int, int);
+ method @Deprecated public void destroy();
+ method @Deprecated public void finish();
+ method @Deprecated public final android.content.Context getApplicationContext();
+ method @Deprecated public android.renderscript.RenderScript.RSErrorHandler getErrorHandler();
+ method @Deprecated public android.renderscript.RenderScript.RSMessageHandler getMessageHandler();
+ method @Deprecated public static long getMinorVersion();
+ method @Deprecated public static void releaseAllContexts();
+ method @Deprecated public void sendMessage(int, int[]);
+ method @Deprecated public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
+ method @Deprecated public void setMessageHandler(android.renderscript.RenderScript.RSMessageHandler);
+ method @Deprecated public void setPriority(android.renderscript.RenderScript.Priority);
+ field @Deprecated public static final int CREATE_FLAG_LOW_LATENCY = 2; // 0x2
+ field @Deprecated public static final int CREATE_FLAG_LOW_POWER = 4; // 0x4
+ field @Deprecated public static final int CREATE_FLAG_NONE = 0; // 0x0
+ }
+
+ @Deprecated public enum RenderScript.ContextType {
+ enum_constant @Deprecated public static final android.renderscript.RenderScript.ContextType DEBUG;
+ enum_constant @Deprecated public static final android.renderscript.RenderScript.ContextType NORMAL;
+ enum_constant @Deprecated public static final android.renderscript.RenderScript.ContextType PROFILE;
+ }
+
+ @Deprecated public enum RenderScript.Priority {
+ enum_constant @Deprecated public static final android.renderscript.RenderScript.Priority LOW;
+ enum_constant @Deprecated public static final android.renderscript.RenderScript.Priority NORMAL;
+ }
+
+ @Deprecated public static class RenderScript.RSErrorHandler implements java.lang.Runnable {
+ ctor @Deprecated public RenderScript.RSErrorHandler();
+ method @Deprecated public void run();
+ field @Deprecated protected String mErrorMessage;
+ field @Deprecated protected int mErrorNum;
}
- public final class ScriptGroup extends android.renderscript.BaseObj {
- method public Object[] execute(java.lang.Object...);
+ @Deprecated public static class RenderScript.RSMessageHandler implements java.lang.Runnable {
+ ctor @Deprecated public RenderScript.RSMessageHandler();
+ method @Deprecated public void run();
+ field @Deprecated protected int[] mData;
+ field @Deprecated protected int mID;
+ field @Deprecated protected int mLength;
+ }
+
+ @Deprecated public class Sampler extends android.renderscript.BaseObj {
+ method @Deprecated public static android.renderscript.Sampler CLAMP_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler CLAMP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler CLAMP_NEAREST(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler MIRRORED_REPEAT_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler MIRRORED_REPEAT_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler MIRRORED_REPEAT_NEAREST(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler WRAP_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler WRAP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
+ method @Deprecated public static android.renderscript.Sampler WRAP_NEAREST(android.renderscript.RenderScript);
+ method @Deprecated public float getAnisotropy();
+ method @Deprecated public android.renderscript.Sampler.Value getMagnification();
+ method @Deprecated public android.renderscript.Sampler.Value getMinification();
+ method @Deprecated public android.renderscript.Sampler.Value getWrapS();
+ method @Deprecated public android.renderscript.Sampler.Value getWrapT();
+ }
+
+ @Deprecated public static class Sampler.Builder {
+ ctor @Deprecated public Sampler.Builder(android.renderscript.RenderScript);
+ method @Deprecated public android.renderscript.Sampler create();
+ method @Deprecated public void setAnisotropy(float);
+ method @Deprecated public void setMagnification(android.renderscript.Sampler.Value);
+ method @Deprecated public void setMinification(android.renderscript.Sampler.Value);
+ method @Deprecated public void setWrapS(android.renderscript.Sampler.Value);
+ method @Deprecated public void setWrapT(android.renderscript.Sampler.Value);
+ }
+
+ @Deprecated public enum Sampler.Value {
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value CLAMP;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value LINEAR;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value LINEAR_MIP_LINEAR;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value LINEAR_MIP_NEAREST;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value MIRRORED_REPEAT;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value NEAREST;
+ enum_constant @Deprecated public static final android.renderscript.Sampler.Value WRAP;
+ }
+
+ @Deprecated public class Script extends android.renderscript.BaseObj {
+ method @Deprecated public void bindAllocation(android.renderscript.Allocation, int);
+ method @Deprecated protected android.renderscript.Script.FieldID createFieldID(int, android.renderscript.Element);
+ method @Deprecated protected android.renderscript.Script.InvokeID createInvokeID(int);
+ method @Deprecated protected android.renderscript.Script.KernelID createKernelID(int, int, android.renderscript.Element, android.renderscript.Element);
+ method @Deprecated protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
+ method @Deprecated protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
+ method @Deprecated protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker);
+ method @Deprecated protected void forEach(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public boolean getVarB(int);
+ method @Deprecated public double getVarD(int);
+ method @Deprecated public float getVarF(int);
+ method @Deprecated public int getVarI(int);
+ method @Deprecated public long getVarJ(int);
+ method @Deprecated public void getVarV(int, android.renderscript.FieldPacker);
+ method @Deprecated protected void invoke(int);
+ method @Deprecated protected void invoke(int, android.renderscript.FieldPacker);
+ method @Deprecated protected void reduce(int, android.renderscript.Allocation[], android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void setTimeZone(String);
+ method @Deprecated public void setVar(int, float);
+ method @Deprecated public void setVar(int, double);
+ method @Deprecated public void setVar(int, int);
+ method @Deprecated public void setVar(int, long);
+ method @Deprecated public void setVar(int, boolean);
+ method @Deprecated public void setVar(int, android.renderscript.BaseObj);
+ method @Deprecated public void setVar(int, android.renderscript.FieldPacker);
+ method @Deprecated public void setVar(int, android.renderscript.FieldPacker, android.renderscript.Element, int[]);
+ }
+
+ @Deprecated public static class Script.Builder {
+ }
+
+ @Deprecated public static class Script.FieldBase {
+ ctor @Deprecated protected Script.FieldBase();
+ method @Deprecated public android.renderscript.Allocation getAllocation();
+ method @Deprecated public android.renderscript.Element getElement();
+ method @Deprecated public android.renderscript.Type getType();
+ method @Deprecated protected void init(android.renderscript.RenderScript, int);
+ method @Deprecated protected void init(android.renderscript.RenderScript, int, int);
+ method @Deprecated public void updateAllocation();
+ field @Deprecated protected android.renderscript.Allocation mAllocation;
+ field @Deprecated protected android.renderscript.Element mElement;
+ }
+
+ @Deprecated public static final class Script.FieldID extends android.renderscript.BaseObj {
+ }
+
+ @Deprecated public static final class Script.InvokeID extends android.renderscript.BaseObj {
+ }
+
+ @Deprecated public static final class Script.KernelID extends android.renderscript.BaseObj {
+ }
+
+ @Deprecated public static final class Script.LaunchOptions {
+ ctor @Deprecated public Script.LaunchOptions();
+ method @Deprecated public int getXEnd();
+ method @Deprecated public int getXStart();
+ method @Deprecated public int getYEnd();
+ method @Deprecated public int getYStart();
+ method @Deprecated public int getZEnd();
+ method @Deprecated public int getZStart();
+ method @Deprecated public android.renderscript.Script.LaunchOptions setX(int, int);
+ method @Deprecated public android.renderscript.Script.LaunchOptions setY(int, int);
+ method @Deprecated public android.renderscript.Script.LaunchOptions setZ(int, int);
+ }
+
+ @Deprecated public class ScriptC extends android.renderscript.Script {
+ ctor @Deprecated protected ScriptC(int, android.renderscript.RenderScript);
+ ctor @Deprecated protected ScriptC(long, android.renderscript.RenderScript);
+ ctor @Deprecated protected ScriptC(android.renderscript.RenderScript, android.content.res.Resources, int);
+ ctor @Deprecated protected ScriptC(android.renderscript.RenderScript, String, byte[], byte[]);
+ }
+
+ @Deprecated public final class ScriptGroup extends android.renderscript.BaseObj {
+ method @Deprecated public Object[] execute(java.lang.Object...);
method @Deprecated public void execute();
method @Deprecated public void setInput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
method @Deprecated public void setOutput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
}
- public static final class ScriptGroup.Binding {
- ctor public ScriptGroup.Binding(android.renderscript.Script.FieldID, Object);
+ @Deprecated public static final class ScriptGroup.Binding {
+ ctor @Deprecated public ScriptGroup.Binding(android.renderscript.Script.FieldID, Object);
}
@Deprecated public static final class ScriptGroup.Builder {
@@ -36372,336 +36373,336 @@ package android.renderscript {
method @Deprecated public android.renderscript.ScriptGroup create();
}
- public static final class ScriptGroup.Builder2 {
- ctor public ScriptGroup.Builder2(android.renderscript.RenderScript);
- method public android.renderscript.ScriptGroup.Input addInput();
- method public android.renderscript.ScriptGroup.Closure addInvoke(android.renderscript.Script.InvokeID, java.lang.Object...);
- method public android.renderscript.ScriptGroup.Closure addKernel(android.renderscript.Script.KernelID, android.renderscript.Type, java.lang.Object...);
- method public android.renderscript.ScriptGroup create(String, android.renderscript.ScriptGroup.Future...);
- }
-
- public static final class ScriptGroup.Closure extends android.renderscript.BaseObj {
- method public android.renderscript.ScriptGroup.Future getGlobal(android.renderscript.Script.FieldID);
- method public android.renderscript.ScriptGroup.Future getReturn();
- }
-
- public static final class ScriptGroup.Future {
- }
-
- public static final class ScriptGroup.Input {
- }
-
- public abstract class ScriptIntrinsic extends android.renderscript.Script {
- }
-
- public final class ScriptIntrinsic3DLUT extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsic3DLUT create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setLUT(android.renderscript.Allocation);
- }
-
- public final class ScriptIntrinsicBLAS extends android.renderscript.ScriptIntrinsic {
- method public void BNNM(android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation, int, int);
- method public void CGBMV(int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
- method public void CGEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
- method public void CGEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
- method public void CGERC(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CGERU(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CHBMV(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
- method public void CHEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
- method public void CHEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
- method public void CHER(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CHER2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CHER2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void CHERK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void CHPMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
- method public void CHPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CHPR2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void CSYMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
- method public void CSYR2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
- method public void CSYRK(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
- method public void CTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void CTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void CTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void CTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void CTRMM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void CTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void CTRSM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void CTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DGBMV(int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
- method public void DGEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void DGEMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
- method public void DGER(double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void DSBMV(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
- method public void DSPMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
- method public void DSPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void DSPR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void DSYMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void DSYMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
- method public void DSYR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void DSYR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void DSYR2K(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void DSYRK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void DTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DTRMM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void DTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void DTRSM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void DTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void SGBMV(int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
- method public void SGEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void SGEMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
- method public void SGER(float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void SSBMV(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
- method public void SSPMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
- method public void SSPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void SSPR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void SSYMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void SSYMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
- method public void SSYR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void SSYR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void SSYR2K(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void SSYRK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
- method public void STBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void STBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void STPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void STPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void STRMM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void STRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void STRSM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void STRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZGBMV(int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
- method public void ZGEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
- method public void ZGEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
- method public void ZGERC(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZGERU(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZHBMV(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
- method public void ZHEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
- method public void ZHEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
- method public void ZHER(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZHER2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZHER2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void ZHERK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
- method public void ZHPMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
- method public void ZHPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZHPR2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
- method public void ZSYMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
- method public void ZSYR2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
- method public void ZSYRK(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
- method public void ZTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZTRMM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void ZTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public void ZTRSM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
- method public void ZTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
- method public static android.renderscript.ScriptIntrinsicBLAS create(android.renderscript.RenderScript);
- field public static final int CONJ_TRANSPOSE = 113; // 0x71
- field public static final int LEFT = 141; // 0x8d
- field public static final int LOWER = 122; // 0x7a
- field public static final int NON_UNIT = 131; // 0x83
- field public static final int NO_TRANSPOSE = 111; // 0x6f
- field public static final int RIGHT = 142; // 0x8e
- field public static final int TRANSPOSE = 112; // 0x70
- field public static final int UNIT = 132; // 0x84
- field public static final int UPPER = 121; // 0x79
- }
-
- public class ScriptIntrinsicBlend extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicBlend create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.KernelID getKernelIDAdd();
- method public android.renderscript.Script.KernelID getKernelIDClear();
- method public android.renderscript.Script.KernelID getKernelIDDst();
- method public android.renderscript.Script.KernelID getKernelIDDstAtop();
- method public android.renderscript.Script.KernelID getKernelIDDstIn();
- method public android.renderscript.Script.KernelID getKernelIDDstOut();
- method public android.renderscript.Script.KernelID getKernelIDDstOver();
- method public android.renderscript.Script.KernelID getKernelIDMultiply();
- method public android.renderscript.Script.KernelID getKernelIDSrc();
- method public android.renderscript.Script.KernelID getKernelIDSrcAtop();
- method public android.renderscript.Script.KernelID getKernelIDSrcIn();
- method public android.renderscript.Script.KernelID getKernelIDSrcOut();
- method public android.renderscript.Script.KernelID getKernelIDSrcOver();
- method public android.renderscript.Script.KernelID getKernelIDSubtract();
- method public android.renderscript.Script.KernelID getKernelIDXor();
- }
-
- public final class ScriptIntrinsicBlur extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicBlur create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setInput(android.renderscript.Allocation);
- method public void setRadius(float);
- }
-
- public final class ScriptIntrinsicColorMatrix extends android.renderscript.ScriptIntrinsic {
+ @Deprecated public static final class ScriptGroup.Builder2 {
+ ctor @Deprecated public ScriptGroup.Builder2(android.renderscript.RenderScript);
+ method @Deprecated public android.renderscript.ScriptGroup.Input addInput();
+ method @Deprecated public android.renderscript.ScriptGroup.Closure addInvoke(android.renderscript.Script.InvokeID, java.lang.Object...);
+ method @Deprecated public android.renderscript.ScriptGroup.Closure addKernel(android.renderscript.Script.KernelID, android.renderscript.Type, java.lang.Object...);
+ method @Deprecated public android.renderscript.ScriptGroup create(String, android.renderscript.ScriptGroup.Future...);
+ }
+
+ @Deprecated public static final class ScriptGroup.Closure extends android.renderscript.BaseObj {
+ method @Deprecated public android.renderscript.ScriptGroup.Future getGlobal(android.renderscript.Script.FieldID);
+ method @Deprecated public android.renderscript.ScriptGroup.Future getReturn();
+ }
+
+ @Deprecated public static final class ScriptGroup.Future {
+ }
+
+ @Deprecated public static final class ScriptGroup.Input {
+ }
+
+ @Deprecated public abstract class ScriptIntrinsic extends android.renderscript.Script {
+ }
+
+ @Deprecated public final class ScriptIntrinsic3DLUT extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsic3DLUT create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setLUT(android.renderscript.Allocation);
+ }
+
+ @Deprecated public final class ScriptIntrinsicBLAS extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public void BNNM(android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation, int, int);
+ method @Deprecated public void CGBMV(int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+ method @Deprecated public void CGEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+ method @Deprecated public void CGEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+ method @Deprecated public void CGERC(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CGERU(android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CHBMV(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+ method @Deprecated public void CHEMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+ method @Deprecated public void CHEMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+ method @Deprecated public void CHER(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CHER2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CHER2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void CHERK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void CHPMV(int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Float2, android.renderscript.Allocation, int);
+ method @Deprecated public void CHPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CHPR2(int, android.renderscript.Float2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void CSYMM(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+ method @Deprecated public void CSYR2K(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+ method @Deprecated public void CSYRK(int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Float2, android.renderscript.Allocation);
+ method @Deprecated public void CTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void CTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void CTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void CTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void CTRMM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void CTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void CTRSM(int, int, int, int, android.renderscript.Float2, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void CTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DGBMV(int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+ method @Deprecated public void DGEMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void DGEMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+ method @Deprecated public void DGER(double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void DSBMV(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+ method @Deprecated public void DSPMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+ method @Deprecated public void DSPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void DSPR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void DSYMM(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void DSYMV(int, double, android.renderscript.Allocation, android.renderscript.Allocation, int, double, android.renderscript.Allocation, int);
+ method @Deprecated public void DSYR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void DSYR2(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void DSYR2K(int, int, double, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void DSYRK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void DTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DTRMM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void DTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void DTRSM(int, int, int, int, double, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void DTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void SGBMV(int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+ method @Deprecated public void SGEMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void SGEMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+ method @Deprecated public void SGER(float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void SSBMV(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+ method @Deprecated public void SSPMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+ method @Deprecated public void SSPR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void SSPR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void SSYMM(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void SSYMV(int, float, android.renderscript.Allocation, android.renderscript.Allocation, int, float, android.renderscript.Allocation, int);
+ method @Deprecated public void SSYR(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void SSYR2(int, float, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void SSYR2K(int, int, float, android.renderscript.Allocation, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void SSYRK(int, int, float, android.renderscript.Allocation, float, android.renderscript.Allocation);
+ method @Deprecated public void STBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void STBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void STPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void STPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void STRMM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void STRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void STRSM(int, int, int, int, float, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void STRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZGBMV(int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+ method @Deprecated public void ZGEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+ method @Deprecated public void ZGEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+ method @Deprecated public void ZGERC(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZGERU(android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZHBMV(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+ method @Deprecated public void ZHEMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+ method @Deprecated public void ZHEMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+ method @Deprecated public void ZHER(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZHER2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZHER2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void ZHERK(int, int, double, android.renderscript.Allocation, double, android.renderscript.Allocation);
+ method @Deprecated public void ZHPMV(int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, int, android.renderscript.Double2, android.renderscript.Allocation, int);
+ method @Deprecated public void ZHPR(int, double, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZHPR2(int, android.renderscript.Double2, android.renderscript.Allocation, int, android.renderscript.Allocation, int, android.renderscript.Allocation);
+ method @Deprecated public void ZSYMM(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+ method @Deprecated public void ZSYR2K(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+ method @Deprecated public void ZSYRK(int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Double2, android.renderscript.Allocation);
+ method @Deprecated public void ZTBMV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZTBSV(int, int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZTPMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZTPSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZTRMM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void ZTRMV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public void ZTRSM(int, int, int, int, android.renderscript.Double2, android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void ZTRSV(int, int, int, android.renderscript.Allocation, android.renderscript.Allocation, int);
+ method @Deprecated public static android.renderscript.ScriptIntrinsicBLAS create(android.renderscript.RenderScript);
+ field @Deprecated public static final int CONJ_TRANSPOSE = 113; // 0x71
+ field @Deprecated public static final int LEFT = 141; // 0x8d
+ field @Deprecated public static final int LOWER = 122; // 0x7a
+ field @Deprecated public static final int NON_UNIT = 131; // 0x83
+ field @Deprecated public static final int NO_TRANSPOSE = 111; // 0x6f
+ field @Deprecated public static final int RIGHT = 142; // 0x8e
+ field @Deprecated public static final int TRANSPOSE = 112; // 0x70
+ field @Deprecated public static final int UNIT = 132; // 0x84
+ field @Deprecated public static final int UPPER = 121; // 0x79
+ }
+
+ @Deprecated public class ScriptIntrinsicBlend extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicBlend create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDAdd();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDClear();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDDst();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDDstAtop();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDDstIn();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDDstOut();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDDstOver();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDMultiply();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSrc();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSrcAtop();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSrcIn();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSrcOut();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSrcOver();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDSubtract();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelIDXor();
+ }
+
+ @Deprecated public final class ScriptIntrinsicBlur extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicBlur create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setInput(android.renderscript.Allocation);
+ method @Deprecated public void setRadius(float);
+ }
+
+ @Deprecated public final class ScriptIntrinsicColorMatrix extends android.renderscript.ScriptIntrinsic {
method @Deprecated public static android.renderscript.ScriptIntrinsicColorMatrix create(android.renderscript.RenderScript, android.renderscript.Element);
- method public static android.renderscript.ScriptIntrinsicColorMatrix create(android.renderscript.RenderScript);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setAdd(android.renderscript.Float4);
- method public void setAdd(float, float, float, float);
- method public void setColorMatrix(android.renderscript.Matrix4f);
- method public void setColorMatrix(android.renderscript.Matrix3f);
- method public void setGreyscale();
- method public void setRGBtoYUV();
- method public void setYUVtoRGB();
- }
-
- public final class ScriptIntrinsicConvolve3x3 extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicConvolve3x3 create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setCoefficients(float[]);
- method public void setInput(android.renderscript.Allocation);
- }
-
- public final class ScriptIntrinsicConvolve5x5 extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicConvolve5x5 create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setCoefficients(float[]);
- method public void setInput(android.renderscript.Allocation);
- }
-
- public final class ScriptIntrinsicHistogram extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicHistogram create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public void forEach_Dot(android.renderscript.Allocation);
- method public void forEach_Dot(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID_Separate();
- method public void setDotCoefficients(float, float, float, float);
- method public void setOutput(android.renderscript.Allocation);
- }
-
- public final class ScriptIntrinsicLUT extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicLUT create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
- method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setAlpha(int, int);
- method public void setBlue(int, int);
- method public void setGreen(int, int);
- method public void setRed(int, int);
- }
-
- public final class ScriptIntrinsicResize extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicResize create(android.renderscript.RenderScript);
- method public void forEach_bicubic(android.renderscript.Allocation);
- method public void forEach_bicubic(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID_bicubic();
- method public void setInput(android.renderscript.Allocation);
- }
-
- public final class ScriptIntrinsicYuvToRGB extends android.renderscript.ScriptIntrinsic {
- method public static android.renderscript.ScriptIntrinsicYuvToRGB create(android.renderscript.RenderScript, android.renderscript.Element);
- method public void forEach(android.renderscript.Allocation);
- method public android.renderscript.Script.FieldID getFieldID_Input();
- method public android.renderscript.Script.KernelID getKernelID();
- method public void setInput(android.renderscript.Allocation);
- }
-
- public class Short2 {
- ctor public Short2();
- ctor public Short2(short, short);
- field public short x;
- field public short y;
- }
-
- public class Short3 {
- ctor public Short3();
- ctor public Short3(short, short, short);
- field public short x;
- field public short y;
- field public short z;
- }
-
- public class Short4 {
- ctor public Short4();
- ctor public Short4(short, short, short, short);
- field public short w;
- field public short x;
- field public short y;
- field public short z;
- }
-
- public class Type extends android.renderscript.BaseObj {
- method public static android.renderscript.Type createX(android.renderscript.RenderScript, android.renderscript.Element, int);
- method public static android.renderscript.Type createXY(android.renderscript.RenderScript, android.renderscript.Element, int, int);
- method public static android.renderscript.Type createXYZ(android.renderscript.RenderScript, android.renderscript.Element, int, int, int);
- method public int getCount();
- method public android.renderscript.Element getElement();
- method public int getX();
- method public int getY();
- method public int getYuv();
- method public int getZ();
- method public boolean hasFaces();
- method public boolean hasMipmaps();
- }
-
- public static class Type.Builder {
- ctor public Type.Builder(android.renderscript.RenderScript, android.renderscript.Element);
- method public android.renderscript.Type create();
- method public android.renderscript.Type.Builder setFaces(boolean);
- method public android.renderscript.Type.Builder setMipmaps(boolean);
- method public android.renderscript.Type.Builder setX(int);
- method public android.renderscript.Type.Builder setY(int);
- method public android.renderscript.Type.Builder setYuvFormat(int);
- method public android.renderscript.Type.Builder setZ(int);
- }
-
- public enum Type.CubemapFace {
- enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_X;
- enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_Y;
- enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_Z;
- enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_X;
- enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_Y;
- enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_Z;
+ method @Deprecated public static android.renderscript.ScriptIntrinsicColorMatrix create(android.renderscript.RenderScript);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setAdd(android.renderscript.Float4);
+ method @Deprecated public void setAdd(float, float, float, float);
+ method @Deprecated public void setColorMatrix(android.renderscript.Matrix4f);
+ method @Deprecated public void setColorMatrix(android.renderscript.Matrix3f);
+ method @Deprecated public void setGreyscale();
+ method @Deprecated public void setRGBtoYUV();
+ method @Deprecated public void setYUVtoRGB();
+ }
+
+ @Deprecated public final class ScriptIntrinsicConvolve3x3 extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicConvolve3x3 create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setCoefficients(float[]);
+ method @Deprecated public void setInput(android.renderscript.Allocation);
+ }
+
+ @Deprecated public final class ScriptIntrinsicConvolve5x5 extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicConvolve5x5 create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setCoefficients(float[]);
+ method @Deprecated public void setInput(android.renderscript.Allocation);
+ }
+
+ @Deprecated public final class ScriptIntrinsicHistogram extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicHistogram create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public void forEach_Dot(android.renderscript.Allocation);
+ method @Deprecated public void forEach_Dot(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID_Separate();
+ method @Deprecated public void setDotCoefficients(float, float, float, float);
+ method @Deprecated public void setOutput(android.renderscript.Allocation);
+ }
+
+ @Deprecated public final class ScriptIntrinsicLUT extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicLUT create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
+ method @Deprecated public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setAlpha(int, int);
+ method @Deprecated public void setBlue(int, int);
+ method @Deprecated public void setGreen(int, int);
+ method @Deprecated public void setRed(int, int);
+ }
+
+ @Deprecated public final class ScriptIntrinsicResize extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicResize create(android.renderscript.RenderScript);
+ method @Deprecated public void forEach_bicubic(android.renderscript.Allocation);
+ method @Deprecated public void forEach_bicubic(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID_bicubic();
+ method @Deprecated public void setInput(android.renderscript.Allocation);
+ }
+
+ @Deprecated public final class ScriptIntrinsicYuvToRGB extends android.renderscript.ScriptIntrinsic {
+ method @Deprecated public static android.renderscript.ScriptIntrinsicYuvToRGB create(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public void forEach(android.renderscript.Allocation);
+ method @Deprecated public android.renderscript.Script.FieldID getFieldID_Input();
+ method @Deprecated public android.renderscript.Script.KernelID getKernelID();
+ method @Deprecated public void setInput(android.renderscript.Allocation);
+ }
+
+ @Deprecated public class Short2 {
+ ctor @Deprecated public Short2();
+ ctor @Deprecated public Short2(short, short);
+ field @Deprecated public short x;
+ field @Deprecated public short y;
+ }
+
+ @Deprecated public class Short3 {
+ ctor @Deprecated public Short3();
+ ctor @Deprecated public Short3(short, short, short);
+ field @Deprecated public short x;
+ field @Deprecated public short y;
+ field @Deprecated public short z;
+ }
+
+ @Deprecated public class Short4 {
+ ctor @Deprecated public Short4();
+ ctor @Deprecated public Short4(short, short, short, short);
+ field @Deprecated public short w;
+ field @Deprecated public short x;
+ field @Deprecated public short y;
+ field @Deprecated public short z;
+ }
+
+ @Deprecated public class Type extends android.renderscript.BaseObj {
+ method @Deprecated public static android.renderscript.Type createX(android.renderscript.RenderScript, android.renderscript.Element, int);
+ method @Deprecated public static android.renderscript.Type createXY(android.renderscript.RenderScript, android.renderscript.Element, int, int);
+ method @Deprecated public static android.renderscript.Type createXYZ(android.renderscript.RenderScript, android.renderscript.Element, int, int, int);
+ method @Deprecated public int getCount();
+ method @Deprecated public android.renderscript.Element getElement();
+ method @Deprecated public int getX();
+ method @Deprecated public int getY();
+ method @Deprecated public int getYuv();
+ method @Deprecated public int getZ();
+ method @Deprecated public boolean hasFaces();
+ method @Deprecated public boolean hasMipmaps();
+ }
+
+ @Deprecated public static class Type.Builder {
+ ctor @Deprecated public Type.Builder(android.renderscript.RenderScript, android.renderscript.Element);
+ method @Deprecated public android.renderscript.Type create();
+ method @Deprecated public android.renderscript.Type.Builder setFaces(boolean);
+ method @Deprecated public android.renderscript.Type.Builder setMipmaps(boolean);
+ method @Deprecated public android.renderscript.Type.Builder setX(int);
+ method @Deprecated public android.renderscript.Type.Builder setY(int);
+ method @Deprecated public android.renderscript.Type.Builder setYuvFormat(int);
+ method @Deprecated public android.renderscript.Type.Builder setZ(int);
+ }
+
+ @Deprecated public enum Type.CubemapFace {
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace NEGATIVE_X;
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace NEGATIVE_Y;
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace NEGATIVE_Z;
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITIVE_X;
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITIVE_Y;
+ enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITIVE_Z;
enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITVE_X;
enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITVE_Y;
enum_constant @Deprecated public static final android.renderscript.Type.CubemapFace POSITVE_Z;
@@ -40532,6 +40533,9 @@ package android.telephony {
field public static final String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
field public static final String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool";
field public static final String KEY_SUPPORTS_CALL_COMPOSER_BOOL = "supports_call_composer_bool";
+ field public static final String KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_DTMF_BOOL = "supports_device_to_device_communication_using_dtmf_bool";
+ field public static final String KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL = "supports_device_to_device_communication_using_rtp_bool";
+ field public static final String KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL = "supports_sdp_negotiation_of_d2d_rtp_header_extensions_bool";
field public static final String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL = "support_3gpp_call_forwarding_while_roaming_bool";
field public static final String KEY_SUPPORT_ADD_CONFERENCE_PARTICIPANTS_BOOL = "support_add_conference_participants_bool";
field public static final String KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL = "support_adhoc_conference_calls_bool";
@@ -42138,7 +42142,7 @@ package android.telephony {
}
public static interface TelephonyCallback.CallStateListener {
- method @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public void onCallStateChanged(int, @Nullable String);
+ method public void onCallStateChanged(int);
}
public static interface TelephonyCallback.CarrierNetworkListener {
@@ -46425,8 +46429,8 @@ package android.view {
method @Deprecated public int getPixelFormat();
method @Nullable public android.graphics.ColorSpace getPreferredWideGamutColorSpace();
method public long getPresentationDeadlineNanos();
- method public void getRealMetrics(android.util.DisplayMetrics);
- method public void getRealSize(android.graphics.Point);
+ method @Deprecated public void getRealMetrics(android.util.DisplayMetrics);
+ method @Deprecated public void getRealSize(android.graphics.Point);
method @Deprecated public void getRectSize(android.graphics.Rect);
method public float getRefreshRate();
method public int getRotation();
@@ -46565,9 +46569,9 @@ package android.view {
public class GestureDetector {
ctor @Deprecated public GestureDetector(android.view.GestureDetector.OnGestureListener, android.os.Handler);
ctor @Deprecated public GestureDetector(android.view.GestureDetector.OnGestureListener);
- ctor public GestureDetector(android.content.Context, android.view.GestureDetector.OnGestureListener);
- ctor public GestureDetector(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler);
- ctor public GestureDetector(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler, boolean);
+ ctor public GestureDetector(@UiContext android.content.Context, android.view.GestureDetector.OnGestureListener);
+ ctor public GestureDetector(@UiContext android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler);
+ ctor public GestureDetector(@UiContext android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler, boolean);
method public boolean isLongpressEnabled();
method public boolean onGenericMotionEvent(android.view.MotionEvent);
method public boolean onTouchEvent(android.view.MotionEvent);
@@ -47256,7 +47260,7 @@ package android.view {
method public abstract android.view.LayoutInflater cloneInContext(android.content.Context);
method public final android.view.View createView(String, String, android.util.AttributeSet) throws java.lang.ClassNotFoundException, android.view.InflateException;
method @Nullable public final android.view.View createView(@NonNull android.content.Context, @NonNull String, @Nullable String, @Nullable android.util.AttributeSet) throws java.lang.ClassNotFoundException, android.view.InflateException;
- method public static android.view.LayoutInflater from(android.content.Context);
+ method public static android.view.LayoutInflater from(@UiContext android.content.Context);
method public android.content.Context getContext();
method public final android.view.LayoutInflater.Factory getFactory();
method public final android.view.LayoutInflater.Factory2 getFactory2();
@@ -48150,7 +48154,7 @@ package android.view {
method public final boolean getClipToOutline();
method @Nullable public final android.view.contentcapture.ContentCaptureSession getContentCaptureSession();
method public CharSequence getContentDescription();
- method public final android.content.Context getContext();
+ method @UiContext public final android.content.Context getContext();
method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
method public final boolean getDefaultFocusHighlightEnabled();
method public static int getDefaultSize(int, int);
@@ -48949,7 +48953,7 @@ package android.view {
public class ViewConfiguration {
ctor @Deprecated public ViewConfiguration();
- method public static android.view.ViewConfiguration get(android.content.Context);
+ method public static android.view.ViewConfiguration get(@UiContext android.content.Context);
method @Deprecated @FloatRange(from=1.0) public static float getAmbiguousGestureMultiplier();
method public static long getDefaultActionModeHideDuration();
method public static int getDoubleTapTimeout();
@@ -49507,7 +49511,7 @@ package android.view {
}
public abstract class Window {
- ctor public Window(android.content.Context);
+ ctor public Window(@UiContext android.content.Context);
method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
method public void addFlags(int);
method public final void addOnFrameMetricsAvailableListener(@NonNull android.view.Window.OnFrameMetricsAvailableListener, android.os.Handler);
@@ -49522,7 +49526,7 @@ package android.view {
method public int getColorMode();
method public final android.view.Window getContainer();
method public android.transition.Scene getContentScene();
- method public final android.content.Context getContext();
+ method @UiContext public final android.content.Context getContext();
method @Nullable public abstract android.view.View getCurrentFocus();
method @NonNull public abstract android.view.View getDecorView();
method public static int getDefaultFeatures(android.content.Context);
@@ -51472,6 +51476,7 @@ package android.view.inputmethod {
method public int describeContents();
method public void dump(android.util.Printer, String);
method public android.content.ComponentName getComponent();
+ method public int getConfigChanges();
method public String getId();
method public int getIsDefaultResourceId();
method public String getPackageName();
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 194a6d31cc43..057e16c8de5c 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -171,6 +171,14 @@ package android.media.session {
package android.net {
+ public final class EthernetNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+ ctor public EthernetNetworkSpecifier(@NonNull String);
+ method public int describeContents();
+ method @Nullable public String getInterfaceName();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkSpecifier> CREATOR;
+ }
+
public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
method public int getResourceId();
}
@@ -205,6 +213,13 @@ package android.net {
field @NonNull public final java.util.List<java.lang.String> underlyingIfaces;
}
+ public class VpnManager {
+ field @Deprecated public static final int TYPE_VPN_LEGACY = 3; // 0x3
+ field public static final int TYPE_VPN_NONE = -1; // 0xffffffff
+ field public static final int TYPE_VPN_PLATFORM = 2; // 0x2
+ field public static final int TYPE_VPN_SERVICE = 1; // 0x1
+ }
+
}
package android.os {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index a7473e7a4c45..72868c87da24 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -147,6 +147,7 @@ package android {
field public static final String MANAGE_SENSOR_PRIVACY = "android.permission.MANAGE_SENSOR_PRIVACY";
field public static final String MANAGE_SMARTSPACE = "android.permission.MANAGE_SMARTSPACE";
field public static final String MANAGE_SOUND_TRIGGER = "android.permission.MANAGE_SOUND_TRIGGER";
+ field public static final String MANAGE_SPEECH_RECOGNITION = "android.permission.MANAGE_SPEECH_RECOGNITION";
field public static final String MANAGE_SUBSCRIPTION_PLANS = "android.permission.MANAGE_SUBSCRIPTION_PLANS";
field public static final String MANAGE_TEST_NETWORKS = "android.permission.MANAGE_TEST_NETWORKS";
field public static final String MANAGE_TIME_AND_ZONE_DETECTION = "android.permission.MANAGE_TIME_AND_ZONE_DETECTION";
@@ -260,7 +261,6 @@ package android {
field public static final String SIGNAL_REBOOT_READINESS = "android.permission.SIGNAL_REBOOT_READINESS";
field public static final String SOUND_TRIGGER_RUN_IN_BATTERY_SAVER = "android.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER";
field public static final String START_ACTIVITIES_FROM_BACKGROUND = "android.permission.START_ACTIVITIES_FROM_BACKGROUND";
- field public static final String START_FOREGROUND_SERVICES_FROM_BACKGROUND = "android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND";
field public static final String STATUS_BAR_SERVICE = "android.permission.STATUS_BAR_SERVICE";
field public static final String STOP_APP_SWITCHES = "android.permission.STOP_APP_SWITCHES";
field public static final String SUBSTITUTE_NOTIFICATION_APP_NAME = "android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME";
@@ -360,6 +360,7 @@ package android {
field public static final int config_systemGallery = 17039399; // 0x1040027
field public static final int config_systemShell = 17039402; // 0x104002a
field public static final int config_systemSpeechRecognizer = 17039406; // 0x104002e
+ field public static final int config_systemTelevisionNotificationHandler = 17039409; // 0x1040031
field public static final int config_systemWellbeing = 17039408; // 0x1040030
field public static final int config_systemWifiCoexManager = 17039407; // 0x104002f
}
@@ -381,7 +382,7 @@ package android.accounts {
package android.app {
- public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
method public void convertFromTranslucent();
method public boolean convertToTranslucent(android.app.Activity.TranslucentConversionListener, android.app.ActivityOptions);
method @Deprecated public boolean isBackgroundVisibleBehind();
@@ -2173,6 +2174,7 @@ package android.content {
field public static final String OEM_LOCK_SERVICE = "oem_lock";
field public static final String PERMISSION_SERVICE = "permission";
field public static final String PERSISTENT_DATA_BLOCK_SERVICE = "persistent_data_block";
+ field public static final String POWER_EXEMPTION_SERVICE = "power_exemption";
field public static final String REBOOT_READINESS_SERVICE = "reboot_readiness";
field public static final String ROLLBACK_SERVICE = "rollback";
field public static final String SEARCH_UI_SERVICE = "search_ui";
@@ -2196,7 +2198,7 @@ package android.content {
}
public static final class ContextParams.Builder {
- method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public android.content.ContextParams.Builder setRenouncedPermissions(@NonNull java.util.Set<java.lang.String>);
+ method @NonNull @RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS) public android.content.ContextParams.Builder setRenouncedPermissions(@Nullable java.util.Set<java.lang.String>);
}
public class ContextWrapper extends android.content.Context {
@@ -2882,11 +2884,16 @@ package android.graphics.fonts {
}
public static final class FontFamilyUpdateRequest.FontFamily {
- ctor public FontFamilyUpdateRequest.FontFamily(@NonNull String, @NonNull java.util.List<android.graphics.fonts.FontFamilyUpdateRequest.Font>);
method @NonNull public java.util.List<android.graphics.fonts.FontFamilyUpdateRequest.Font> getFonts();
method @NonNull public String getName();
}
+ public static final class FontFamilyUpdateRequest.FontFamily.Builder {
+ ctor public FontFamilyUpdateRequest.FontFamily.Builder(@NonNull String, @NonNull java.util.List<android.graphics.fonts.FontFamilyUpdateRequest.Font>);
+ method @NonNull public android.graphics.fonts.FontFamilyUpdateRequest.FontFamily.Builder addFont(@NonNull android.graphics.fonts.FontFamilyUpdateRequest.Font);
+ method @NonNull public android.graphics.fonts.FontFamilyUpdateRequest.FontFamily build();
+ }
+
public final class FontFileUpdateRequest {
ctor public FontFileUpdateRequest(@NonNull android.os.ParcelFileDescriptor, @NonNull byte[]);
method @NonNull public android.os.ParcelFileDescriptor getParcelFileDescriptor();
@@ -3103,6 +3110,7 @@ package android.hardware.hdmi {
method @NonNull public java.util.List<android.hardware.hdmi.HdmiDeviceInfo> getConnectedDevices();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getHdmiCecEnabled();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getHdmiCecVersion();
+ method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getHdmiCecVolumeControlEnabled();
method public int getPhysicalAddress();
method @Nullable public android.hardware.hdmi.HdmiPlaybackClient getPlaybackClient();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public String getPowerControlMode();
@@ -3110,6 +3118,8 @@ package android.hardware.hdmi {
method @Nullable public android.hardware.hdmi.HdmiSwitchClient getSwitchClient();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getSystemAudioModeMuting();
method @Nullable public android.hardware.hdmi.HdmiTvClient getTvClient();
+ method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getTvSendStandbyOnSleep();
+ method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getTvWakeOnOneTouchPlay();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public java.util.List<java.lang.String> getUserCecSettings();
method public boolean isDeviceConnected(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
method public void powerOffDevice(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
@@ -3118,10 +3128,13 @@ package android.hardware.hdmi {
method public void setActiveSource(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setHdmiCecEnabled(@NonNull int);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setHdmiCecVersion(@NonNull int);
+ method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setHdmiCecVolumeControlEnabled(int);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setPowerControlMode(@NonNull String);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setPowerStateChangeOnActiveSourceLost(@NonNull String);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setStandbyMode(boolean);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setSystemAudioModeMuting(@NonNull int);
+ method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setTvSendStandbyOnSleep(@NonNull int);
+ method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setTvWakeOnOneTouchPlay(@NonNull int);
field public static final String ACTION_OSD_MESSAGE = "android.hardware.hdmi.action.OSD_MESSAGE";
field public static final int AVR_VOLUME_MUTED = 101; // 0x65
field public static final String CEC_SETTING_NAME_HDMI_CEC_ENABLED = "hdmi_cec_enabled";
@@ -3129,6 +3142,9 @@ package android.hardware.hdmi {
field public static final String CEC_SETTING_NAME_POWER_CONTROL_MODE = "send_standby_on_sleep";
field public static final String CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST = "power_state_change_on_active_source_lost";
field public static final String CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING = "system_audio_mode_muting";
+ field public static final String CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP = "tv_send_standby_on_sleep";
+ field public static final String CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY = "tv_wake_on_one_touch_play";
+ field public static final String CEC_SETTING_NAME_VOLUME_CONTROL_MODE = "volume_control_enabled";
field public static final int CLEAR_TIMER_STATUS_CEC_DISABLE = 162; // 0xa2
field public static final int CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION = 160; // 0xa0
field public static final int CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE = 161; // 0xa1
@@ -3224,6 +3240,12 @@ package android.hardware.hdmi {
field public static final int TIMER_STATUS_PROGRAMMED_INFO_MIGHT_NOT_ENOUGH_SPACE = 11; // 0xb
field public static final int TIMER_STATUS_PROGRAMMED_INFO_NOT_ENOUGH_SPACE = 9; // 0x9
field public static final int TIMER_STATUS_PROGRAMMED_INFO_NO_MEDIA_INFO = 10; // 0xa
+ field public static final int TV_SEND_STANDBY_ON_SLEEP_DISABLED = 0; // 0x0
+ field public static final int TV_SEND_STANDBY_ON_SLEEP_ENABLED = 1; // 0x1
+ field public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_DISABLED = 0; // 0x0
+ field public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED = 1; // 0x1
+ field public static final int VOLUME_CONTROL_DISABLED = 0; // 0x0
+ field public static final int VOLUME_CONTROL_ENABLED = 1; // 0x1
}
public static interface HdmiControlManager.CecSettingChangeListener {
@@ -7463,22 +7485,22 @@ package android.net.netstats.provider {
package android.net.sip {
- public class SipAudioCall {
- method @Nullable public android.net.rtp.AudioGroup getAudioGroup();
- method public void setAudioGroup(@NonNull android.net.rtp.AudioGroup);
+ @Deprecated public class SipAudioCall {
+ method @Deprecated @Nullable public android.net.rtp.AudioGroup getAudioGroup();
+ method @Deprecated public void setAudioGroup(@NonNull android.net.rtp.AudioGroup);
}
- public class SipManager {
- method @NonNull public java.util.List<android.net.sip.SipProfile> getProfiles() throws android.net.sip.SipException;
- field public static final String ACTION_SIP_CALL_OPTION_CHANGED = "android.net.sip.action.SIP_CALL_OPTION_CHANGED";
- field public static final String ACTION_SIP_INCOMING_CALL = "android.net.sip.action.SIP_INCOMING_CALL";
- field public static final String ACTION_SIP_REMOVE_PROFILE = "android.net.sip.action.SIP_REMOVE_PROFILE";
- field public static final String ACTION_SIP_SERVICE_UP = "android.net.sip.action.SIP_SERVICE_UP";
- field public static final String ACTION_START_SIP = "android.net.sip.action.START_SIP";
+ @Deprecated public class SipManager {
+ method @Deprecated @NonNull public java.util.List<android.net.sip.SipProfile> getProfiles() throws android.net.sip.SipException;
+ field @Deprecated public static final String ACTION_SIP_CALL_OPTION_CHANGED = "android.net.sip.action.SIP_CALL_OPTION_CHANGED";
+ field @Deprecated public static final String ACTION_SIP_INCOMING_CALL = "android.net.sip.action.SIP_INCOMING_CALL";
+ field @Deprecated public static final String ACTION_SIP_REMOVE_PROFILE = "android.net.sip.action.SIP_REMOVE_PROFILE";
+ field @Deprecated public static final String ACTION_SIP_SERVICE_UP = "android.net.sip.action.SIP_SERVICE_UP";
+ field @Deprecated public static final String ACTION_START_SIP = "android.net.sip.action.START_SIP";
}
- public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
- method public int getCallingUid();
+ @Deprecated public class SipProfile implements java.lang.Cloneable android.os.Parcelable java.io.Serializable {
+ method @Deprecated public int getCallingUid();
}
}
@@ -8153,6 +8175,25 @@ package android.os {
field @NonNull public static final android.os.Parcelable.Creator<android.os.ParcelableHolder> CREATOR;
}
+ public class PowerExemptionManager {
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToPermanentAllowList(@NonNull String);
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToPermanentAllowList(@NonNull java.util.List<java.lang.String>);
+ method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public void addToTemporaryAllowList(@NonNull String, long, int, @Nullable String);
+ method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public long addToTemporaryAllowListForEvent(@NonNull String, int, int, @Nullable String);
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void removeFromAllowList(@NonNull String);
+ field public static final int EVENT_MMS = 2; // 0x2
+ field public static final int EVENT_SMS = 1; // 0x1
+ field public static final int EVENT_UNSPECIFIED = 0; // 0x0
+ field public static final int REASON_ACTIVITY_RECOGNITION = 103; // 0x67
+ field public static final int REASON_GEOFENCING = 100; // 0x64
+ field public static final int REASON_OTHER = 1; // 0x1
+ field public static final int REASON_PUSH_MESSAGING = 101; // 0x65
+ field public static final int REASON_PUSH_MESSAGING_OVER_QUOTA = 102; // 0x66
+ field public static final int REASON_UNKNOWN = 0; // 0x0
+ field public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED = 0; // 0x0
+ field public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1; // 0x1
+ }
+
public final class PowerManager {
method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long);
method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend();
@@ -9932,11 +9973,13 @@ package android.service.resumeonreboot {
package android.service.rotationresolver {
public final class RotationResolutionRequest implements android.os.Parcelable {
+ ctor public RotationResolutionRequest(@NonNull String, int, int, boolean, long);
method public int describeContents();
method public int getCurrentRotation();
method @NonNull public String getPackageName();
method public int getProposedRotation();
method public long getTimeoutMillis();
+ method public boolean shouldUseCamera();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.rotationresolver.RotationResolutionRequest> CREATOR;
}
@@ -11404,7 +11447,7 @@ package android.telephony {
field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27; // 0x1b
field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26; // 0x1a
field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4; // 0x4
- field @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public static final int EVENT_CALL_STATE_CHANGED = 6; // 0x6
+ field public static final int EVENT_CALL_STATE_CHANGED = 6; // 0x6
field public static final int EVENT_CARRIER_NETWORK_CHANGED = 17; // 0x11
field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_INFO_CHANGED = 11; // 0xb
field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_LOCATION_CHANGED = 5; // 0x5
@@ -11416,6 +11459,7 @@ package android.telephony {
field public static final int EVENT_DISPLAY_INFO_CHANGED = 21; // 0x15
field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25; // 0x19
field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28; // 0x1c
+ field @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public static final int EVENT_LEGACY_CALL_STATE_CHANGED = 36; // 0x24
field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3; // 0x3
field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_OEM_HOOK_RAW = 15; // 0xf
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29; // 0x1d
@@ -11619,7 +11663,7 @@ package android.telephony {
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult setIccLockEnabled(boolean, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabled(int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
- method public int setNrDualConnectivityState(int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setNrDualConnectivityState(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 7b5b1989c1e5..72d39764bfc1 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -87,7 +87,7 @@ package android.animation {
package android.app {
- public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
method public void onMovedToDisplay(int, android.content.res.Configuration);
}
@@ -721,6 +721,8 @@ package android.content.pm {
public class ActivityInfo extends android.content.pm.ComponentInfo implements android.os.Parcelable {
method public static boolean isTranslucentOrFloating(android.content.res.TypedArray);
+ field public static final long FORCE_NON_RESIZE_APP = 181136395L; // 0xacbec0bL
+ field public static final long FORCE_RESIZE_APP = 174042936L; // 0xa5faf38L
field public static final int RESIZE_MODE_RESIZEABLE = 2; // 0x2
}
@@ -1176,7 +1178,7 @@ package android.hardware.soundtrigger {
package android.inputmethodservice {
- public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
+ @UiContext public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService {
field public static final long FINISH_INPUT_NO_FALLBACK_CONNECTION = 156215187L; // 0x94fa793L
}
@@ -2123,6 +2125,14 @@ package android.service.watchdog {
}
+package android.speech {
+
+ public class SpeechRecognizer {
+ method public void setTemporaryOnDeviceRecognizer(@Nullable android.content.ComponentName);
+ }
+
+}
+
package android.telecom {
public static class Call.Details {
@@ -2148,6 +2158,10 @@ package android.telecom {
method @NonNull public android.telecom.ConnectionRequest.Builder setVideoState(int);
}
+ public abstract class ConnectionService extends android.app.Service {
+ method public void onBindClient(@Nullable android.content.Intent);
+ }
+
}
package android.telephony {
@@ -2325,7 +2339,6 @@ package android.util {
field public static final String FFLAG_PREFIX = "sys.fflag.";
field public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
field public static final String PERSIST_PREFIX = "persist.sys.fflag.override.";
- field public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
field public static final String SETTINGS_WIFITRACKER2 = "settings_wifitracker2";
}
@@ -2700,6 +2713,10 @@ package android.view.inputmethod {
method @NonNull public static android.view.inputmethod.InlineSuggestionsResponse newInlineSuggestionsResponse(@NonNull java.util.List<android.view.inputmethod.InlineSuggestion>);
}
+ public final class InputMethodInfo implements android.os.Parcelable {
+ ctor public InputMethodInfo(@NonNull String, @NonNull String, @NonNull CharSequence, @NonNull String, int);
+ }
+
public final class InputMethodManager {
method public int getDisplayId();
method public boolean hasActiveInputConnection(@Nullable android.view.View);
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index b15fa27485be..856ed507c524 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -580,6 +580,13 @@ public class AccessibilityServiceInfo implements Parcelable {
private int mHtmlDescriptionRes;
/**
+ * Whether the service is for accessibility.
+ *
+ * @hide
+ */
+ private boolean mIsAccessibilityTool = false;
+
+ /**
* Creates a new instance.
*/
public AccessibilityServiceInfo() {
@@ -708,6 +715,8 @@ public class AccessibilityServiceInfo implements Parcelable {
if (peekedValue != null) {
mHtmlDescriptionRes = peekedValue.resourceId;
}
+ mIsAccessibilityTool = asAttributes.getBoolean(
+ R.styleable.AccessibilityService_isAccessibilityTool, false);
asAttributes.recycle();
} catch (NameNotFoundException e) {
throw new XmlPullParserException( "Unable to create context for: "
@@ -1036,6 +1045,15 @@ public class AccessibilityServiceInfo implements Parcelable {
}
/**
+ * Indicates if the service is used to assist users with disabilities.
+ *
+ * @return {@code true} if the property is set to true.
+ */
+ public boolean isAccessibilityTool() {
+ return mIsAccessibilityTool;
+ }
+
+ /**
* {@inheritDoc}
*/
public int describeContents() {
@@ -1061,6 +1079,7 @@ public class AccessibilityServiceInfo implements Parcelable {
parcel.writeInt(mAnimatedImageRes);
parcel.writeInt(mHtmlDescriptionRes);
parcel.writeString(mNonLocalizedDescription);
+ parcel.writeBoolean(mIsAccessibilityTool);
}
private void initFromParcel(Parcel parcel) {
@@ -1082,6 +1101,7 @@ public class AccessibilityServiceInfo implements Parcelable {
mAnimatedImageRes = parcel.readInt();
mHtmlDescriptionRes = parcel.readInt();
mNonLocalizedDescription = parcel.readString();
+ mIsAccessibilityTool = parcel.readBoolean();
}
@Override
@@ -1136,6 +1156,8 @@ public class AccessibilityServiceInfo implements Parcelable {
stringBuilder.append(", ");
stringBuilder.append("summary: ").append(mNonLocalizedSummary);
stringBuilder.append(", ");
+ stringBuilder.append("isAccessibilityTool: ").append(mIsAccessibilityTool);
+ stringBuilder.append(", ");
appendCapabilities(stringBuilder, mCapabilities);
return stringBuilder.toString();
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0b5958695dff..8977ba774d0b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5775,11 +5775,14 @@ public final class ActivityThread extends ClientTransactionHandler
// ResourcesImpl constructions.
final int diff = activity.mCurrentConfig.diffPublicOnly(newConfig);
- if (diff == 0 && !shouldUpdateWindowMetricsBounds(activity.mCurrentConfig, newConfig)
- && !movedToDifferentDisplay && mResourcesManager.isSameResourcesOverrideConfig(
- activityToken, amOverrideConfig)) {
- // Nothing significant, don't proceed with updating and reporting.
- return null;
+ if (diff == 0) {
+ if (!shouldUpdateWindowMetricsBounds(activity.mCurrentConfig, newConfig)
+ && !movedToDifferentDisplay
+ && mResourcesManager.isSameResourcesOverrideConfig(
+ activityToken, amOverrideConfig)) {
+ // Nothing significant, don't proceed with updating and reporting.
+ return null;
+ }
} else if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
// If this activity doesn't handle any of the config changes, then don't bother
// calling onConfigurationChanged. Otherwise, report to the activity for the
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index a6260d6d9cad..dba62b9d3b63 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3228,6 +3228,12 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public void registerDexModule(@NonNull String dexModule,
@Nullable DexModuleRegisterCallback callback) {
+ // Create the callback delegate to be passed to package manager service.
+ DexModuleRegisterCallbackDelegate callbackDelegate = null;
+ if (callback != null) {
+ callbackDelegate = new DexModuleRegisterCallbackDelegate(callback);
+ }
+
// Check if this is a shared module by looking if the others can read it.
boolean isSharedModule = false;
try {
@@ -3236,18 +3242,13 @@ public class ApplicationPackageManager extends PackageManager {
isSharedModule = true;
}
} catch (ErrnoException e) {
- callback.onDexModuleRegistered(dexModule, false,
- "Could not get stat the module file: " + e.getMessage());
+ if (callbackDelegate != null) {
+ callback.onDexModuleRegistered(dexModule, false,
+ "Could not get stat the module file: " + e.getMessage());
+ }
return;
}
- // Module path is ok.
- // Create the callback delegate to be passed to package manager service.
- DexModuleRegisterCallbackDelegate callbackDelegate = null;
- if (callback != null) {
- callbackDelegate = new DexModuleRegisterCallbackDelegate(callback);
- }
-
// Invoke the package manager service.
try {
mPM.registerDexModule(mContext.getPackageName(), dexModule,
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index d040938803f6..3af07635c185 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1995,7 +1995,7 @@ class ContextImpl extends Context {
final String errorMessage = "Tried to access visual service "
+ SystemServiceRegistry.getSystemServiceClassName(name)
+ " from a non-visual Context:" + getOuterContext();
- final String message = "Visual services, such as WindowManager, WallpaperService "
+ final String message = "Visual services, such as WindowManager"
+ "or LayoutInflater should be accessed from Activity or other visual "
+ "Context. Use an Activity or a Context created with "
+ "Context#createWindowContext(int, Bundle), which are adjusted to "
@@ -2635,7 +2635,8 @@ class ContextImpl extends Context {
@Override
public @NonNull Context createAttributionContext(@Nullable String attributionTag) {
- return createContext(new ContextParams.Builder().setAttributionTag(attributionTag).build());
+ return createContext(
+ new ContextParams.Builder(mParams).setAttributionTag(attributionTag).build());
}
@Override
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index be426aa7ed2b..83d0246744df 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -1110,6 +1110,10 @@ public final class LoadedApk {
mPackageName,
PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
UserHandle.myUserId());
+ if (pi == null) {
+ throw new IllegalStateException("Unable to get package info for "
+ + mPackageName + "; is package not installed?");
+ }
/*
* Two possible indications that this package could be
* sharing its virtual machine with other packages:
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index b00cfcb0d020..2b45723dae55 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1611,7 +1611,8 @@ public class Notification implements Parcelable
/**
* {@code SemanticAction}: Mark the conversation associated with the notification as a
- * priority. Note that this is only for use by the notification assistant services.
+ * priority. Note that this is only for use by the notification assistant services. The
+ * type will be ignored for actions an app adds to its own notifications.
* @hide
*/
@SystemApi
@@ -1619,7 +1620,8 @@ public class Notification implements Parcelable
/**
* {@code SemanticAction}: Mark content as a potential phishing attempt.
- * Note that this is only for use by the notification assistant services.
+ * Note that this is only for use by the notification assistant services. The type will
+ * be ignored for actions an app adds to its own notifications.
* @hide
*/
@SystemApi
@@ -5015,11 +5017,14 @@ public class Notification implements Parcelable
}
if (p.text != null && p.text.length() != 0
&& (!showProgress || p.mAllowTextWithProgress)) {
- int textId = com.android.internal.R.id.text;
- contentView.setTextViewText(textId, processTextSpans(p.text));
- setTextViewColorSecondary(contentView, textId, p);
- contentView.setViewVisibility(textId, View.VISIBLE);
+ contentView.setViewVisibility(p.mTextViewId, View.VISIBLE);
+ contentView.setTextViewText(p.mTextViewId, processTextSpans(p.text));
+ setTextViewColorSecondary(contentView, p.mTextViewId, p);
hasSecondLine = true;
+ } else if (p.mTextViewId != R.id.text) {
+ // This alternate text view ID is not cleared by resetStandardTemplate
+ contentView.setViewVisibility(p.mTextViewId, View.GONE);
+ contentView.setTextViewText(p.mTextViewId, null);
}
setHeaderlessVerticalMargins(contentView, p, hasSecondLine);
@@ -5211,6 +5216,9 @@ public class Notification implements Parcelable
// views in states with a header (big states)
result.mHeadingExtraMarginSet.applyToView(contentView, R.id.notification_header);
result.mTitleMarginSet.applyToView(contentView, R.id.title);
+ // If there is no title, the text (or big_text) needs to wrap around the image
+ result.mTitleMarginSet.applyToView(contentView, p.mTextViewId);
+ contentView.setInt(p.mTextViewId, "setNumIndentLines", p.hasTitle() ? 0 : 1);
}
}
@@ -5443,8 +5451,12 @@ public class Notification implements Parcelable
return p.allowColorization && mN.isColorized();
}
- private boolean isCallActionColorCustomizable(StandardTemplateParams p) {
- return isColorized(p) && mContext.getResources().getBoolean(
+ private boolean isCallActionColorCustomizable() {
+ // NOTE: this doesn't need to check StandardTemplateParams.allowColorization because
+ // that is only used for disallowing colorization of headers for the minimized state,
+ // and neither of those conditions applies when showing actions.
+ // Not requiring StandardTemplateParams as an argument simplifies the creation process.
+ return mN.isColorized() && mContext.getResources().getBoolean(
R.bool.config_callNotificationActionColorsRequireColorized);
}
@@ -5510,13 +5522,13 @@ public class Notification implements Parcelable
*/
private @NonNull List<Notification.Action> getNonContextualActions() {
if (mActions == null) return Collections.emptyList();
- List<Notification.Action> contextualActions = new ArrayList<>();
+ List<Notification.Action> standardActions = new ArrayList<>();
for (Notification.Action action : mActions) {
if (!action.isContextual()) {
- contextualActions.add(action);
+ standardActions.add(action);
}
}
- return contextualActions;
+ return standardActions;
}
private RemoteViews applyStandardTemplateWithActions(int layoutId,
@@ -5536,16 +5548,29 @@ public class Notification implements Parcelable
// filter them out here.
List<Notification.Action> nonContextualActions = getNonContextualActions();
- int N = nonContextualActions.size();
- boolean emphazisedMode = mN.fullScreenIntent != null;
+ int numActions = Math.min(nonContextualActions.size(), MAX_ACTION_BUTTONS);
+ boolean emphazisedMode = mN.fullScreenIntent != null || p.mCallStyleActions;
+ if (p.mCallStyleActions) {
+ // Clear view padding to allow buttons to start on the left edge.
+ // This must be done before 'setEmphasizedMode' which sets top/bottom margins.
+ big.setViewPadding(R.id.actions, 0, 0, 0, 0);
+ // Add an optional indent that will make buttons start at the correct column when
+ // there is enough space to do so (and fall back to the left edge if not).
+ big.setInt(R.id.actions, "setCollapsibleIndentDimen",
+ R.dimen.call_notification_collapsible_indent);
+ }
big.setBoolean(R.id.actions, "setEmphasizedMode", emphazisedMode);
- if (N > 0 && !p.mHideActions) {
+ if (p.mCallStyleActions) {
+ // Use "wrap_content" (unlike normal emphasized mode) and allow prioritizing the
+ // required actions (Answer, Decline, and Hang Up).
+ big.setBoolean(R.id.actions, "setPrioritizedWrapMode", true);
+ }
+ if (numActions > 0 && !p.mHideActions) {
big.setViewVisibility(R.id.actions_container, View.VISIBLE);
big.setViewVisibility(R.id.actions, View.VISIBLE);
big.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
RemoteViews.MARGIN_BOTTOM, 0);
- if (N>MAX_ACTION_BUTTONS) N=MAX_ACTION_BUTTONS;
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < numActions; i++) {
Action action = nonContextualActions.get(i);
boolean actionHasValidInput = hasValidRemoteInput(action);
@@ -5556,6 +5581,11 @@ public class Notification implements Parcelable
// Clear the drawable
button.setInt(R.id.action0, "setBackgroundResource", 0);
}
+ if (p.mCallStyleActions && i > 0) {
+ // Clear start margin from non-first buttons to reduce the gap between them.
+ // (8dp remaining gap is from all buttons' standard 4dp inset).
+ button.setViewLayoutMarginDimen(R.id.action0, RemoteViews.MARGIN_START, 0);
+ }
big.addView(R.id.actions, button);
}
} else {
@@ -5773,11 +5803,11 @@ public class Notification implements Parcelable
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.S) {
return true;
}
- // If the big content view has no content, we can exempt the app from having to show it.
+ // Notifications with contentView and without a bigContentView, style, or actions would
+ // not have an expanded state before S, so showing the standard template expanded state
+ // usually looks wrong, so we keep it simple and don't show the expanded state.
boolean exempt = mN.contentView != null && mN.bigContentView == null
- && mStyle == null && mActions.size() == 0
- && mN.extras.getCharSequence(EXTRA_TITLE) == null
- && mN.extras.getCharSequence(EXTRA_TEXT) == null;
+ && mStyle == null && mActions.size() == 0;
return !exempt;
}
@@ -6017,7 +6047,7 @@ public class Notification implements Parcelable
button.setColorStateList(R.id.action0, "setButtonBackground",
ColorStateList.valueOf(background));
button.setBoolean(R.id.action0, "setHasStroke", !hasColorOverride);
- if (p.mAllowActionIcons) {
+ if (p.mCallStyleActions) {
button.setImageViewIcon(R.id.action0, action.getIcon());
boolean priority = action.getExtras().getBoolean(CallStyle.KEY_ACTION_PRIORITY);
button.setBoolean(R.id.action0, "setWrapModePriority", priority);
@@ -7014,16 +7044,7 @@ public class Notification implements Parcelable
p.title = mBigContentTitle;
}
- RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(layoutId, p,
- result);
-
- if (mBigContentTitle != null && mBigContentTitle.equals("")) {
- contentView.setViewVisibility(R.id.title, View.GONE);
- } else {
- contentView.setViewVisibility(R.id.title, View.VISIBLE);
- }
-
- return contentView;
+ return mBuilder.applyStandardTemplateWithActions(layoutId, p, result);
}
/**
@@ -7616,22 +7637,16 @@ public class Notification implements Parcelable
public RemoteViews makeBigContentView() {
StandardTemplateParams p = mBuilder.mParams.reset()
.viewType(StandardTemplateParams.VIEW_TYPE_BIG)
- .fillTextsFrom(mBuilder).text(null);
- RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource(), p, null);
+ .textViewId(R.id.big_text)
+ .fillTextsFrom(mBuilder);
+ // Replace the text with the big text, but only if the big text is not empty.
CharSequence bigTextText = mBuilder.processLegacyText(mBigText);
- if (TextUtils.isEmpty(bigTextText)) {
- // In case the bigtext is null / empty fall back to the normal text to avoid a weird
- // experience
- bigTextText = mBuilder.processLegacyText(
- mBuilder.getAllExtras().getCharSequence(EXTRA_TEXT));
+ if (!TextUtils.isEmpty(bigTextText)) {
+ p.text(bigTextText);
}
- contentView.setTextViewText(R.id.big_text, mBuilder.processTextSpans(bigTextText));
- mBuilder.setTextViewColorSecondary(contentView, R.id.big_text, p);
- contentView.setViewVisibility(R.id.big_text,
- TextUtils.isEmpty(bigTextText) ? View.GONE : View.VISIBLE);
- return contentView;
+ return getStandardView(mBuilder.getBigTextLayoutResource(), p, null /* result */);
}
/**
@@ -9263,6 +9278,17 @@ public class Notification implements Parcelable
return this;
}
+ /** @hide */
+ @Override
+ public Notification buildStyled(Notification wip) {
+ wip = super.buildStyled(wip);
+ // ensure that the actions in the builder and notification are corrected.
+ mBuilder.mActions = getActionsListWithSystemActions();
+ wip.actions = new Action[mBuilder.mActions.size()];
+ mBuilder.mActions.toArray(wip.actions);
+ return wip;
+ }
+
/**
* @hide
*/
@@ -9322,14 +9348,14 @@ public class Notification implements Parcelable
}
@NonNull
- private Action makeNegativeAction(@NonNull StandardTemplateParams p) {
+ private Action makeNegativeAction() {
if (mDeclineIntent == null) {
- return makeAction(p, R.drawable.ic_call_decline,
+ return makeAction(R.drawable.ic_call_decline,
R.string.call_notification_hang_up_action,
mDeclineButtonColor, R.color.call_notification_decline_color,
mHangUpIntent);
} else {
- return makeAction(p, R.drawable.ic_call_decline,
+ return makeAction(R.drawable.ic_call_decline,
R.string.call_notification_decline_action,
mDeclineButtonColor, R.color.call_notification_decline_color,
mDeclineIntent);
@@ -9337,18 +9363,17 @@ public class Notification implements Parcelable
}
@Nullable
- private Action makeAnswerAction(@NonNull StandardTemplateParams p) {
- return mAnswerIntent == null ? null : makeAction(p, R.drawable.ic_call_answer,
+ private Action makeAnswerAction() {
+ return mAnswerIntent == null ? null : makeAction(R.drawable.ic_call_answer,
R.string.call_notification_answer_action,
mAnswerButtonColor, R.color.call_notification_answer_color,
mAnswerIntent);
}
@NonNull
- private Action makeAction(@NonNull StandardTemplateParams p,
- @DrawableRes int icon, @StringRes int title,
+ private Action makeAction(@DrawableRes int icon, @StringRes int title,
@ColorInt Integer colorInt, @ColorRes int defaultColorRes, PendingIntent intent) {
- if (colorInt == null || !mBuilder.isCallActionColorCustomizable(p)) {
+ if (colorInt == null || !mBuilder.isCallActionColorCustomizable()) {
colorInt = mBuilder.mContext.getColor(defaultColorRes);
}
Action action = new Action.Builder(Icon.createWithResource("", icon),
@@ -9360,29 +9385,62 @@ public class Notification implements Parcelable
return action;
}
- private ArrayList<Action> makeActionsList(@NonNull StandardTemplateParams p) {
- final Action negativeAction = makeNegativeAction(p);
- final Action answerAction = makeAnswerAction(p);
+ private boolean isActionAddedByCallStyle(Action action) {
+ // This is an internal extra added by the style to these actions. If an app were to add
+ // this extra to the action themselves, the action would be dropped. :shrug:
+ return action != null && action.getExtras().getBoolean(KEY_ACTION_PRIORITY);
+ }
- ArrayList<Action> actions = new ArrayList<>(MAX_ACTION_BUTTONS);
- final Action lastAction;
- if (answerAction == null) {
- // If there's no answer action, put the hang up / decline action at the end
- lastAction = negativeAction;
- } else {
- // Otherwise put the answer action at the end, and put the decline action at start.
- actions.add(negativeAction);
- lastAction = answerAction;
- }
- // For consistency with the standard actions bar, contextual actions are ignored.
- for (Action action : mBuilder.getNonContextualActions()) {
- if (actions.size() >= MAX_ACTION_BUTTONS - 1) {
- break;
+ /**
+ * Gets the actions list for the call with the answer/decline/hangUp actions inserted in
+ * the correct place. This returns the correct result even if the system actions have
+ * already been added, and even if more actions were added since then.
+ * @hide
+ */
+ @NonNull
+ public ArrayList<Action> getActionsListWithSystemActions() {
+ // Define the system actions we expect to see
+ final Action negativeAction = makeNegativeAction();
+ final Action answerAction = makeAnswerAction();
+ // Sort the expected actions into the correct order:
+ // * If there's no answer action, put the hang up / decline action at the end
+ // * Otherwise put the answer action at the end, and put the decline action at start.
+ final Action firstAction = answerAction == null ? null : negativeAction;
+ final Action lastAction = answerAction == null ? negativeAction : answerAction;
+
+ // Start creating the result list.
+ int nonContextualActionSlotsRemaining = MAX_ACTION_BUTTONS;
+ ArrayList<Action> resultActions = new ArrayList<>(MAX_ACTION_BUTTONS);
+ if (firstAction != null) {
+ resultActions.add(firstAction);
+ --nonContextualActionSlotsRemaining;
+ }
+
+ // Copy actions into the new list, correcting system actions.
+ if (mBuilder.mActions != null) {
+ for (Notification.Action action : mBuilder.mActions) {
+ if (action.isContextual()) {
+ // Always include all contextual actions
+ resultActions.add(action);
+ } else if (isActionAddedByCallStyle(action)) {
+ // Drop any old versions of system actions
+ } else {
+ // Copy non-contextual actions; decrement the remaining action slots.
+ resultActions.add(action);
+ --nonContextualActionSlotsRemaining;
+ }
+ // If there's exactly one action slot left, fill it with the lastAction.
+ if (nonContextualActionSlotsRemaining == 1) {
+ resultActions.add(lastAction);
+ --nonContextualActionSlotsRemaining;
+ }
}
- actions.add(action);
}
- actions.add(lastAction);
- return actions;
+ // If there are any action slots left, the lastAction still needs to be added.
+ if (nonContextualActionSlotsRemaining >= 1) {
+ resultActions.add(lastAction);
+ }
+ return resultActions;
}
private RemoteViews makeCallLayout() {
@@ -9395,19 +9453,15 @@ public class Notification implements Parcelable
// Bind standard template
StandardTemplateParams p = mBuilder.mParams.reset()
.viewType(StandardTemplateParams.VIEW_TYPE_BIG)
- .allowActionIcons(true)
+ .callStyleActions(true)
.allowTextWithProgress(true)
.hideLargeIcon(true)
.text(text)
.summaryText(mBuilder.processLegacyText(mVerificationText));
- RemoteViews contentView = mBuilder.applyStandardTemplate(
+ mBuilder.mActions = getActionsListWithSystemActions();
+ RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
mBuilder.getCallLayoutResource(), p, null /* result */);
- // Bind actions.
- mBuilder.resetStandardTemplateWithActions(contentView);
- mBuilder.bindSnoozeAction(contentView, p);
- bindCallActions(contentView, p);
-
// Bind some extra conversation-specific header fields.
mBuilder.setTextViewColorPrimary(contentView, R.id.conversation_text, p);
mBuilder.setTextViewColorSecondary(contentView, R.id.app_name_divider, p);
@@ -9427,41 +9481,6 @@ public class Notification implements Parcelable
return contentView;
}
- private void bindCallActions(RemoteViews view, StandardTemplateParams p) {
- view.setViewVisibility(R.id.actions_container, View.VISIBLE);
- view.setViewVisibility(R.id.actions, View.VISIBLE);
- view.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
- RemoteViews.MARGIN_BOTTOM, 0);
-
- // Clear view padding to allow buttons to start on the left edge.
- // This must be done before 'setEmphasizedMode' which sets top/bottom margins.
- view.setViewPadding(R.id.actions, 0, 0, 0, 0);
- // Add an optional indent that will make buttons start at the correct column when
- // there is enough space to do so (and fall back to the left edge if not).
- view.setInt(R.id.actions, "setCollapsibleIndentDimen",
- R.dimen.call_notification_collapsible_indent);
-
- // Emphasize so that buttons have borders or colored backgrounds
- boolean emphasizedMode = true;
- view.setBoolean(R.id.actions, "setEmphasizedMode", emphasizedMode);
- // Use "wrap_content" (unlike normal emphasized mode) and allow prioritizing the
- // required actions (Answer, Decline, and Hang Up).
- view.setBoolean(R.id.actions, "setPrioritizedWrapMode", true);
-
- // Create the buttons for the generated actions list.
- int i = 0;
- for (Action action : makeActionsList(p)) {
- final RemoteViews button = mBuilder.generateActionButton(action, emphasizedMode, p);
- if (i > 0) {
- // Clear start margin from non-first buttons to reduce the gap between buttons.
- // (8dp remaining gap is from all buttons' standard 4dp inset).
- button.setViewLayoutMarginDimen(R.id.action0, RemoteViews.MARGIN_START, 0);
- }
- view.addView(R.id.actions, button);
- ++i;
- }
- }
-
private void bindCallerVerification(RemoteViews contentView, StandardTemplateParams p) {
String iconContentDescription = null;
boolean showDivider = true;
@@ -12083,6 +12102,21 @@ public class Notification implements Parcelable
if (viewId == R.id.notification_header) {
views.setFloat(R.id.notification_header,
"setTopLineExtraMarginEndDp", marginEndDp);
+ } else if (viewId == R.id.text || viewId == R.id.big_text) {
+ if (mValueIfGone != 0) {
+ throw new RuntimeException("Programming error: `text` and `big_text` use "
+ + "ImageFloatingTextView which can either show a margin or not; "
+ + "thus mValueIfGone must be 0, but it was " + mValueIfGone);
+ }
+ // Note that the caller must set "setNumIndentLines" to a positive int in order
+ // for this margin to do anything at all.
+ views.setFloat(viewId, "setImageEndMarginDp", mValueIfVisible);
+ views.setBoolean(viewId, "setHasImage", mRightIconVisible);
+ // Apply just the *extra* margin as the view layout margin; this will be
+ // unchanged depending on the visibility of the image, but it means that the
+ // extra margin applies to *every* line of text instead of just indented lines.
+ views.setViewLayoutMargin(viewId, RemoteViews.MARGIN_END,
+ extraMarginDp, TypedValue.COMPLEX_UNIT_DIP);
} else {
views.setViewLayoutMargin(viewId, RemoteViews.MARGIN_END,
marginEndDp, TypedValue.COMPLEX_UNIT_DIP);
@@ -12119,8 +12153,9 @@ public class Notification implements Parcelable
boolean mHideProgress;
boolean mHideSnoozeButton;
boolean mPromotePicture;
- boolean mAllowActionIcons;
+ boolean mCallStyleActions;
boolean mAllowTextWithProgress;
+ int mTextViewId;
CharSequence title;
CharSequence text;
CharSequence headerTextSecondary;
@@ -12138,8 +12173,9 @@ public class Notification implements Parcelable
mHideProgress = false;
mHideSnoozeButton = false;
mPromotePicture = false;
- mAllowActionIcons = false;
+ mCallStyleActions = false;
mAllowTextWithProgress = false;
+ mTextViewId = R.id.text;
title = null;
text = null;
summaryText = null;
@@ -12179,8 +12215,8 @@ public class Notification implements Parcelable
return this;
}
- final StandardTemplateParams allowActionIcons(boolean allowActionIcons) {
- this.mAllowActionIcons = allowActionIcons;
+ final StandardTemplateParams callStyleActions(boolean callStyleActions) {
+ this.mCallStyleActions = callStyleActions;
return this;
}
@@ -12199,6 +12235,11 @@ public class Notification implements Parcelable
return this;
}
+ public StandardTemplateParams textViewId(int textViewId) {
+ mTextViewId = textViewId;
+ return this;
+ }
+
final StandardTemplateParams title(CharSequence title) {
this.title = title;
return this;
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index bd99348b235a..8e53b5ba1c9f 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -650,7 +650,6 @@ public class WallpaperManager {
*/
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
public Drawable getDrawable() {
- assertUiContext("getDrawable");
final ColorManagementProxy cmProxy = getColorManagementProxy();
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM, cmProxy);
if (bm != null) {
@@ -718,7 +717,6 @@ public class WallpaperManager {
*/
public Drawable getBuiltInDrawable(int outWidth, int outHeight, boolean scaleToFit,
float horizontalAlignment, float verticalAlignment, @SetWallpaperFlags int which) {
- assertUiContext("getBuiltInDrawable");
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
@@ -884,7 +882,6 @@ public class WallpaperManager {
* null pointer if these is none.
*/
public Drawable peekDrawable() {
- assertUiContext("peekDrawable");
final ColorManagementProxy cmProxy = getColorManagementProxy();
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM, cmProxy);
if (bm != null) {
@@ -927,7 +924,6 @@ public class WallpaperManager {
*/
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
public Drawable peekFastDrawable() {
- assertUiContext("peekFastDrawable");
final ColorManagementProxy cmProxy = getColorManagementProxy();
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM, cmProxy);
if (bm != null) {
@@ -1084,6 +1080,7 @@ public class WallpaperManager {
return getWallpaperColors(which, mContext.getUserId());
}
+ // TODO(b/181083333): add multiple root display area support on this API.
/**
* Get the primary colors of the wallpaper configured in the given user.
* @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or
@@ -1094,7 +1091,7 @@ public class WallpaperManager {
*/
@UnsupportedAppUsage
public @Nullable WallpaperColors getWallpaperColors(int which, int userId) {
- assertUiContext("getWallpaperColors");
+ StrictMode.assertUiContext(mContext, "getWallpaperColors");
return sGlobals.getWallpaperColors(which, userId, mContext.getDisplayId());
}
@@ -1333,7 +1330,6 @@ public class WallpaperManager {
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
public int setResource(@RawRes int resid, @SetWallpaperFlags int which)
throws IOException {
- assertUiContext("setResource");
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
@@ -1637,6 +1633,7 @@ public class WallpaperManager {
}
}
+ // TODO(b/181083333): add multiple root display area support on this API.
/**
* Returns the desired minimum width for the wallpaper. Callers of
* {@link #setBitmap(android.graphics.Bitmap)} or
@@ -1654,7 +1651,7 @@ public class WallpaperManager {
* @see #getDesiredMinimumHeight()
*/
public int getDesiredMinimumWidth() {
- assertUiContext("getDesiredMinimumWidth");
+ StrictMode.assertUiContext(mContext, "getDesiredMinimumWidth");
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
@@ -1666,6 +1663,7 @@ public class WallpaperManager {
}
}
+ // TODO(b/181083333): add multiple root display area support on this API.
/**
* Returns the desired minimum height for the wallpaper. Callers of
* {@link #setBitmap(android.graphics.Bitmap)} or
@@ -1683,7 +1681,7 @@ public class WallpaperManager {
* @see #getDesiredMinimumWidth()
*/
public int getDesiredMinimumHeight() {
- assertUiContext("getDesiredMinimumHeight");
+ StrictMode.assertUiContext(mContext, "getDesiredMinimumHeight");
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
@@ -1695,6 +1693,7 @@ public class WallpaperManager {
}
}
+ // TODO(b/181083333): add multiple root display area support on this API.
/**
* For use only by the current home application, to specify the size of
* wallpaper it would like to use. This allows such applications to have
@@ -1714,7 +1713,7 @@ public class WallpaperManager {
* @param minimumHeight Desired minimum height
*/
public void suggestDesiredDimensions(int minimumWidth, int minimumHeight) {
- assertUiContext("suggestDesiredDimensions");
+ StrictMode.assertUiContext(mContext, "suggestDesiredDimensions");
try {
/**
* The framework makes no attempt to limit the window size
@@ -1757,6 +1756,7 @@ public class WallpaperManager {
}
}
+ // TODO(b/181083333): add multiple root display area support on this API.
/**
* Specify extra padding that the wallpaper should have outside of the display.
* That is, the given padding supplies additional pixels the wallpaper should extend
@@ -1770,7 +1770,7 @@ public class WallpaperManager {
*/
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER_HINTS)
public void setDisplayPadding(Rect padding) {
- assertUiContext("setDisplayPadding");
+ StrictMode.assertUiContext(mContext, "setDisplayPadding");
try {
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
@@ -2023,7 +2023,6 @@ public class WallpaperManager {
*/
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
public void clear() throws IOException {
- assertUiContext("clear");
setStream(openDefaultWallpaper(mContext, FLAG_SYSTEM), null, false);
}
@@ -2176,10 +2175,6 @@ public class WallpaperManager {
return mCmProxy;
}
- private void assertUiContext(final String methodName) {
- StrictMode.assertUiContext(mContext, methodName);
- }
-
/**
* A hidden class to help {@link Globals#getCurrentWallpaperLocked} handle color management.
* @hide
diff --git a/core/java/android/app/WindowTokenClient.java b/core/java/android/app/WindowTokenClient.java
index 29792ac47a36..2298e84d755e 100644
--- a/core/java/android/app/WindowTokenClient.java
+++ b/core/java/android/app/WindowTokenClient.java
@@ -85,8 +85,10 @@ public class WindowTokenClient extends IWindowToken.Stub {
context.destroy();
mContextRef.clear();
}
- // If a secondary display is detached, release all views attached to this token.
- WindowManagerGlobal.getInstance().closeAll(this, mContextRef.getClass().getName(),
- "WindowContext");
+ ActivityThread.currentActivityThread().getHandler().post(() -> {
+ // If the tracked window token is detached, release all views attached to this token.
+ WindowManagerGlobal.getInstance().closeAll(WindowTokenClient.this,
+ "#onWindowTokenRemoved()", "WindowTokenClient");
+ });
}
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ccf41e5f3063..30fb858b4bbc 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -987,7 +987,8 @@ public class DevicePolicyManager {
* The default for this extra is {@code false} - by default, the admin of a fully-managed
* device has the ability to grant sensors-related permissions.
*
- * <p>Use with {@link #ACTION_PROVISION_MANAGED_DEVICE} only.
+ * <p>Use only for device owner provisioning.
+ * @see #ACTION_GET_PROVISIONING_MODE
*/
public static final String EXTRA_PROVISIONING_PERMISSION_GRANT_OPT_OUT =
"android.app.extra.PROVISIONING_PERMISSION_GRANT_OPT_OUT";
@@ -11838,7 +11839,7 @@ public class DevicePolicyManager {
/**
* @hide
- * Force update user setup completed status. This API has no effect on user build.
+ * Force update user setup completed status.
* @throws {@link SecurityException} if the caller has no
* {@code android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS} or the caller is
* not {@link UserHandle#SYSTEM_USER}
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index d79fac58cf12..8fd0de7dbb39 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -849,6 +849,7 @@ public class AppWidgetHostView extends FrameLayout {
public void setColorResources(@NonNull SparseIntArray colorMapping) {
mColorResources = RemoteViews.ColorResources.create(mContext, colorMapping);
mLayoutId = -1;
+ mViewMode = VIEW_MODE_NOINIT;
reapplyLastRemoteViews();
}
@@ -863,6 +864,7 @@ public class AppWidgetHostView extends FrameLayout {
if (mColorResources != null) {
mColorResources = null;
mLayoutId = -1;
+ mViewMode = VIEW_MODE_NOINIT;
reapplyLastRemoteViews();
}
}
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 53aaae0470e2..16413e1a1db6 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -139,7 +139,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @UnsupportedAppUsage(trackingBug = 181103983)
public static final String ACTION_CODEC_CONFIG_CHANGED =
"android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
@@ -684,7 +684,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @return the current codec status
* @hide
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @UnsupportedAppUsage(trackingBug = 181103983)
@Nullable
@RequiresPermission(Manifest.permission.BLUETOOTH)
public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
@@ -713,7 +713,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* @param codecConfig the codec configuration preference
* @hide
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @UnsupportedAppUsage(trackingBug = 181103983)
@RequiresPermission(Manifest.permission.BLUETOOTH)
public void setCodecConfigPreference(@NonNull BluetoothDevice device,
@NonNull BluetoothCodecConfig codecConfig) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index df5c58c2634f..0509e3f77c1f 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4837,6 +4837,15 @@ public abstract class Context {
public static final String POWER_WHITELIST_MANAGER = "power_whitelist";
/**
+ * System service name for the PowerExemptionManager.
+ *
+ * @see #getSystemService(String)
+ * @hide
+ */
+ @SystemApi
+ public static final String POWER_EXEMPTION_SERVICE = "power_exemption";
+
+ /**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.app.admin.DevicePolicyManager} for working with global
* device policy management.
diff --git a/core/java/android/content/ContextParams.java b/core/java/android/content/ContextParams.java
index 17ec2a847d4f..fad905bfac13 100644
--- a/core/java/android/content/ContextParams.java
+++ b/core/java/android/content/ContextParams.java
@@ -120,14 +120,45 @@ public final class ContextParams {
private Set<String> mRenouncedPermissions;
/**
+ * Create a new builder.
+ * <p>
+ * This is valuable when you are interested in having explicit control
+ * over every sub-parameter, and don't want to inherit any values from
+ * an existing Context.
+ * <p>
+ * Developers should strongly consider using
+ * {@link #Builder(ContextParams)} instead of this constructor, since
+ * that will will automatically inherit any new sub-parameters added in
+ * future platform releases.
+ */
+ public Builder() {
+ }
+
+ /**
+ * Create a new builder that inherits all sub-parameters by default.
+ * <p>
+ * This is valuable when you are only interested in overriding specific
+ * sub-parameters, and want to preserve all other parameters. Setting a
+ * specific sub-parameter on the returned builder will override any
+ * inherited value.
+ */
+ public Builder(@NonNull ContextParams params) {
+ Objects.requireNonNull(params);
+ mAttributionTag = params.mAttributionTag;
+ mReceiverPackage = params.mReceiverPackage;
+ mReceiverAttributionTag = params.mReceiverAttributionTag;
+ mRenouncedPermissions = params.mRenouncedPermissions;
+ }
+
+ /**
* Sets an attribution tag against which to track permission accesses.
*
* @param attributionTag The attribution tag.
* @return This builder.
*/
@NonNull
- public Builder setAttributionTag(@NonNull String attributionTag) {
- mAttributionTag = Objects.requireNonNull(attributionTag);
+ public Builder setAttributionTag(@Nullable String attributionTag) {
+ mAttributionTag = attributionTag;
return this;
}
@@ -140,9 +171,9 @@ public final class ContextParams {
* @return This builder.
*/
@NonNull
- public Builder setReceiverPackage(@NonNull String packageName,
+ public Builder setReceiverPackage(@Nullable String packageName,
@Nullable String attributionTag) {
- mReceiverPackage = Objects.requireNonNull(packageName);
+ mReceiverPackage = packageName;
mReceiverAttributionTag = attributionTag;
return this;
}
@@ -169,8 +200,13 @@ public final class ContextParams {
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.RENOUNCE_PERMISSIONS)
- public @NonNull Builder setRenouncedPermissions(@NonNull Set<String> renouncedPermissions) {
- mRenouncedPermissions = Collections.unmodifiableSet(renouncedPermissions);
+ public @NonNull Builder setRenouncedPermissions(
+ @Nullable Set<String> renouncedPermissions) {
+ if (renouncedPermissions != null) {
+ mRenouncedPermissions = Collections.unmodifiableSet(renouncedPermissions);
+ } else {
+ mRenouncedPermissions = null;
+ }
return this;
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d352b273f882..de17fda82d71 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6761,6 +6761,12 @@ public class Intent implements Parcelable, Cloneable {
* #putExtras(Bundle)} when the provided Bundle has not been unparceled.
*/
private static final int LOCAL_FLAG_UNFILTERED_EXTRAS = 1 << 3;
+
+ /**
+ * Local flag indicating this instance was created from a {@link Uri}.
+ */
+ private static final int LOCAL_FLAG_FROM_URI = 1 << 4;
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// toUri() and parseUri() options.
@@ -7173,6 +7179,16 @@ public class Intent implements Parcelable, Cloneable {
* @see #toUri
*/
public static Intent parseUri(String uri, @UriFlags int flags) throws URISyntaxException {
+ Intent intent = parseUriInternal(uri, flags);
+ intent.mLocalFlags |= LOCAL_FLAG_FROM_URI;
+ return intent;
+ }
+
+ /**
+ * @see #parseUri(String, int)
+ */
+ private static Intent parseUriInternal(String uri, @UriFlags int flags)
+ throws URISyntaxException {
int i = 0;
try {
final boolean androidApp = uri.startsWith("android-app:");
@@ -7392,7 +7408,9 @@ public class Intent implements Parcelable, Cloneable {
}
public static Intent getIntentOld(String uri) throws URISyntaxException {
- return getIntentOld(uri, 0);
+ Intent intent = getIntentOld(uri, 0);
+ intent.mLocalFlags |= LOCAL_FLAG_FROM_URI;
+ return intent;
}
private static Intent getIntentOld(String uri, int flags) throws URISyntaxException {
@@ -11353,6 +11371,13 @@ public class Intent implements Parcelable, Cloneable {
StrictMode.onUnsafeIntentLaunch(this);
} else if ((mLocalFlags & LOCAL_FLAG_UNFILTERED_EXTRAS) != 0) {
StrictMode.onUnsafeIntentLaunch(this);
+ } else if ((mLocalFlags & LOCAL_FLAG_FROM_URI) != 0
+ && !(mCategories != null && mCategories.contains(CATEGORY_BROWSABLE)
+ && mComponent == null)) {
+ // Since the docs for #URI_ALLOW_UNSAFE recommend setting the category to browsable
+ // for an implicit Intent parsed from a URI a violation should be reported if these
+ // conditions are not met.
+ StrictMode.onUnsafeIntentLaunch(this);
}
}
}
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 1660c9d23002..5a17753bf9ad 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -892,22 +892,42 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
*/
@ChangeId
@Disabled
- public static final long FORCE_RESIZE_APP = 174042936L; // number refers to buganizer id
+ @TestApi
+ public static final long FORCE_RESIZE_APP = 174042936L; // buganizer id
+
+ /**
+ * This change id forces the packages it is applied to to be non-resizable.
+ * @hide
+ */
+ @ChangeId
+ @Disabled
+ @TestApi
+ public static final long FORCE_NON_RESIZE_APP = 181136395L; // buganizer id
/**
* Return value for {@link #supportsSizeChanges()} indicating that this activity does not
- * support size changes.
+ * support size changes due to the android.supports_size_changes metadata flag either being
+ * unset or set to {@code false} on application or activity level.
+ *
* @hide
*/
- public static final int SIZE_CHANGES_UNSUPPORTED = 0;
+ public static final int SIZE_CHANGES_UNSUPPORTED_METADATA = 0;
+
+ /**
+ * Return value for {@link #supportsSizeChanges()} indicating that this activity has been
+ * overridden to not support size changes through the compat framework change id
+ * {@link #FORCE_NON_RESIZE_APP}.
+ * @hide
+ */
+ public static final int SIZE_CHANGES_UNSUPPORTED_OVERRIDE = 1;
/**
* Return value for {@link #supportsSizeChanges()} indicating that this activity supports size
- * changes due to the android.supports_size_changes metadata flag being set either on
- * application or on activity level.
+ * changes due to the android.supports_size_changes metadata flag being set to {@code true}
+ * either on application or activity level.
* @hide
*/
- public static final int SIZE_CHANGES_SUPPORTED_METADATA = 1;
+ public static final int SIZE_CHANGES_SUPPORTED_METADATA = 2;
/**
* Return value for {@link #supportsSizeChanges()} indicating that this activity has been
@@ -915,11 +935,12 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
* {@link #FORCE_RESIZE_APP}.
* @hide
*/
- public static final int SIZE_CHANGES_SUPPORTED_OVERRIDE = 2;
+ public static final int SIZE_CHANGES_SUPPORTED_OVERRIDE = 3;
/** @hide */
@IntDef(prefix = { "SIZE_CHANGES_" }, value = {
- SIZE_CHANGES_UNSUPPORTED,
+ SIZE_CHANGES_UNSUPPORTED_METADATA,
+ SIZE_CHANGES_UNSUPPORTED_OVERRIDE,
SIZE_CHANGES_SUPPORTED_METADATA,
SIZE_CHANGES_SUPPORTED_OVERRIDE,
})
@@ -1213,6 +1234,12 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
*/
@SizeChangesSupportMode
public int supportsSizeChanges() {
+ if (CompatChanges.isChangeEnabled(FORCE_NON_RESIZE_APP,
+ applicationInfo.packageName,
+ UserHandle.getUserHandleForUid(applicationInfo.uid))) {
+ return SIZE_CHANGES_UNSUPPORTED_OVERRIDE;
+ }
+
if (supportsSizeChanges) {
return SIZE_CHANGES_SUPPORTED_METADATA;
}
@@ -1223,7 +1250,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
return SIZE_CHANGES_SUPPORTED_OVERRIDE;
}
- return SIZE_CHANGES_UNSUPPORTED;
+ return SIZE_CHANGES_UNSUPPORTED_METADATA;
}
/** @hide */
@@ -1269,8 +1296,10 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
/** @hide */
public static String sizeChangesSupportModeToString(@SizeChangesSupportMode int mode) {
switch (mode) {
- case SIZE_CHANGES_UNSUPPORTED:
- return "SIZE_CHANGES_UNSUPPORTED";
+ case SIZE_CHANGES_UNSUPPORTED_METADATA:
+ return "SIZE_CHANGES_UNSUPPORTED_METADATA";
+ case SIZE_CHANGES_UNSUPPORTED_OVERRIDE:
+ return "SIZE_CHANGES_UNSUPPORTED_OVERRIDE";
case SIZE_CHANGES_SUPPORTED_METADATA:
return "SIZE_CHANGES_SUPPORTED_METADATA";
case SIZE_CHANGES_SUPPORTED_OVERRIDE:
diff --git a/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java b/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java
index 25758e9d9a61..8c7695ad5a5a 100644
--- a/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java
+++ b/core/java/android/graphics/fonts/FontFamilyUpdateRequest.java
@@ -72,6 +72,45 @@ public final class FontFamilyUpdateRequest {
* A font family definition.
*/
public static final class FontFamily {
+
+ /**
+ * Builds a {@link FontFamily}.
+ */
+ public static final class Builder {
+ @NonNull private final String mName;
+ @NonNull private final List<Font> mFonts;
+
+ /**
+ * Constructs a {@link FontFamily.Builder}.
+ */
+ public Builder(@NonNull String name, @NonNull List<Font> fonts) {
+ Objects.requireNonNull(name);
+ Preconditions.checkStringNotEmpty(name);
+ Objects.requireNonNull(fonts);
+ Preconditions.checkCollectionElementsNotNull(fonts, "fonts");
+ Preconditions.checkCollectionNotEmpty(fonts, "fonts");
+ mName = name;
+ mFonts = new ArrayList<>(fonts);
+ }
+
+ /**
+ * Adds a {@link Font} to the builder.
+ *
+ * @return This builder object.
+ */
+ public @NonNull Builder addFont(@NonNull Font font) {
+ mFonts.add(font);
+ return this;
+ }
+
+ /**
+ * Builds a {@link FontFamily}.
+ */
+ public @NonNull FontFamily build() {
+ return new FontFamily(mName, mFonts);
+ }
+ }
+
@NonNull
private final String mName;
@NonNull
@@ -90,12 +129,7 @@ public final class FontFamilyUpdateRequest {
* @see android.graphics.Typeface#create(String, int)
* @see Font
*/
- public FontFamily(@NonNull String name, @NonNull List<Font> fonts) {
- Objects.requireNonNull(name);
- Preconditions.checkStringNotEmpty(name);
- Objects.requireNonNull(fonts);
- Preconditions.checkCollectionElementsNotNull(fonts, "fonts");
- Preconditions.checkCollectionNotEmpty(fonts, "fonts");
+ private FontFamily(@NonNull String name, @NonNull List<Font> fonts) {
mName = name;
mFonts = fonts;
}
diff --git a/core/java/android/hardware/display/AmbientDisplayConfiguration.java b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
index 7dc1eaabdc9c..93e5a0ea18f3 100644
--- a/core/java/android/hardware/display/AmbientDisplayConfiguration.java
+++ b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
@@ -52,7 +52,8 @@ public class AmbientDisplayConfiguration {
|| wakeDisplayGestureEnabled(user)
|| pickupGestureEnabled(user)
|| tapGestureEnabled(user)
- || doubleTapGestureEnabled(user);
+ || doubleTapGestureEnabled(user)
+ || quickPickupSensorEnabled(user);
}
/** {@hide} */
@@ -100,6 +101,13 @@ public class AmbientDisplayConfiguration {
}
/** {@hide} */
+ public boolean quickPickupSensorEnabled(int user) {
+ return boolSettingDefaultOff(Settings.Secure.DOZE_QUICK_PICKUP_GESTURE, user)
+ && !TextUtils.isEmpty(quickPickupSensorType())
+ && !alwaysOnEnabled(user);
+ }
+
+ /** {@hide} */
public boolean wakeScreenGestureAvailable() {
return mContext.getResources()
.getBoolean(R.bool.config_dozeWakeLockScreenSensorAvailable);
@@ -143,6 +151,11 @@ public class AmbientDisplayConfiguration {
}
/** {@hide} */
+ public String quickPickupSensorType() {
+ return mContext.getResources().getString(R.string.config_quickPickupSensorType);
+ }
+
+ /** {@hide} */
public boolean pulseOnLongPressEnabled(int user) {
return pulseOnLongPressAvailable() && boolSettingDefaultOff(
Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, user);
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index bbf421da6b48..2c3e7f18a3ab 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -68,6 +68,9 @@ public final class DisplayManager {
* {@link #EXTRA_WIFI_DISPLAY_STATUS} extra.
* </p><p>
* This broadcast is only sent to registered receivers and can only be sent by the system.
+ * </p><p>
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission is required to
+ * receive this broadcast.
* </p>
* @hide
*/
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 0256b7bc6de0..8dc8d5b60943 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -475,28 +475,11 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
* @hide
*/
@RequiresPermission(MANAGE_BIOMETRIC)
- public void revokeChallenge() {
- final List<FaceSensorPropertiesInternal> faceSensorProperties =
- getSensorPropertiesInternal();
- if (faceSensorProperties.isEmpty()) {
- Slog.e(TAG, "No sensors during revokeChallenge");
- }
- revokeChallenge(faceSensorProperties.get(0).sensorId);
- }
-
- /**
- * Invalidates the current challenge.
- *
- * TODO(b/171335732): should take userId and challenge
- *
- * @hide
- */
- @RequiresPermission(MANAGE_BIOMETRIC)
- public void revokeChallenge(int sensorId) {
+ public void revokeChallenge(int sensorId, int userId, long challenge) {
if (mService != null) {
try {
- mService.revokeChallenge(mToken, sensorId, 0 /* userId */,
- mContext.getOpPackageName(), 0 /* challenge */);
+ mService.revokeChallenge(mToken, sensorId, userId,
+ mContext.getOpPackageName(), challenge);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index fc795d8a0488..1c33b26dfa18 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -686,17 +686,6 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
}
/**
- * Revokes the current challenge.
- * @hide
- */
- @RequiresPermission(MANAGE_FINGERPRINT)
- public void revokeChallenge(int userId) {
- // On HALs with only single in-flight challenge such as IBiometricsFingerprint@2.1,
- // this parameter is ignored.
- revokeChallenge(userId, 0L);
- }
-
- /**
* Revokes the specified challenge.
* @hide
*/
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index b90c72832d36..ad71f15f6e26 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -461,6 +461,7 @@ public final class HdmiControlManager {
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
* @hide
*/
+ @SystemApi
public static final int VOLUME_CONTROL_ENABLED = 1;
/**
* HDMI CEC disabled.
@@ -468,6 +469,7 @@ public final class HdmiControlManager {
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
* @hide
*/
+ @SystemApi
public static final int VOLUME_CONTROL_DISABLED = 0;
/**
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
@@ -486,12 +488,14 @@ public final class HdmiControlManager {
*
* @hide
*/
+ @SystemApi
public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED = 1;
/**
* TV Wake on One Touch Play disabled.
*
* @hide
*/
+ @SystemApi
public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_DISABLED = 0;
/**
* @hide
@@ -509,12 +513,14 @@ public final class HdmiControlManager {
*
* @hide
*/
+ @SystemApi
public static final int TV_SEND_STANDBY_ON_SLEEP_ENABLED = 1;
/**
* Not sending &lt;Standby&gt; on sleep.
*
* @hide
*/
+ @SystemApi
public static final int TV_SEND_STANDBY_ON_SLEEP_DISABLED = 0;
/**
* @hide
@@ -759,6 +765,7 @@ public final class HdmiControlManager {
* @hide
* @see android.hardware.hdmi.HdmiControlManager#setHdmiCecVolumeControlEnabled(int)
*/
+ @SystemApi
public static final String CEC_SETTING_NAME_VOLUME_CONTROL_MODE =
"volume_control_enabled";
/**
@@ -767,6 +774,7 @@ public final class HdmiControlManager {
*
* @hide
*/
+ @SystemApi
public static final String CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY =
"tv_wake_on_one_touch_play";
/**
@@ -775,6 +783,7 @@ public final class HdmiControlManager {
*
* @hide
*/
+ @SystemApi
public static final String CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP =
"tv_send_standby_on_sleep";
/**
@@ -1259,6 +1268,7 @@ public final class HdmiControlManager {
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
public void setHdmiCecVolumeControlEnabled(
@VolumeControl int hdmiCecVolumeControlEnabled) {
@@ -1274,6 +1284,7 @@ public final class HdmiControlManager {
* Returns whether volume changes via HDMI CEC are enabled.
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
@VolumeControl
public int getHdmiCecVolumeControlEnabled() {
@@ -2155,6 +2166,7 @@ public final class HdmiControlManager {
*
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
public void setTvWakeOnOneTouchPlay(@NonNull @TvWakeOnOneTouchPlay int value) {
if (mService == null) {
@@ -2176,6 +2188,7 @@ public final class HdmiControlManager {
*
* @hide
*/
+ @SystemApi
@NonNull
@TvWakeOnOneTouchPlay
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
@@ -2199,6 +2212,7 @@ public final class HdmiControlManager {
*
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
public void setTvSendStandbyOnSleep(@NonNull @TvSendStandbyOnSleep int value) {
if (mService == null) {
@@ -2220,6 +2234,7 @@ public final class HdmiControlManager {
*
* @hide
*/
+ @SystemApi
@NonNull
@TvSendStandbyOnSleep
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index a65f36b14f13..eaa8bd403e24 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -60,7 +60,8 @@ public final class ContextHubManager {
private static final String TAG = "ContextHubManager";
/**
- * An extra of type int describing the client's authorization state.
+ * An extra containing an int from {@link AuthorizationState} describing the client's
+ * authorization state.
*/
public static final String EXTRA_CLIENT_AUTHORIZATION_STATE =
"android.hardware.location.extra.CLIENT_AUTHORIZATION_STATE";
@@ -115,11 +116,9 @@ public final class ContextHubManager {
/**
* Indicates the {@link ContextHubClient} will soon lose its authorization to communicate with a
- * nanoapp. The {@link ContextHubClient} must perform any cleanup with the nanoapp as soon as
- * possible.
- *
- * Note that the time between this state event and {@link AUTHORIZATION_DENIED} must be enough
- * for the {@link ContextHubClient} to send at least one message to the nanoapp.
+ * nanoapp. After receiving this state event, the {@link ContextHubClient} has one minute to
+ * perform any cleanup with the nanoapp such that the nanoapp is no longer performing work on
+ * behalf of the {@link ContextHubClient}.
*/
public static final int AUTHORIZATION_DENIED_GRACE_PERIOD = 1;
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index 5cfcd667632b..9198eb74d1f8 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -171,7 +171,7 @@ class IInputMethodWrapper extends IInputMethod.Stub
SomeArgs args = (SomeArgs) msg.obj;
try {
inputMethod.initializeInternal((IBinder) args.arg1, msg.arg1,
- (IInputMethodPrivilegedOperations) args.arg2);
+ (IInputMethodPrivilegedOperations) args.arg2, (int) args.arg3);
} finally {
args.recycle();
}
@@ -280,9 +280,10 @@ class IInputMethodWrapper extends IInputMethod.Stub
@BinderThread
@Override
public void initializeInternal(IBinder token, int displayId,
- IInputMethodPrivilegedOperations privOps) {
+ IInputMethodPrivilegedOperations privOps, int configChanges) {
mCaller.executeOrSendMessage(
- mCaller.obtainMessageIOO(DO_INITIALIZE_INTERNAL, displayId, token, privOps));
+ mCaller.obtainMessageIOOO(DO_INITIALIZE_INTERNAL, displayId, token, privOps,
+ configChanges));
}
@BinderThread
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 7e2be01feb01..40a0fc4e8339 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -70,6 +70,7 @@ import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -131,6 +132,7 @@ import android.widget.TextView;
import android.window.WindowMetricsHelper;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.IInputContentUriToken;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
@@ -513,6 +515,8 @@ public class InputMethodService extends AbstractInputMethodService {
private boolean mIsAutomotive;
private Handler mHandler;
private boolean mImeSurfaceScheduledForRemoval;
+ private Configuration mLastKnownConfig;
+ private int mHandledConfigChanges;
/**
* An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput}
@@ -588,12 +592,13 @@ public class InputMethodService extends AbstractInputMethodService {
@MainThread
@Override
public final void initializeInternal(@NonNull IBinder token, int displayId,
- IInputMethodPrivilegedOperations privilegedOperations) {
+ IInputMethodPrivilegedOperations privilegedOperations, int configChanges) {
if (InputMethodPrivilegedOperationsRegistry.isRegistered(token)) {
Log.w(TAG, "The token has already registered, ignore this initialization.");
return;
}
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal");
+ mHandledConfigChanges = configChanges;
mPrivOps.set(privilegedOperations);
InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps);
updateInputMethodDisplay(displayId);
@@ -821,6 +826,9 @@ public class InputMethodService extends AbstractInputMethodService {
setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
}
final boolean isVisible = isInputViewShown();
+ if (isVisible && getResources() != null) {
+ mLastKnownConfig = new Configuration(getResources().getConfiguration());
+ }
final boolean visibilityChanged = isVisible != wasVisible;
if (resultReceiver != null) {
resultReceiver.send(visibilityChanged
@@ -1428,10 +1436,30 @@ public class InputMethodService extends AbstractInputMethodService {
* state: {@link #onStartInput} if input is active, and
* {@link #onCreateInputView} and {@link #onStartInputView} and related
* appropriate functions if the UI is displayed.
+ * <p>Starting with {@link Build.VERSION_CODES#S}, IMEs can opt into handling configuration
+ * changes themselves instead of being restarted with
+ * {@link android.R.styleable#InputMethod_configChanges}.
*/
@Override public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- resetStateForNewConfiguration();
+ if (shouldImeRestartForConfig(newConfig)) {
+ resetStateForNewConfiguration();
+ }
+ }
+
+ /**
+ * @return {@code true} if {@link InputMethodService} needs to restart to handle
+ * .{@link #onConfigurationChanged(Configuration)}
+ */
+ @VisibleForTesting
+ boolean shouldImeRestartForConfig(@NonNull Configuration newConfig) {
+ if (mLastKnownConfig == null) {
+ return true;
+ }
+ // If the new config is the same as the config this Service is already running with,
+ // then don't bother calling resetStateForNewConfiguration.
+ int unhandledDiff = (mLastKnownConfig.diffPublicOnly(newConfig) & ~mHandledConfigChanges);
+ return unhandledDiff != 0;
}
private void resetStateForNewConfiguration() {
@@ -3181,7 +3209,17 @@ public class InputMethodService extends AbstractInputMethodService {
requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS);
}
}
-
+
+ @VisibleForTesting
+ void setLastKnownConfig(@NonNull Configuration config) {
+ mLastKnownConfig = config;
+ }
+
+ @VisibleForTesting
+ void setHandledConfigChanges(int configChanges) {
+ mHandledConfigChanges = configChanges;
+ }
+
void startExtractingText(boolean inputChanged) {
final ExtractEditText eet = mExtractEditText;
if (eet != null && getCurrentInputStarted()
diff --git a/core/java/android/net/EthernetNetworkSpecifier.java b/core/java/android/net/EthernetNetworkSpecifier.java
new file mode 100644
index 000000000000..e1685887e806
--- /dev/null
+++ b/core/java/android/net/EthernetNetworkSpecifier.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * A {@link NetworkSpecifier} used to identify ethernet interfaces.
+ *
+ * @see EthernetManager
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class EthernetNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+
+ /**
+ * Name of the network interface.
+ */
+ @NonNull
+ private final String mInterfaceName;
+
+ public EthernetNetworkSpecifier(@NonNull String interfaceName) {
+ Preconditions.checkStringNotEmpty(interfaceName);
+ mInterfaceName = interfaceName;
+ }
+
+ // This may be null in the future to support specifiers based on data other than the interface
+ // name.
+ @Nullable
+ public String getInterfaceName() {
+ return mInterfaceName;
+ }
+
+ @Override
+ public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) {
+ return equals(other);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (!(o instanceof EthernetNetworkSpecifier)) return false;
+ return TextUtils.equals(mInterfaceName, ((EthernetNetworkSpecifier) o).mInterfaceName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(mInterfaceName);
+ }
+
+ @Override
+ public String toString() {
+ return "EthernetNetworkSpecifier (" + mInterfaceName + ")";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mInterfaceName);
+ }
+
+ public static final @NonNull Parcelable.Creator<EthernetNetworkSpecifier> CREATOR =
+ new Parcelable.Creator<EthernetNetworkSpecifier>() {
+ public EthernetNetworkSpecifier createFromParcel(Parcel in) {
+ return new EthernetNetworkSpecifier(in.readString());
+ }
+ public EthernetNetworkSpecifier[] newArray(int size) {
+ return new EthernetNetworkSpecifier[size];
+ }
+ };
+}
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index a5ece7b713c7..b037261f0bc2 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -179,21 +179,6 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
}
/**
- * Build a {@link NetworkIdentity} from the given {@link NetworkState} and
- * {@code subType}, assuming that any mobile networks are using the current IMSI.
- * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
- * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not.
- */
- // TODO: Delete this function after NetworkPolicyManagerService finishes the migration.
- public static NetworkIdentity buildNetworkIdentity(Context context,
- NetworkState state, boolean defaultNetwork, @NetworkType int subType) {
- final NetworkStateSnapshot snapshot = new NetworkStateSnapshot(state.network,
- state.networkCapabilities, state.linkProperties, state.subscriberId,
- state.legacyNetworkType);
- return buildNetworkIdentity(context, snapshot, defaultNetwork, subType);
- }
-
- /**
* Build a {@link NetworkIdentity} from the given {@link NetworkStateSnapshot} and
* {@code subType}, assuming that any mobile networks are using the current IMSI.
* The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index f472ed4381d1..77754d1256a7 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -16,12 +16,15 @@
package android.net;
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.content.ComponentName;
@@ -56,18 +59,21 @@ import java.util.List;
*/
public class VpnManager {
/** Type representing a lack of VPN @hide */
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_NONE = -1;
/**
* A VPN created by an app using the {@link VpnService} API.
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_SERVICE = 1;
/**
* A VPN created using a {@link VpnManager} API such as {@link #startProvisionedVpnProfile}.
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_PLATFORM = 2;
/**
@@ -76,6 +82,7 @@ public class VpnManager {
* @hide
*/
@Deprecated
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int TYPE_VPN_LEGACY = 3;
/**
diff --git a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
index de086f63b14d..22d7faf2fe18 100644
--- a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
+++ b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
@@ -19,11 +19,13 @@ package android.net.vcn;
import static android.net.vcn.VcnControlPlaneConfig.CONFIG_TYPE_IKE;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.TunnelModeChildSessionParams;
+import android.net.vcn.persistablebundleutils.IkeSessionParamsUtils;
+import android.net.vcn.persistablebundleutils.TunnelModeChildSessionParamsUtils;
import android.os.PersistableBundle;
import android.util.ArraySet;
+import android.util.Log;
import java.util.Objects;
@@ -38,14 +40,11 @@ import java.util.Objects;
public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
private static final String TAG = VcnControlPlaneIkeConfig.class.getSimpleName();
- // STOPSHIP: b/163604823 Make mIkeParams and mChildParams @NonNull when it is supported to
- // construct mIkeParams and mChildParams from PersistableBundles.
-
private static final String IKE_PARAMS_KEY = "mIkeParams";
- @Nullable private final IkeSessionParams mIkeParams;
+ @NonNull private final IkeSessionParams mIkeParams;
private static final String CHILD_PARAMS_KEY = "mChildParams";
- @Nullable private final TunnelModeChildSessionParams mChildParams;
+ @NonNull private final TunnelModeChildSessionParams mChildParams;
private static final ArraySet<String> BUNDLE_KEY_SET = new ArraySet<>();
@@ -80,11 +79,19 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
final PersistableBundle ikeParamsBundle = in.getPersistableBundle(IKE_PARAMS_KEY);
final PersistableBundle childParamsBundle = in.getPersistableBundle(CHILD_PARAMS_KEY);
- // STOPSHIP: b/163604823 Support constructing mIkeParams and mChildParams from
- // PersistableBundles.
+ Objects.requireNonNull(ikeParamsBundle, "IKE Session Params was null");
+ Objects.requireNonNull(childParamsBundle, "Child Session Params was null");
+
+ mIkeParams = IkeSessionParamsUtils.fromPersistableBundle(ikeParamsBundle);
+ mChildParams = TunnelModeChildSessionParamsUtils.fromPersistableBundle(childParamsBundle);
+
+ for (String key : in.keySet()) {
+ if (!BUNDLE_KEY_SET.contains(key)) {
+ Log.w(TAG, "Found an unexpected key in the PersistableBundle: " + key);
+ }
+ }
- mIkeParams = null;
- mChildParams = null;
+ validate();
}
private void validate() {
@@ -101,9 +108,11 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
@NonNull
public PersistableBundle toPersistableBundle() {
final PersistableBundle result = super.toPersistableBundle();
-
- // STOPSHIP: b/163604823 Support converting mIkeParams and mChildParams to
- // PersistableBundles.
+ result.putPersistableBundle(
+ IKE_PARAMS_KEY, IkeSessionParamsUtils.toPersistableBundle(mIkeParams));
+ result.putPersistableBundle(
+ CHILD_PARAMS_KEY,
+ TunnelModeChildSessionParamsUtils.toPersistableBundle(mChildParams));
return result;
}
@@ -134,10 +143,9 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
VcnControlPlaneIkeConfig other = (VcnControlPlaneIkeConfig) o;
- // STOPSHIP: b/163604823 Also check mIkeParams and mChildParams when it is supported to
- // construct mIkeParams and mChildParams from PersistableBundles. They are not checked
- // now so that VcnGatewayConnectionConfigTest and VcnConfigTest can pass.
- return super.equals(o);
+ return super.equals(o)
+ && Objects.equals(mIkeParams, other.mIkeParams)
+ && Objects.equals(mChildParams, other.mChildParams);
}
/** @hide */
diff --git a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java b/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
index b6036b4a6fd1..35b318687773 100644
--- a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
+++ b/core/java/android/net/vcn/persistablebundleutils/CertUtils.java
@@ -18,18 +18,24 @@ package android.net.vcn.persistablebundleutils;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Objects;
/**
- * CertUtils provides utility methods for constructing Certificate.
+ * CertUtils provides utility methods for constructing Certificate and PrivateKey.
*
* @hide
*/
public class CertUtils {
private static final String CERT_TYPE_X509 = "X.509";
+ private static final String PRIVATE_KEY_TYPE_RSA = "RSA";
/** Decodes an ASN.1 DER encoded Certificate */
public static X509Certificate certificateFromByteArray(byte[] derEncoded) {
@@ -43,4 +49,18 @@ public class CertUtils {
throw new IllegalArgumentException("Fail to decode certificate", e);
}
}
+
+ /** Decodes a PKCS#8 encoded RSA private key */
+ public static RSAPrivateKey privateKeyFromByteArray(byte[] pkcs8Encoded) {
+ Objects.requireNonNull(pkcs8Encoded, "pkcs8Encoded was null");
+ PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(pkcs8Encoded);
+
+ try {
+ KeyFactory keyFactory = KeyFactory.getInstance(PRIVATE_KEY_TYPE_RSA);
+
+ return (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+ throw new IllegalArgumentException("Fail to decode PrivateKey", e);
+ }
+ }
}
diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
new file mode 100644
index 000000000000..9d3462cb0b2e
--- /dev/null
+++ b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vcn.persistablebundleutils;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.InetAddresses;
+import android.net.eap.EapSessionConfig;
+import android.net.ipsec.ike.IkeSaProposal;
+import android.net.ipsec.ike.IkeSessionParams;
+import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv4PcscfServer;
+import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv6PcscfServer;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig;
+import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest;
+import android.os.PersistableBundle;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.vcn.util.PersistableBundleUtils;
+
+import java.net.InetAddress;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Abstract utility class to convert IkeSessionParams to/from PersistableBundle.
+ *
+ * @hide
+ */
+@VisibleForTesting(visibility = Visibility.PRIVATE)
+public final class IkeSessionParamsUtils {
+ private static final String SERVER_HOST_NAME_KEY = "SERVER_HOST_NAME_KEY";
+ private static final String SA_PROPOSALS_KEY = "SA_PROPOSALS_KEY";
+ private static final String LOCAL_ID_KEY = "LOCAL_ID_KEY";
+ private static final String REMOTE_ID_KEY = "REMOTE_ID_KEY";
+ private static final String LOCAL_AUTH_KEY = "LOCAL_AUTH_KEY";
+ private static final String REMOTE_AUTH_KEY = "REMOTE_AUTH_KEY";
+ private static final String CONFIG_REQUESTS_KEY = "CONFIG_REQUESTS_KEY";
+ private static final String RETRANS_TIMEOUTS_KEY = "RETRANS_TIMEOUTS_KEY";
+ private static final String HARD_LIFETIME_SEC_KEY = "HARD_LIFETIME_SEC_KEY";
+ private static final String SOFT_LIFETIME_SEC_KEY = "SOFT_LIFETIME_SEC_KEY";
+ private static final String DPD_DELAY_SEC_KEY = "DPD_DELAY_SEC_KEY";
+ private static final String NATT_KEEPALIVE_DELAY_SEC_KEY = "NATT_KEEPALIVE_DELAY_SEC_KEY";
+ private static final String IKE_OPTIONS_KEY = "IKE_OPTIONS_KEY";
+
+ private static final Set<Integer> IKE_OPTIONS = new ArraySet<>();
+
+ static {
+ IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID);
+ IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH);
+ IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_MOBIKE);
+ }
+
+ /** Serializes an IkeSessionParams to a PersistableBundle. */
+ @NonNull
+ public static PersistableBundle toPersistableBundle(@NonNull IkeSessionParams params) {
+ if (params.getConfiguredNetwork() != null || params.getIke3gppExtension() != null) {
+ throw new IllegalStateException(
+ "Cannot convert a IkeSessionParams with a caller configured network or with"
+ + " 3GPP extension enabled");
+ }
+
+ final PersistableBundle result = new PersistableBundle();
+
+ result.putString(SERVER_HOST_NAME_KEY, params.getServerHostname());
+
+ final PersistableBundle saProposalBundle =
+ PersistableBundleUtils.fromList(
+ params.getSaProposals(), IkeSaProposalUtils::toPersistableBundle);
+ result.putPersistableBundle(SA_PROPOSALS_KEY, saProposalBundle);
+
+ result.putPersistableBundle(
+ LOCAL_ID_KEY,
+ IkeIdentificationUtils.toPersistableBundle(params.getLocalIdentification()));
+ result.putPersistableBundle(
+ REMOTE_ID_KEY,
+ IkeIdentificationUtils.toPersistableBundle(params.getRemoteIdentification()));
+
+ result.putPersistableBundle(
+ LOCAL_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getLocalAuthConfig()));
+ result.putPersistableBundle(
+ REMOTE_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getRemoteAuthConfig()));
+
+ final List<ConfigRequest> reqList = new ArrayList<>();
+ for (IkeConfigRequest req : params.getConfigurationRequests()) {
+ reqList.add(new ConfigRequest(req));
+ }
+ final PersistableBundle configReqListBundle =
+ PersistableBundleUtils.fromList(reqList, ConfigRequest::toPersistableBundle);
+ result.putPersistableBundle(CONFIG_REQUESTS_KEY, configReqListBundle);
+
+ result.putIntArray(RETRANS_TIMEOUTS_KEY, params.getRetransmissionTimeoutsMillis());
+ result.putInt(HARD_LIFETIME_SEC_KEY, params.getHardLifetimeSeconds());
+ result.putInt(SOFT_LIFETIME_SEC_KEY, params.getSoftLifetimeSeconds());
+ result.putInt(DPD_DELAY_SEC_KEY, params.getDpdDelaySeconds());
+ result.putInt(NATT_KEEPALIVE_DELAY_SEC_KEY, params.getNattKeepAliveDelaySeconds());
+
+ final List<Integer> enabledIkeOptions = new ArrayList<>();
+ for (int option : IKE_OPTIONS) {
+ if (params.hasIkeOption(option)) {
+ enabledIkeOptions.add(option);
+ }
+ }
+
+ final int[] optionArray = enabledIkeOptions.stream().mapToInt(i -> i).toArray();
+ result.putIntArray(IKE_OPTIONS_KEY, optionArray);
+
+ return result;
+ }
+
+ /** Constructs an IkeSessionParams by deserializing a PersistableBundle. */
+ @NonNull
+ public static IkeSessionParams fromPersistableBundle(@NonNull PersistableBundle in) {
+ Objects.requireNonNull(in, "PersistableBundle is null");
+
+ final IkeSessionParams.Builder builder = new IkeSessionParams.Builder();
+
+ builder.setServerHostname(in.getString(SERVER_HOST_NAME_KEY));
+
+ PersistableBundle proposalBundle = in.getPersistableBundle(SA_PROPOSALS_KEY);
+ Objects.requireNonNull(in, "SA Proposals was null");
+ List<IkeSaProposal> saProposals =
+ PersistableBundleUtils.toList(
+ proposalBundle, IkeSaProposalUtils::fromPersistableBundle);
+ for (IkeSaProposal proposal : saProposals) {
+ builder.addSaProposal(proposal);
+ }
+
+ builder.setLocalIdentification(
+ IkeIdentificationUtils.fromPersistableBundle(
+ in.getPersistableBundle(LOCAL_ID_KEY)));
+ builder.setRemoteIdentification(
+ IkeIdentificationUtils.fromPersistableBundle(
+ in.getPersistableBundle(REMOTE_ID_KEY)));
+
+ AuthConfigUtils.setBuilderByReadingPersistableBundle(
+ in.getPersistableBundle(LOCAL_AUTH_KEY),
+ in.getPersistableBundle(REMOTE_AUTH_KEY),
+ builder);
+
+ builder.setRetransmissionTimeoutsMillis(in.getIntArray(RETRANS_TIMEOUTS_KEY));
+ builder.setLifetimeSeconds(
+ in.getInt(HARD_LIFETIME_SEC_KEY), in.getInt(SOFT_LIFETIME_SEC_KEY));
+ builder.setDpdDelaySeconds(in.getInt(DPD_DELAY_SEC_KEY));
+ builder.setNattKeepAliveDelaySeconds(in.getInt(NATT_KEEPALIVE_DELAY_SEC_KEY));
+
+ final PersistableBundle configReqListBundle = in.getPersistableBundle(CONFIG_REQUESTS_KEY);
+ Objects.requireNonNull(configReqListBundle, "Config request list was null");
+ final List<ConfigRequest> reqList =
+ PersistableBundleUtils.toList(configReqListBundle, ConfigRequest::new);
+ for (ConfigRequest req : reqList) {
+ switch (req.type) {
+ case ConfigRequest.IPV4_P_CSCF_ADDRESS:
+ if (req.address == null) {
+ builder.addPcscfServerRequest(AF_INET);
+ } else {
+ builder.addPcscfServerRequest(req.address);
+ }
+ break;
+ case ConfigRequest.IPV6_P_CSCF_ADDRESS:
+ if (req.address == null) {
+ builder.addPcscfServerRequest(AF_INET6);
+ } else {
+ builder.addPcscfServerRequest(req.address);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Unrecognized config request type: " + req.type);
+ }
+ }
+
+ // Clear IKE Options that are by default enabled
+ for (int option : IKE_OPTIONS) {
+ builder.removeIkeOption(option);
+ }
+
+ final int[] optionArray = in.getIntArray(IKE_OPTIONS_KEY);
+ for (int option : optionArray) {
+ builder.addIkeOption(option);
+ }
+
+ return builder.build();
+ }
+
+ private static final class AuthConfigUtils {
+ private static final int IKE_AUTH_METHOD_PSK = 1;
+ private static final int IKE_AUTH_METHOD_PUB_KEY_SIGNATURE = 2;
+ private static final int IKE_AUTH_METHOD_EAP = 3;
+
+ private static final String AUTH_METHOD_KEY = "AUTH_METHOD_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(@NonNull IkeAuthConfig authConfig) {
+ if (authConfig instanceof IkeAuthPskConfig) {
+ IkeAuthPskConfig config = (IkeAuthPskConfig) authConfig;
+ return IkeAuthPskConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_PSK));
+ } else if (authConfig instanceof IkeAuthDigitalSignLocalConfig) {
+ IkeAuthDigitalSignLocalConfig config = (IkeAuthDigitalSignLocalConfig) authConfig;
+ return IkeAuthDigitalSignConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE));
+ } else if (authConfig instanceof IkeAuthDigitalSignRemoteConfig) {
+ IkeAuthDigitalSignRemoteConfig config = (IkeAuthDigitalSignRemoteConfig) authConfig;
+ return IkeAuthDigitalSignConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE));
+ } else if (authConfig instanceof IkeAuthEapConfig) {
+ IkeAuthEapConfig config = (IkeAuthEapConfig) authConfig;
+ return IkeAuthEapConfigUtils.toPersistableBundle(
+ config, createPersistableBundle(IKE_AUTH_METHOD_EAP));
+ } else {
+ throw new IllegalStateException("Invalid IkeAuthConfig subclass");
+ }
+ }
+
+ private static PersistableBundle createPersistableBundle(int type) {
+ final PersistableBundle result = new PersistableBundle();
+ result.putInt(AUTH_METHOD_KEY, type);
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+ Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+ final int localMethodType = localAuthBundle.getInt(AUTH_METHOD_KEY);
+ final int remoteMethodType = remoteAuthBundle.getInt(AUTH_METHOD_KEY);
+ switch (localMethodType) {
+ case IKE_AUTH_METHOD_PSK:
+ if (remoteMethodType != IKE_AUTH_METHOD_PSK) {
+ throw new IllegalArgumentException(
+ "Expect remote auth method to be PSK based, but was "
+ + remoteMethodType);
+ }
+ IkeAuthPskConfigUtils.setBuilderByReadingPersistableBundle(
+ localAuthBundle, remoteAuthBundle, builder);
+ return;
+ case IKE_AUTH_METHOD_PUB_KEY_SIGNATURE:
+ if (remoteMethodType != IKE_AUTH_METHOD_PUB_KEY_SIGNATURE) {
+ throw new IllegalArgumentException(
+ "Expect remote auth method to be digital signature based, but was "
+ + remoteMethodType);
+ }
+ IkeAuthDigitalSignConfigUtils.setBuilderByReadingPersistableBundle(
+ localAuthBundle, remoteAuthBundle, builder);
+ return;
+ case IKE_AUTH_METHOD_EAP:
+ if (remoteMethodType != IKE_AUTH_METHOD_PUB_KEY_SIGNATURE) {
+ throw new IllegalArgumentException(
+ "When using EAP for local authentication, expect remote auth"
+ + " method to be digital signature based, but was "
+ + remoteMethodType);
+ }
+ IkeAuthEapConfigUtils.setBuilderByReadingPersistableBundle(
+ localAuthBundle, remoteAuthBundle, builder);
+ return;
+ default:
+ throw new IllegalArgumentException(
+ "Invalid EAP method type " + localMethodType);
+ }
+ }
+ }
+
+ private static final class IkeAuthPskConfigUtils {
+ private static final String PSK_KEY = "PSK_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthPskConfig config, @NonNull PersistableBundle result) {
+ result.putPersistableBundle(
+ PSK_KEY, PersistableBundleUtils.fromByteArray(config.getPsk()));
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+ Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+ final PersistableBundle localPskBundle = localAuthBundle.getPersistableBundle(PSK_KEY);
+ final PersistableBundle remotePskBundle =
+ remoteAuthBundle.getPersistableBundle(PSK_KEY);
+ Objects.requireNonNull(localAuthBundle, "Local PSK was null");
+ Objects.requireNonNull(remoteAuthBundle, "Remote PSK was null");
+
+ final byte[] localPsk = PersistableBundleUtils.toByteArray(localPskBundle);
+ final byte[] remotePsk = PersistableBundleUtils.toByteArray(remotePskBundle);
+ if (!Arrays.equals(localPsk, remotePsk)) {
+ throw new IllegalArgumentException("Local PSK and remote PSK are different");
+ }
+ builder.setAuthPsk(localPsk);
+ }
+ }
+
+ private static class IkeAuthDigitalSignConfigUtils {
+ private static final String END_CERT_KEY = "END_CERT_KEY";
+ private static final String INTERMEDIATE_CERTS_KEY = "INTERMEDIATE_CERTS_KEY";
+ private static final String PRIVATE_KEY_KEY = "PRIVATE_KEY_KEY";
+ private static final String TRUST_CERT_KEY = "TRUST_CERT_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthDigitalSignLocalConfig config, @NonNull PersistableBundle result) {
+ try {
+ result.putPersistableBundle(
+ END_CERT_KEY,
+ PersistableBundleUtils.fromByteArray(
+ config.getClientEndCertificate().getEncoded()));
+
+ final List<X509Certificate> certList = config.getIntermediateCertificates();
+ final List<byte[]> encodedCertList = new ArrayList<>(certList.size());
+ for (X509Certificate cert : certList) {
+ encodedCertList.add(cert.getEncoded());
+ }
+
+ final PersistableBundle certsBundle =
+ PersistableBundleUtils.fromList(
+ encodedCertList, PersistableBundleUtils::fromByteArray);
+ result.putPersistableBundle(INTERMEDIATE_CERTS_KEY, certsBundle);
+ } catch (CertificateEncodingException e) {
+ throw new IllegalArgumentException("Fail to encode certificate");
+ }
+
+ // TODO: b/170670506 Consider putting PrivateKey in Android KeyStore
+ result.putPersistableBundle(
+ PRIVATE_KEY_KEY,
+ PersistableBundleUtils.fromByteArray(config.getPrivateKey().getEncoded()));
+ return result;
+ }
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthDigitalSignRemoteConfig config, @NonNull PersistableBundle result) {
+ try {
+ X509Certificate caCert = config.getRemoteCaCert();
+ if (caCert != null) {
+ result.putPersistableBundle(
+ TRUST_CERT_KEY,
+ PersistableBundleUtils.fromByteArray(caCert.getEncoded()));
+ }
+ } catch (CertificateEncodingException e) {
+ throw new IllegalArgumentException("Fail to encode the certificate");
+ }
+
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ Objects.requireNonNull(localAuthBundle, "localAuthBundle was null");
+ Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null");
+
+ // Deserialize localAuth
+ final PersistableBundle endCertBundle =
+ localAuthBundle.getPersistableBundle(END_CERT_KEY);
+ Objects.requireNonNull(endCertBundle, "End cert was null");
+ final byte[] encodedCert = PersistableBundleUtils.toByteArray(endCertBundle);
+ final X509Certificate endCert = CertUtils.certificateFromByteArray(encodedCert);
+
+ final PersistableBundle certsBundle =
+ localAuthBundle.getPersistableBundle(INTERMEDIATE_CERTS_KEY);
+ Objects.requireNonNull(certsBundle, "Intermediate certs was null");
+ final List<byte[]> encodedCertList =
+ PersistableBundleUtils.toList(certsBundle, PersistableBundleUtils::toByteArray);
+ final List<X509Certificate> certList = new ArrayList<>(encodedCertList.size());
+ for (byte[] encoded : encodedCertList) {
+ certList.add(CertUtils.certificateFromByteArray(encoded));
+ }
+
+ final PersistableBundle privateKeyBundle =
+ localAuthBundle.getPersistableBundle(PRIVATE_KEY_KEY);
+ Objects.requireNonNull(privateKeyBundle, "PrivateKey bundle was null");
+ final PrivateKey privateKey =
+ CertUtils.privateKeyFromByteArray(
+ PersistableBundleUtils.toByteArray(privateKeyBundle));
+
+ // Deserialize remoteAuth
+ final PersistableBundle trustCertBundle =
+ remoteAuthBundle.getPersistableBundle(TRUST_CERT_KEY);
+
+ X509Certificate caCert = null;
+ if (trustCertBundle != null) {
+ final byte[] encodedCaCert = PersistableBundleUtils.toByteArray(trustCertBundle);
+ caCert = CertUtils.certificateFromByteArray(encodedCaCert);
+ }
+
+ builder.setAuthDigitalSignature(caCert, endCert, certList, privateKey);
+ }
+ }
+
+ private static final class IkeAuthEapConfigUtils {
+ private static final String EAP_CONFIG_KEY = "EAP_CONFIG_KEY";
+
+ @NonNull
+ public static PersistableBundle toPersistableBundle(
+ @NonNull IkeAuthEapConfig config, @NonNull PersistableBundle result) {
+ result.putPersistableBundle(
+ EAP_CONFIG_KEY,
+ EapSessionConfigUtils.toPersistableBundle(config.getEapConfig()));
+ return result;
+ }
+
+ public static void setBuilderByReadingPersistableBundle(
+ @NonNull PersistableBundle localAuthBundle,
+ @NonNull PersistableBundle remoteAuthBundle,
+ @NonNull IkeSessionParams.Builder builder) {
+ // Deserialize localAuth
+ final PersistableBundle eapBundle =
+ localAuthBundle.getPersistableBundle(EAP_CONFIG_KEY);
+ Objects.requireNonNull(eapBundle, "EAP Config was null");
+ final EapSessionConfig eapConfig =
+ EapSessionConfigUtils.fromPersistableBundle(eapBundle);
+
+ // Deserialize remoteAuth
+ final PersistableBundle trustCertBundle =
+ remoteAuthBundle.getPersistableBundle(
+ IkeAuthDigitalSignConfigUtils.TRUST_CERT_KEY);
+
+ X509Certificate serverCaCert = null;
+ if (trustCertBundle != null) {
+ final byte[] encodedCaCert = PersistableBundleUtils.toByteArray(trustCertBundle);
+ serverCaCert = CertUtils.certificateFromByteArray(encodedCaCert);
+ }
+ builder.setAuthEap(serverCaCert, eapConfig);
+ }
+ }
+
+ private static final class ConfigRequest {
+ private static final int IPV4_P_CSCF_ADDRESS = 1;
+ private static final int IPV6_P_CSCF_ADDRESS = 2;
+
+ private static final String TYPE_KEY = "type";
+ private static final String ADDRESS_KEY = "address";
+
+ public final int type;
+
+ // Null when it is an empty request
+ @Nullable public final InetAddress address;
+
+ ConfigRequest(IkeConfigRequest config) {
+ if (config instanceof ConfigRequestIpv4PcscfServer) {
+ type = IPV4_P_CSCF_ADDRESS;
+ address = ((ConfigRequestIpv4PcscfServer) config).getAddress();
+ } else if (config instanceof ConfigRequestIpv6PcscfServer) {
+ type = IPV6_P_CSCF_ADDRESS;
+ address = ((ConfigRequestIpv6PcscfServer) config).getAddress();
+ } else {
+ throw new IllegalStateException("Unknown TunnelModeChildConfigRequest");
+ }
+ }
+
+ ConfigRequest(PersistableBundle in) {
+ Objects.requireNonNull(in, "PersistableBundle was null");
+
+ type = in.getInt(TYPE_KEY);
+
+ String addressStr = in.getString(ADDRESS_KEY);
+ if (addressStr == null) {
+ address = null;
+ } else {
+ address = InetAddresses.parseNumericAddress(addressStr);
+ }
+ }
+
+ @NonNull
+ public PersistableBundle toPersistableBundle() {
+ final PersistableBundle result = new PersistableBundle();
+
+ result.putInt(TYPE_KEY, type);
+ if (address != null) {
+ result.putString(ADDRESS_KEY, address.getHostAddress());
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index a46af9754f32..b12dad038ce3 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1247,9 +1247,9 @@ public final class FileUtils {
}
/**
- * Creates a directory with name {@code name} under an existing directory {@code baseDir}.
- * Returns a {@code File} object representing the directory on success, {@code null} on
- * failure.
+ * Creates a directory with name {@code name} under an existing directory {@code baseDir} if it
+ * doesn't exist already. Returns a {@code File} object representing the directory if it exists
+ * and {@code null} if not.
*
* @hide
*/
@@ -1259,13 +1259,23 @@ public final class FileUtils {
return createDir(dir) ? dir : null;
}
- /** @hide */
+ /**
+ * Ensure the given directory exists, creating it if needed. This method is threadsafe.
+ *
+ * @return false if the directory doesn't exist and couldn't be created
+ *
+ * @hide
+ */
public static boolean createDir(File dir) {
+ if (dir.mkdir()) {
+ return true;
+ }
+
if (dir.exists()) {
return dir.isDirectory();
}
- return dir.mkdir();
+ return false;
}
/**
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 786a7d08047e..a19728c5c498 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -323,6 +323,13 @@ public final class PowerManager {
public static final int USER_ACTIVITY_EVENT_ATTENTION = 4;
/**
+ * User activity event type: {@link com.android.server.power.FaceDownDetector} taking action
+ * on behalf of user.
+ * @hide
+ */
+ public static final int USER_ACTIVITY_EVENT_FACE_DOWN = 5;
+
+ /**
* User activity flag: If already dimmed, extend the dim timeout
* but do not brighten. This flag is useful for keeping the screen on
* a little longer without causing a visible change such as when
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 1189fdb0b04a..df24baaf8ad9 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -2274,10 +2274,9 @@ public final class StrictMode {
*/
public static void assertUiContext(@NonNull Context context, @NonNull String methodName) {
if (vmIncorrectContextUseEnabled() && !context.isUiContext()) {
- final String errorMessage = "Tried to access UI related API" + methodName
+ final String errorMessage = "Tried to access UI related API:" + methodName
+ " from a non-UI Context:" + context;
- final String message = "UI-related services, such as WindowManager, WallpaperService "
- + "or LayoutInflater should be accessed from Activity or other UI "
+ final String message = methodName + " should be accessed from Activity or other UI "
+ "Contexts. Use an Activity or a Context created with "
+ "Context#createWindowContext(int, Bundle), which are adjusted to "
+ "the configuration and visual bounds of an area on screen.";
diff --git a/core/java/android/os/incremental/IIncrementalService.aidl b/core/java/android/os/incremental/IIncrementalService.aidl
index 3fbc28402405..d7bb2262063e 100644
--- a/core/java/android/os/incremental/IIncrementalService.aidl
+++ b/core/java/android/os/incremental/IIncrementalService.aidl
@@ -23,6 +23,7 @@ import android.os.incremental.IStorageLoadingProgressListener;
import android.os.incremental.IStorageHealthListener;
import android.os.incremental.PerUidReadTimeouts;
import android.os.incremental.StorageHealthCheckParams;
+import android.os.PersistableBundle;
/** @hide */
interface IIncrementalService {
@@ -165,4 +166,13 @@ interface IIncrementalService {
* Register storage health status listener.
*/
void unregisterStorageHealthListener(int storageId);
+
+ /**
+ * Metrics key for the duration in milliseconds between now and the oldest pending read. The value is a long.
+ */
+ const @utf8InCpp String METRICS_MILLIS_SINCE_OLDEST_PENDING_READ = "millisSinceOldestPendingRead";
+ /**
+ * Return a bundle containing the requested metrics keys and their values.
+ */
+ PersistableBundle getMetrics(int storageId);
}
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
index 73520e07d118..2a42b981ac26 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -51,6 +51,8 @@ import java.util.UUID;
public final class IncrementalFileStorages {
private static final String TAG = "IncrementalFileStorages";
+ private static final String SYSTEM_DATA_LOADER_PACKAGE = "android";
+
private @NonNull final IncrementalManager mIncrementalManager;
private @NonNull final File mStageDir;
private @Nullable IncrementalStorage mInheritedStorage;
@@ -116,7 +118,10 @@ public final class IncrementalFileStorages {
mInheritedStorage = mIncrementalManager.openStorage(
inheritedDir.getAbsolutePath());
if (mInheritedStorage != null) {
- if (!mInheritedStorage.isFullyLoaded()) {
+ boolean systemDataLoader = SYSTEM_DATA_LOADER_PACKAGE.equals(
+ dataLoaderParams.getComponentName().getPackageName());
+ if (systemDataLoader && !mInheritedStorage.isFullyLoaded()) {
+ // System data loader does not support incomplete storages.
throw new IOException("Inherited storage has missing pages.");
}
diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java
index 396ba2d3cea5..82c4c715f4b0 100644
--- a/core/java/android/os/storage/StorageManagerInternal.java
+++ b/core/java/android/os/storage/StorageManagerInternal.java
@@ -52,6 +52,11 @@ public abstract class StorageManagerInternal {
}
/**
+ * Return true if fuse is mounted.
+ */
+ public abstract boolean isFuseMounted(int userId);
+
+ /**
* Create storage directories if it does not exist.
* Return true if the directories were setup correctly, otherwise false.
*/
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4dfbb6fa2d05..6865041a5037 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8369,6 +8369,14 @@ public final class Settings {
public static final String DOZE_WAKE_DISPLAY_GESTURE = "doze_wake_display_gesture";
/**
+ * Gesture that wakes up the display on quick pickup, toggling between
+ * {@link Display.STATE_OFF} and {@link Display.STATE_DOZE}.
+ * @hide
+ */
+ @Readable
+ public static final String DOZE_QUICK_PICKUP_GESTURE = "doze_quick_pickup_gesture";
+
+ /**
* Whether the device should suppress the current doze configuration and disable dozing.
* @hide
*/
diff --git a/core/java/android/service/autofill/AutofillServiceInfo.java b/core/java/android/service/autofill/AutofillServiceInfo.java
index 4c8ee598f512..00c30b12c93d 100644
--- a/core/java/android/service/autofill/AutofillServiceInfo.java
+++ b/core/java/android/service/autofill/AutofillServiceInfo.java
@@ -23,6 +23,7 @@ import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -38,6 +39,7 @@ import android.util.Log;
import android.util.Xml;
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.XmlUtils;
@@ -233,6 +235,39 @@ public final class AutofillServiceInfo {
return compatibilityPackages;
}
+ /**
+ * Used by {@link TestDataBuilder}.
+ */
+ private AutofillServiceInfo(String passwordsActivity) {
+ mServiceInfo = new ServiceInfo();
+ mServiceInfo.applicationInfo = new ApplicationInfo();
+ mServiceInfo.packageName = "com.android.test";
+ mSettingsActivity = null;
+ mPasswordsActivity = passwordsActivity;
+ mCompatibilityPackages = null;
+ mInlineSuggestionsEnabled = false;
+ }
+
+ /**
+ * Builds test data for unit tests.
+ */
+ @VisibleForTesting
+ public static final class TestDataBuilder {
+ private String mPasswordsActivity;
+
+ public TestDataBuilder() {
+ }
+
+ public TestDataBuilder setPasswordsActivity(String passwordsActivity) {
+ mPasswordsActivity = passwordsActivity;
+ return this;
+ }
+
+ public AutofillServiceInfo build() {
+ return new AutofillServiceInfo(mPasswordsActivity);
+ }
+ }
+
@NonNull
public ServiceInfo getServiceInfo() {
return mServiceInfo;
diff --git a/core/java/android/service/rotationresolver/RotationResolutionRequest.java b/core/java/android/service/rotationresolver/RotationResolutionRequest.java
index 8e76e2fc9202..8dec0922b097 100644
--- a/core/java/android/service/rotationresolver/RotationResolutionRequest.java
+++ b/core/java/android/service/rotationresolver/RotationResolutionRequest.java
@@ -16,12 +16,15 @@
package android.service.rotationresolver;
+import android.annotation.DurationMillisLong;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.Surface;
+import com.android.internal.util.DataClass;
+
/**
* This class represents a request to an {@link RotationResolverService}. The request contains
* information from the system that can help RotationResolverService to determine the appropriate
@@ -33,68 +36,209 @@ import android.view.Surface;
* @hide
*/
@SystemApi
+@DataClass (
+ genParcelable = true,
+ genToString = true
+)
public final class RotationResolutionRequest implements Parcelable {
- private final @NonNull String mPackageName;
- private final int mProposedRotation;
- private final int mCurrentRotation;
- private final long mTimeoutMillis;
+ /** The Name of the package of the current fore-ground activity. */
+ @NonNull private final String mPackageName;
+
+ /** The current rotation of the screen. */
+ @Surface.Rotation private final int mCurrentRotation;
+
+ /** The proposed screen rotation in the system. */
+ @Surface.Rotation private final int mProposedRotation;
+
+ /** Whether should use camera signal to resolver rotation. */
+ private final boolean mShouldUseCamera;
+
+ /** The timeout of the request. */
+ @DurationMillisLong private final long mTimeoutMillis;
+
+
+
+
+ // Code below generated by codegen v1.0.22.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/rotationresolver/RotationResolutionRequest.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
/**
- * @param proposedRotation The system proposed screen rotation.
- * @param currentRotation The current screen rotation of the phone.
- * @param packageName The current package name of the activity that is running in
- * foreground.
- * @param timeoutMillis The timeout in millisecond for the rotation request.
- * @hide
+ * Creates a new RotationResolutionRequest.
+ *
+ * @param packageName
+ * The Name of the package of the current fore-ground activity.
+ * @param currentRotation
+ * The current rotation of the screen.
+ * @param proposedRotation
+ * The proposed screen rotation in the system.
+ * @param shouldUseCamera
+ * Whether should use camera signal to resolver rotation.
+ * @param timeoutMillis
+ * The timeout of the request.
*/
- public RotationResolutionRequest(int proposedRotation, int currentRotation,
- @NonNull String packageName, long timeoutMillis) {
- mProposedRotation = proposedRotation;
- mCurrentRotation = currentRotation;
- mPackageName = packageName;
- mTimeoutMillis = timeoutMillis;
+ @DataClass.Generated.Member
+ public RotationResolutionRequest(
+ @NonNull String packageName,
+ @Surface.Rotation int currentRotation,
+ @Surface.Rotation int proposedRotation,
+ boolean shouldUseCamera,
+ @DurationMillisLong long timeoutMillis) {
+ this.mPackageName = packageName;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mPackageName);
+ this.mCurrentRotation = currentRotation;
+ com.android.internal.util.AnnotationValidations.validate(
+ Surface.Rotation.class, null, mCurrentRotation);
+ this.mProposedRotation = proposedRotation;
+ com.android.internal.util.AnnotationValidations.validate(
+ Surface.Rotation.class, null, mProposedRotation);
+ this.mShouldUseCamera = shouldUseCamera;
+ this.mTimeoutMillis = timeoutMillis;
+ com.android.internal.util.AnnotationValidations.validate(
+ DurationMillisLong.class, null, mTimeoutMillis);
+
+ // onConstructed(); // You can define this method to get a callback
}
- @Surface.Rotation public int getProposedRotation() {
- return mProposedRotation;
+ /**
+ * The Name of the package of the current fore-ground activity.
+ */
+ @DataClass.Generated.Member
+ public @NonNull String getPackageName() {
+ return mPackageName;
}
- public int getCurrentRotation() {
+ /**
+ * The current rotation of the screen.
+ */
+ @DataClass.Generated.Member
+ public @Surface.Rotation int getCurrentRotation() {
return mCurrentRotation;
}
- public @NonNull String getPackageName() {
- return mPackageName;
+ /**
+ * The proposed screen rotation in the system.
+ */
+ @DataClass.Generated.Member
+ public @Surface.Rotation int getProposedRotation() {
+ return mProposedRotation;
}
- public long getTimeoutMillis() {
+ /**
+ * Whether should use camera signal to resolver rotation.
+ */
+ @DataClass.Generated.Member
+ public boolean shouldUseCamera() {
+ return mShouldUseCamera;
+ }
+
+ /**
+ * The timeout of the request.
+ */
+ @DataClass.Generated.Member
+ public @DurationMillisLong long getTimeoutMillis() {
return mTimeoutMillis;
}
@Override
- public int describeContents() {
- return 0;
+ @DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "RotationResolutionRequest { " +
+ "packageName = " + mPackageName + ", " +
+ "currentRotation = " + mCurrentRotation + ", " +
+ "proposedRotation = " + mProposedRotation + ", " +
+ "shouldUseCamera = " + mShouldUseCamera + ", " +
+ "timeoutMillis = " + mTimeoutMillis +
+ " }";
}
@Override
- public void writeToParcel(@NonNull Parcel parcel, int flags) {
- parcel.writeInt(mProposedRotation);
- parcel.writeInt(mCurrentRotation);
- parcel.writeString(mPackageName);
- parcel.writeLong(mTimeoutMillis);
+ @DataClass.Generated.Member
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ byte flg = 0;
+ if (mShouldUseCamera) flg |= 0x8;
+ dest.writeByte(flg);
+ dest.writeString(mPackageName);
+ dest.writeInt(mCurrentRotation);
+ dest.writeInt(mProposedRotation);
+ dest.writeLong(mTimeoutMillis);
}
- public static final @NonNull Creator<RotationResolutionRequest> CREATOR =
- new Creator<RotationResolutionRequest>() {
- @Override
- public RotationResolutionRequest createFromParcel(Parcel source) {
- return new RotationResolutionRequest(source.readInt(), source.readInt(),
- source.readString(), source.readLong());
- }
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ /* package-private */ RotationResolutionRequest(@NonNull Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+ byte flg = in.readByte();
+ boolean shouldUseCamera = (flg & 0x8) != 0;
+ String packageName = in.readString();
+ int currentRotation = in.readInt();
+ int proposedRotation = in.readInt();
+ long timeoutMillis = in.readLong();
+
+ this.mPackageName = packageName;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mPackageName);
+ this.mCurrentRotation = currentRotation;
+ com.android.internal.util.AnnotationValidations.validate(
+ Surface.Rotation.class, null, mCurrentRotation);
+ this.mProposedRotation = proposedRotation;
+ com.android.internal.util.AnnotationValidations.validate(
+ Surface.Rotation.class, null, mProposedRotation);
+ this.mShouldUseCamera = shouldUseCamera;
+ this.mTimeoutMillis = timeoutMillis;
+ com.android.internal.util.AnnotationValidations.validate(
+ DurationMillisLong.class, null, mTimeoutMillis);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<RotationResolutionRequest> CREATOR
+ = new Parcelable.Creator<RotationResolutionRequest>() {
@Override
public RotationResolutionRequest[] newArray(int size) {
return new RotationResolutionRequest[size];
}
+
+ @Override
+ public RotationResolutionRequest createFromParcel(@NonNull Parcel in) {
+ return new RotationResolutionRequest(in);
+ }
};
+
+ @DataClass.Generated(
+ time = 1615402421314L,
+ codegenVersion = "1.0.22",
+ sourceFile = "frameworks/base/core/java/android/service/rotationresolver/RotationResolutionRequest.java",
+ inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.view.Surface.Rotation int mCurrentRotation\nprivate final @android.view.Surface.Rotation int mProposedRotation\nprivate final boolean mShouldUseCamera\nprivate final @android.annotation.DurationMillisLong long mTimeoutMillis\nclass RotationResolutionRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genToString=true)")
+ @Deprecated
+ private void __metadata() {}
+
+
+ //@formatter:on
+ // End of generated code
+
}
diff --git a/core/java/android/speech/IRecognitionServiceManager.aidl b/core/java/android/speech/IRecognitionServiceManager.aidl
index 8e5292d1ddf1..ad402262878d 100644
--- a/core/java/android/speech/IRecognitionServiceManager.aidl
+++ b/core/java/android/speech/IRecognitionServiceManager.aidl
@@ -31,4 +31,6 @@ oneway interface IRecognitionServiceManager {
in IBinder clientToken,
boolean onDevice,
in IRecognitionServiceManagerCallback callback);
+
+ void setTemporaryComponent(in ComponentName componentName);
}
diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java
index 850f997a2d2f..9b93a64e48a3 100644
--- a/core/java/android/speech/SpeechRecognizer.java
+++ b/core/java/android/speech/SpeechRecognizer.java
@@ -17,6 +17,8 @@
package android.speech;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -35,6 +37,8 @@ import android.util.Log;
import android.util.Slog;
import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.LinkedBlockingQueue;
/**
* This class provides access to the speech recognition service. This service allows access to the
@@ -52,7 +56,7 @@ import java.util.List;
*/
public class SpeechRecognizer {
/** DEBUG value to enable verbose debug prints */
- private final static boolean DBG = false;
+ private static final boolean DBG = false;
/** Log messages identifier */
private static final String TAG = "SpeechRecognizer";
@@ -113,10 +117,11 @@ public class SpeechRecognizer {
public static final int ERROR_SERVER_DISCONNECTED = 11;
/** action codes */
- private final static int MSG_START = 1;
- private final static int MSG_STOP = 2;
- private final static int MSG_CANCEL = 3;
- private final static int MSG_CHANGE_LISTENER = 4;
+ private static final int MSG_START = 1;
+ private static final int MSG_STOP = 2;
+ private static final int MSG_CANCEL = 3;
+ private static final int MSG_CHANGE_LISTENER = 4;
+ private static final int MSG_SET_TEMPORARY_ON_DEVICE_COMPONENT = 5;
/** The actual RecognitionService endpoint */
private IRecognitionService mService;
@@ -134,6 +139,7 @@ public class SpeechRecognizer {
/** Handler that will execute the main tasks */
private Handler mHandler = new Handler(Looper.getMainLooper()) {
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -149,10 +155,19 @@ public class SpeechRecognizer {
case MSG_CHANGE_LISTENER:
handleChangeListener((RecognitionListener) msg.obj);
break;
+ case MSG_SET_TEMPORARY_ON_DEVICE_COMPONENT:
+ handleSetTemporaryComponent((ComponentName) msg.obj);
+ break;
}
}
};
+ /**
+ * Temporary queue, saving the messages until the connection will be established, afterwards,
+ * only mHandler will receive the messages
+ */
+ private final Queue<Message> mPendingTasks = new LinkedBlockingQueue<>();
+
/** The Listener that will receive all the callbacks */
private final InternalListener mListener = new InternalListener();
@@ -287,11 +302,9 @@ public class SpeechRecognizer {
if (mService == null) {
// First time connection: first establish a connection, then dispatch #startListening.
- connectToSystemService(
- () -> putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent)));
- } else {
- putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent));
+ connectToSystemService();
}
+ putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent));
}
/**
@@ -336,6 +349,22 @@ public class SpeechRecognizer {
putMessage(Message.obtain(mHandler, MSG_CANCEL));
}
+ /**
+ * Sets a temporary component to power on-device speech recognizer.
+ *
+ * <p>This is only expected to be called in tests, system would reject calls from client apps.
+ *
+ * @param componentName name of the component to set temporary replace speech recognizer. {@code
+ * null} value resets the recognizer to default.
+ *
+ * @hide
+ */
+ @TestApi
+ public void setTemporaryOnDeviceRecognizer(@Nullable ComponentName componentName) {
+ mHandler.sendMessage(
+ Message.obtain(mHandler, MSG_SET_TEMPORARY_ON_DEVICE_COMPONENT, componentName));
+ }
+
private static void checkIsCalledFromMainThread() {
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new RuntimeException(
@@ -344,7 +373,11 @@ public class SpeechRecognizer {
}
private void putMessage(Message msg) {
- mHandler.sendMessage(msg);
+ if (mService == null) {
+ mPendingTasks.offer(msg);
+ } else {
+ mHandler.sendMessage(msg);
+ }
}
/** sends the actual message to the service */
@@ -395,6 +428,22 @@ public class SpeechRecognizer {
}
}
+ private void handleSetTemporaryComponent(ComponentName componentName) {
+ if (DBG) {
+ Log.d(TAG, "handleSetTemporaryComponent, componentName=" + componentName);
+ }
+
+ if (!maybeInitializeManagerService()) {
+ return;
+ }
+
+ try {
+ mManagerService.setTemporaryComponent(componentName);
+ } catch (final RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
private boolean checkOpenConnection() {
if (mService != null) {
return true;
@@ -422,16 +471,13 @@ public class SpeechRecognizer {
}
mService = null;
+ mPendingTasks.clear();
mListener.mInternalListener = null;
}
/** Establishes a connection to system server proxy and initializes the session. */
- private void connectToSystemService(Runnable onSuccess) {
- mManagerService = IRecognitionServiceManager.Stub.asInterface(
- ServiceManager.getService(Context.SPEECH_RECOGNITION_SERVICE));
-
- if (mManagerService == null) {
- mListener.onError(ERROR_CLIENT);
+ private void connectToSystemService() {
+ if (!maybeInitializeManagerService()) {
return;
}
@@ -450,13 +496,19 @@ public class SpeechRecognizer {
new IRecognitionServiceManagerCallback.Stub(){
@Override
public void onSuccess(IRecognitionService service) throws RemoteException {
+ if (DBG) {
+ Log.i(TAG, "Connected to speech recognition service");
+ }
mService = service;
- onSuccess.run();
+ while (!mPendingTasks.isEmpty()) {
+ mHandler.sendMessage(mPendingTasks.poll());
+ }
}
@Override
public void onError(int errorCode) throws RemoteException {
- Log.e(TAG, "Bind to system recognition service failed");
+ Log.e(TAG, "Bind to system recognition service failed with error "
+ + errorCode);
mListener.onError(errorCode);
}
});
@@ -465,6 +517,21 @@ public class SpeechRecognizer {
}
}
+ private boolean maybeInitializeManagerService() {
+ if (mManagerService != null) {
+ return true;
+ }
+
+ mManagerService = IRecognitionServiceManager.Stub.asInterface(
+ ServiceManager.getService(Context.SPEECH_RECOGNITION_SERVICE));
+
+ if (mManagerService == null && mListener != null) {
+ mListener.onError(ERROR_CLIENT);
+ return false;
+ }
+ return true;
+ }
+
/**
* Returns the component name to be used for establishing a connection, based on the parameters
* used during initialization.
@@ -505,15 +572,15 @@ public class SpeechRecognizer {
private static class InternalListener extends IRecognitionListener.Stub {
private RecognitionListener mInternalListener;
- private final static int MSG_BEGINNING_OF_SPEECH = 1;
- private final static int MSG_BUFFER_RECEIVED = 2;
- private final static int MSG_END_OF_SPEECH = 3;
- private final static int MSG_ERROR = 4;
- private final static int MSG_READY_FOR_SPEECH = 5;
- private final static int MSG_RESULTS = 6;
- private final static int MSG_PARTIAL_RESULTS = 7;
- private final static int MSG_RMS_CHANGED = 8;
- private final static int MSG_ON_EVENT = 9;
+ private static final int MSG_BEGINNING_OF_SPEECH = 1;
+ private static final int MSG_BUFFER_RECEIVED = 2;
+ private static final int MSG_END_OF_SPEECH = 3;
+ private static final int MSG_ERROR = 4;
+ private static final int MSG_READY_FOR_SPEECH = 5;
+ private static final int MSG_RESULTS = 6;
+ private static final int MSG_PARTIAL_RESULTS = 7;
+ private static final int MSG_RMS_CHANGED = 8;
+ private static final int MSG_ON_EVENT = 9;
private final Handler mInternalHandler = new Handler(Looper.getMainLooper()) {
@Override
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index e37921ec03cc..bbe887f500a9 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -1326,7 +1326,7 @@ public class PhoneStateListener {
() -> mExecutor.execute(() -> psl.onCellLocationChanged(location)));
}
- public void onCallStateChanged(int state, String incomingNumber) {
+ public void onLegacyCallStateChanged(int state, String incomingNumber) {
PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
if (psl == null) return;
@@ -1334,6 +1334,10 @@ public class PhoneStateListener {
() -> mExecutor.execute(() -> psl.onCallStateChanged(state, incomingNumber)));
}
+ public void onCallStateChanged(int state) {
+ // Only used for the new TelephonyCallback class
+ }
+
public void onDataConnectionStateChanged(int state, int networkType) {
PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
if (psl == null) return;
diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java
index a2584cae1b9c..2cadda25a9d3 100644
--- a/core/java/android/telephony/TelephonyCallback.java
+++ b/core/java/android/telephony/TelephonyCallback.java
@@ -20,11 +20,9 @@ import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.compat.annotation.ChangeId;
-import android.compat.annotation.UnsupportedAppUsage;
import android.os.Binder;
import android.os.Build;
import android.telephony.emergency.EmergencyNumber;
@@ -170,12 +168,15 @@ public class TelephonyCallback {
/**
* Event for changes to the device call state.
- *
+ * <p>
+ * Handles callbacks to {@link CallStateListener#onCallStateChanged(int)}.
+ * <p>
+ * Note: This is different from the legacy {@link #EVENT_LEGACY_CALL_STATE_CHANGED} listener
+ * which can include the phone number of the caller. We purposely do not include the phone
+ * number as that information is not required for call state listeners going forward.
* @hide
- * @see CallStateListener#onCallStateChanged
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
public static final int EVENT_CALL_STATE_CHANGED = 6;
/**
@@ -556,6 +557,18 @@ public class TelephonyCallback {
public static final int EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED = 35;
/**
+ * Event for changes to the legacy call state changed listener implemented by
+ * {@link PhoneStateListener#onCallStateChanged(int, String)}. This listener variant is similar
+ * to the new {@link CallStateListener#onCallStateChanged(int)} with the important distinction
+ * that it CAN provide the phone number associated with a call.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
+ public static final int EVENT_LEGACY_CALL_STATE_CHANGED = 36;
+
+ /**
* @hide
*/
@IntDef(prefix = {"EVENT_"}, value = {
@@ -593,7 +606,8 @@ public class TelephonyCallback {
EVENT_BARRING_INFO_CHANGED,
EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED,
EVENT_DATA_ENABLED_CHANGED,
- EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED
+ EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED,
+ EVENT_LEGACY_CALL_STATE_CHANGED
})
@Retention(RetentionPolicy.SOURCE)
public @interface TelephonyEvent {
@@ -723,17 +737,9 @@ public class TelephonyCallback {
* calling {@link TelephonyManager#getCallState()} from within this callback may return a
* different state than the callback reports.
*
- * @param state call state
- * @param phoneNumber call phone number. If application does not have
- * {@link android.Manifest.permission#READ_CALL_LOG} permission or
- * carrier
- * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an
- * empty string will be
- * passed as an argument.
+ * @param state the current call state
*/
- @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
- public void onCallStateChanged(@Annotation.CallState int state,
- @Nullable String phoneNumber);
+ public void onCallStateChanged(@Annotation.CallState int state);
}
/**
@@ -1426,13 +1432,17 @@ public class TelephonyCallback {
() -> mExecutor.execute(() -> listener.onCellLocationChanged(location)));
}
- public void onCallStateChanged(int state, String incomingNumber) {
+ public void onLegacyCallStateChanged(int state, String incomingNumber) {
+ // Not used for TelephonyCallback; part of the AIDL which is used by both the legacy
+ // PhoneStateListener and TelephonyCallback.
+ }
+
+ public void onCallStateChanged(int state) {
CallStateListener listener = (CallStateListener) mTelephonyCallbackWeakRef.get();
if (listener == null) return;
Binder.withCleanCallingIdentity(
- () -> mExecutor.execute(() -> listener.onCallStateChanged(state,
- incomingNumber)));
+ () -> mExecutor.execute(() -> listener.onCallStateChanged(state)));
}
public void onDataConnectionStateChanged(int state, int networkType) {
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 459c6e94e4ac..9cda4ae79335 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -861,6 +861,7 @@ public class TelephonyRegistryManager {
eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED);
}
+ // Note: Legacy PhoneStateListeners use EVENT_LEGACY_CALL_STATE_CHANGED
if (telephonyCallback instanceof TelephonyCallback.CallStateListener) {
eventList.add(TelephonyCallback.EVENT_CALL_STATE_CHANGED);
}
@@ -1000,8 +1001,10 @@ public class TelephonyRegistryManager {
eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED);
}
+ // Note: Legacy call state listeners can get the phone number which is not provided in the
+ // new version in TelephonyCallback.
if ((eventMask & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
- eventList.add(TelephonyCallback.EVENT_CALL_STATE_CHANGED);
+ eventList.add(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED);
}
if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 4d321079416b..919c6e50e3a4 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -39,7 +39,6 @@ public class FeatureFlagUtils {
public static final String FFLAG_OVERRIDE_PREFIX = FFLAG_PREFIX + "override.";
public static final String PERSIST_PREFIX = "persist." + FFLAG_OVERRIDE_PREFIX;
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
- public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
public static final String SETTINGS_WIFITRACKER2 = "settings_wifitracker2";
/** @hide */
public static final String SETTINGS_DO_NOT_RESTORE_PRESERVED =
@@ -59,7 +58,6 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put("settings_audio_switcher", "true");
DEFAULT_FLAGS.put("settings_systemui_theme", "true");
DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
- DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false");
DEFAULT_FLAGS.put("settings_skip_direction_mutable", "true");
DEFAULT_FLAGS.put(SETTINGS_WIFITRACKER2, "true");
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 8117c963b959..d484f4d47e99 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -24,9 +24,11 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.TestApi;
+import android.app.ActivityThread;
import android.app.KeyguardManager;
+import android.app.WindowConfiguration;
import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
+import android.content.ComponentName;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -45,11 +47,14 @@ import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.util.Log;
+import com.android.internal.R;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Optional;
/**
* Provides information about the size and density of a logical display.
@@ -61,11 +66,12 @@ import java.util.List;
* be smaller than the real display area because the system subtracts the space needed
* for decor elements such as the status bar. Use {@link WindowMetrics#getBounds()} to query the
* application window bounds.</li>
- * <li>The real display area specifies the part of the display that contains content
- * including the system decorations. Even so, the real display area may be smaller than the
- * physical size of the display if the window manager is emulating a smaller display
- * using (adb shell wm size). Use the following methods to query the
- * real display area: {@link #getRealSize}, {@link #getRealMetrics}.</li>
+ * <li>The real display area specifies the part of the display that is accessible to an application
+ * in the current system state. The real display area may be smaller than the physical size of the
+ * display in a few scenarios. Use {@link WindowManager#getCurrentWindowMetrics()} to identify the
+ * current size of the activity window. UI-related work, such as choosing UI layouts, should rely
+ * upon {@link WindowMetrics#getBounds()}. See {@link #getRealSize} / {@link #getRealMetrics} for
+ * details.</li>
* </ul>
* </p><p>
* A logical display does not necessarily represent a particular physical display device
@@ -78,6 +84,7 @@ public final class Display {
private static final String TAG = "Display";
private static final boolean DEBUG = false;
+ private final Object mLock = new Object();
private final DisplayManagerGlobal mGlobal;
private final int mDisplayId;
private final int mFlags;
@@ -112,6 +119,12 @@ public final class Display {
private boolean mMayAdjustByFixedRotation;
/**
+ * Cache if the application is the recents component.
+ * TODO(b/179308296) Remove once Launcher addresses issue
+ */
+ private Optional<Boolean> mIsRecentsComponent = Optional.empty();
+
+ /**
* The default Display id, which is the id of the primary display assuming there is one.
*/
public static final int DEFAULT_DISPLAY = 0;
@@ -557,7 +570,7 @@ public final class Display {
* @return True if the display is still valid.
*/
public boolean isValid() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mIsValid;
}
@@ -572,7 +585,7 @@ public final class Display {
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public boolean getDisplayInfo(DisplayInfo outDisplayInfo) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
outDisplayInfo.copyFrom(mDisplayInfo);
return mIsValid;
@@ -589,7 +602,7 @@ public final class Display {
* @hide
*/
public int getLayerStack() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.layerStack;
}
@@ -636,7 +649,7 @@ public final class Display {
* @hide
*/
public DisplayAddress getAddress() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.address;
}
@@ -678,9 +691,9 @@ public final class Display {
@UnsupportedAppUsage
public DisplayAdjustments getDisplayAdjustments() {
if (mResources != null) {
- final DisplayAdjustments currentAdjustements = mResources.getDisplayAdjustments();
- if (!mDisplayAdjustments.equals(currentAdjustements)) {
- mDisplayAdjustments = new DisplayAdjustments(currentAdjustements);
+ final DisplayAdjustments currentAdjustments = mResources.getDisplayAdjustments();
+ if (!mDisplayAdjustments.equals(currentAdjustments)) {
+ mDisplayAdjustments = new DisplayAdjustments(currentAdjustments);
}
}
@@ -696,7 +709,7 @@ public final class Display {
* @return The display's name.
*/
public String getName() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.name;
}
@@ -709,7 +722,7 @@ public final class Display {
* @hide
*/
public float getBrightnessDefault() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.brightnessDefault;
}
@@ -748,7 +761,7 @@ public final class Display {
*/
@Deprecated
public void getSize(Point outSize) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
outSize.x = mTempMetrics.widthPixels;
@@ -765,7 +778,7 @@ public final class Display {
*/
@Deprecated
public void getRectSize(Rect outSize) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels);
@@ -803,7 +816,7 @@ public final class Display {
* for example, screen decorations like the status bar are being hidden.
*/
public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth;
outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight;
@@ -819,7 +832,7 @@ public final class Display {
*/
@UnsupportedAppUsage
public int getMaximumSizeDimension() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
}
@@ -830,7 +843,7 @@ public final class Display {
*/
@Deprecated
public int getWidth() {
- synchronized (this) {
+ synchronized (mLock) {
updateCachedAppSizeIfNeededLocked();
return mCachedAppWidthCompat;
}
@@ -841,7 +854,7 @@ public final class Display {
*/
@Deprecated
public int getHeight() {
- synchronized (this) {
+ synchronized (mLock) {
updateCachedAppSizeIfNeededLocked();
return mCachedAppHeightCompat;
}
@@ -866,7 +879,7 @@ public final class Display {
*/
@Surface.Rotation
public int getRotation() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mMayAdjustByFixedRotation
? getDisplayAdjustments().getRotation(mDisplayInfo.rotation)
@@ -892,7 +905,7 @@ public final class Display {
*/
@Nullable
public DisplayCutout getCutout() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mMayAdjustByFixedRotation
? getDisplayAdjustments().getDisplayCutout(mDisplayInfo.displayCutout)
@@ -910,7 +923,7 @@ public final class Display {
@SuppressLint("VisiblySynchronized")
@Nullable
public RoundedCorner getRoundedCorner(@RoundedCorner.Position int position) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
RoundedCorners roundedCorners;
if (mMayAdjustByFixedRotation) {
@@ -942,7 +955,7 @@ public final class Display {
* Gets the refresh rate of this display in frames per second.
*/
public float getRefreshRate() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.getRefreshRate();
}
@@ -958,7 +971,7 @@ public final class Display {
*/
@Deprecated
public float[] getSupportedRefreshRates() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.getDefaultRefreshRates();
}
@@ -968,7 +981,7 @@ public final class Display {
* Returns the active mode of the display.
*/
public Mode getMode() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.getMode();
}
@@ -978,7 +991,7 @@ public final class Display {
* Gets the supported modes of this display.
*/
public Mode[] getSupportedModes() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
final Display.Mode[] modes = mDisplayInfo.supportedModes;
return Arrays.copyOf(modes, modes.length);
@@ -1004,7 +1017,7 @@ public final class Display {
*/
@SuppressLint("VisiblySynchronized")
public boolean isMinimalPostProcessingSupported() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.minimalPostProcessingSupported;
}
@@ -1024,7 +1037,7 @@ public final class Display {
* @hide
*/
public int getColorMode() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.colorMode;
}
@@ -1051,7 +1064,7 @@ public final class Display {
* @see #isHdr()
*/
public HdrCapabilities getHdrCapabilities() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.hdrCapabilities;
}
@@ -1064,7 +1077,7 @@ public final class Display {
* @see HdrCapabilities#getSupportedHdrTypes()
*/
public boolean isHdr() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.isHdr();
}
@@ -1077,7 +1090,7 @@ public final class Display {
* {@link Configuration#isScreenWideColorGamut()}.
*/
public boolean isWideColorGamut() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.isWideColorGamut();
}
@@ -1092,7 +1105,7 @@ public final class Display {
*/
@Nullable
public ColorSpace getPreferredWideGamutColorSpace() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
if (mDisplayInfo.isWideColorGamut()) {
return mGlobal.getPreferredWideGamutColorSpace();
@@ -1106,7 +1119,7 @@ public final class Display {
* @hide
*/
public int[] getSupportedColorModes() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
int[] colorModes = mDisplayInfo.supportedColorModes;
return Arrays.copyOf(colorModes, colorModes.length);
@@ -1123,7 +1136,7 @@ public final class Display {
@NonNull
@TestApi
public @ColorMode ColorSpace[] getSupportedWideColorGamut() {
- synchronized (this) {
+ synchronized (mLock) {
final ColorSpace[] defaultColorSpaces = new ColorSpace[0];
updateDisplayInfoLocked();
if (!isWideColorGamut()) {
@@ -1157,7 +1170,7 @@ public final class Display {
* A/V synchronization.
*/
public long getAppVsyncOffsetNanos() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.appVsyncOffsetNanos;
}
@@ -1175,7 +1188,7 @@ public final class Display {
* ({@link System#nanoTime}).
*/
public long getPresentationDeadlineNanos() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mDisplayInfo.presentationDeadlineNanos;
}
@@ -1190,7 +1203,10 @@ public final class Display {
*/
@Nullable
public DeviceProductInfo getDeviceProductInfo() {
- return mDisplayInfo.deviceProductInfo;
+ synchronized (mLock) {
+ updateDisplayInfoLocked();
+ return mDisplayInfo.deviceProductInfo;
+ }
}
/**
@@ -1223,37 +1239,73 @@ public final class Display {
*/
@Deprecated
public void getMetrics(DisplayMetrics outMetrics) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
mDisplayInfo.getAppMetrics(outMetrics, getDisplayAdjustments());
}
}
/**
- * Gets the real size of the display without subtracting any window decor or
- * applying any compatibility scale factors.
+ * Gets the size of the largest region of the display accessible to an app in the current system
+ * state, without subtracting any window decor or applying scaling factors.
* <p>
* The size is adjusted based on the current rotation of the display.
+ * <p></p>
+ * The returned size will fall into one of these scenarios:
+ * <ol>
+ * <li>The device has no partitions on the display. The returned value is the largest region
+ * of the display accessible to an app in the current system state, regardless of windowing
+ * mode.</li>
+ * <li>The device divides a single display into multiple partitions. An application is
+ * restricted to a portion of the display. This is common in devices where the display changes
+ * size, such as foldables or large screens. The returned size will match the portion of
+ * the display the application is restricted to.</li>
+ * <li>The window manager is emulating a different display size, using {@code adb shell wm
+ * size}. The returned size will match the emulated display size.</li>
+ * </ol>
* </p><p>
- * The real size may be smaller than the physical size of the screen when the
- * window manager is emulating a smaller display (using adb shell wm size).
- * </p><p>
- * In general, {@link #getRealSize(Point)} and {@link WindowManager#getMaximumWindowMetrics()}
- * report the same bounds except that certain areas of the display may not be available to
- * windows created in the {@link WindowManager}'s {@link Context}.
- *
- * For example, imagine a device which has a multi-task mode that limits windows to half of the
- * screen. In this case, {@link WindowManager#getMaximumWindowMetrics()} reports the
- * bounds of the screen half where the window is located, while {@link #getRealSize(Point)}
- * still reports the bounds of the whole display.
+ * The returned value is <b>unsuitable to use when sizing and placing UI elements</b>, since it
+ * does not reflect the application window size in any of these scenarios.
+ * {@link WindowManager#getCurrentWindowMetrics()} is an alternative that returns the size
+ * of the current application window, even if the window is on a device with a partitioned
+ * display. This helps prevent UI bugs where UI elements are misaligned or placed beyond the
+ * bounds of the window.
+ * <p></p>
+ * Handling multi-window mode correctly is necessary since applications are not always
+ * fullscreen. A user on a large screen device, such as a tablet or Chrome OS devices, is more
+ * likely to use multi-window modes.
+ * <p></p>
+ * For example, consider a device with a display partitioned into two halves. The user may have
+ * a fullscreen application open on the first partition. They may have two applications open in
+ * split screen (an example of multi-window mode) on the second partition, with each application
+ * consuming half of the partition. In this case,
+ * {@link WindowManager#getCurrentWindowMetrics()} reports the fullscreen window is half of the
+ * screen in size, and each split screen window is a quarter of the screen in size. On the other
+ * hand, {@link #getRealSize} reports half of the screen size for all windows, since the
+ * application windows are all restricted to their respective partitions.
+ * </p>
*
* @param outSize Set to the real size of the display.
- *
- * @see WindowManager#getMaximumWindowMetrics()
+ * @deprecated Use {@link WindowManager#getCurrentWindowMetrics()} to identify the current size
+ * of the activity window. UI-related work, such as choosing UI layouts, should rely
+ * upon {@link WindowMetrics#getBounds()}.
*/
+ @Deprecated
public void getRealSize(Point outSize) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
+ if (shouldReportMaxBounds()) {
+ final Rect bounds = mResources.getConfiguration()
+ .windowConfiguration.getMaxBounds();
+ outSize.x = bounds.width();
+ outSize.y = bounds.height();
+ if (DEBUG) {
+ Log.d(TAG, "getRealSize determined from max bounds: " + outSize);
+ }
+ // Skip adjusting by fixed rotation, since if it is necessary, the configuration
+ // should already reflect the expected rotation.
+ return;
+ }
outSize.x = mDisplayInfo.logicalWidth;
outSize.y = mDisplayInfo.logicalHeight;
if (mMayAdjustByFixedRotation) {
@@ -1263,19 +1315,66 @@ public final class Display {
}
/**
- * Gets display metrics based on the real size of this display.
+ * Gets the size of the largest region of the display accessible to an app in the current system
+ * state, without subtracting any window decor or applying scaling factors.
* <p>
* The size is adjusted based on the current rotation of the display.
+ * <p></p>
+ * The returned size will fall into one of these scenarios:
+ * <ol>
+ * <li>The device has no partitions on the display. The returned value is the largest region
+ * of the display accessible to an app in the current system state, regardless of windowing
+ * mode.</li>
+ * <li>The device divides a single display into multiple partitions. An application is
+ * restricted to a portion of the display. This is common in devices where the display changes
+ * size, such as foldables or large screens. The returned size will match the portion of
+ * the display the application is restricted to.</li>
+ * <li>The window manager is emulating a different display size, using {@code adb shell wm
+ * size}. The returned size will match the emulated display size.</li>
+ * </ol>
* </p><p>
- * The real size may be smaller than the physical size of the screen when the
- * window manager is emulating a smaller display (using adb shell wm size).
+ * The returned value is <b>unsuitable to use when sizing and placing UI elements</b>, since it
+ * does not reflect the application window size in any of these scenarios.
+ * {@link WindowManager#getCurrentWindowMetrics()} is an alternative that returns the size
+ * of the current application window, even if the window is on a device with a partitioned
+ * display. This helps prevent UI bugs where UI elements are misaligned or placed beyond the
+ * bounds of the window.
+ * <p></p>
+ * Handling multi-window mode correctly is necessary since applications are not always
+ * fullscreen. A user on a large screen device, such as a tablet or Chrome OS devices, is more
+ * likely to use multi-window modes.
+ * <p></p>
+ * For example, consider a device with a display partitioned into two halves. The user may have
+ * a fullscreen application open on the first partition. They may have two applications open in
+ * split screen (an example of multi-window mode) on the second partition, with each application
+ * consuming half of the partition. In this case,
+ * {@link WindowManager#getCurrentWindowMetrics()} reports the fullscreen window is half of the
+ * screen in size, and each split screen window is a quarter of the screen in size. On the other
+ * hand, {@link #getRealMetrics} reports half of the screen size for all windows, since the
+ * application windows are all restricted to their respective partitions.
* </p>
*
* @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
+ * @deprecated Use {@link WindowManager#getCurrentWindowMetrics()} to identify the current size
+ * of the activity window. UI-related work, such as choosing UI layouts, should rely
+ * upon {@link WindowMetrics#getBounds()}. Use {@link Configuration#densityDpi} to
+ * get the current density.
*/
+ @Deprecated
public void getRealMetrics(DisplayMetrics outMetrics) {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
+ if (shouldReportMaxBounds()) {
+ mDisplayInfo.getMaxBoundsMetrics(outMetrics,
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO,
+ mResources.getConfiguration());
+ if (DEBUG) {
+ Log.d(TAG, "getRealMetrics determined from max bounds: " + outMetrics);
+ }
+ // Skip adjusting by fixed rotation, since if it is necessary, the configuration
+ // should already reflect the expected rotation.
+ return;
+ }
mDisplayInfo.getLogicalMetrics(outMetrics,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
if (mMayAdjustByFixedRotation) {
@@ -1285,6 +1384,53 @@ public final class Display {
}
/**
+ * Determines if {@link WindowConfiguration#getMaxBounds()} should be reported as the
+ * display dimensions. The max bounds field may be smaller than the logical dimensions
+ * when apps need to be sandboxed.
+ *
+ * Depends upon {@link WindowConfiguration#getMaxBounds()} being set in
+ * {@link com.android.server.wm.ConfigurationContainer#providesMaxBounds()}. In most cases, this
+ * value reflects the size of the current DisplayArea.
+ * @return {@code true} when max bounds should be applied.
+ */
+ private boolean shouldReportMaxBounds() {
+ if (mResources == null) {
+ return false;
+ }
+ final Configuration config = mResources.getConfiguration();
+ // TODO(b/179308296) Temporarily exclude Launcher from being given max bounds, by checking
+ // if the caller is the recents component.
+ return config != null && !config.windowConfiguration.getMaxBounds().isEmpty()
+ && !isRecentsComponent();
+ }
+
+ /**
+ * Returns {@code true} when the calling package is the recents component.
+ * TODO(b/179308296) Remove once Launcher addresses issue
+ */
+ boolean isRecentsComponent() {
+ if (mIsRecentsComponent.isPresent()) {
+ return mIsRecentsComponent.get();
+ }
+ if (mResources == null) {
+ return false;
+ }
+ try {
+ String recentsComponent = mResources.getString(R.string.config_recentsComponentName);
+ if (recentsComponent == null) {
+ return false;
+ }
+ String recentsPackage = ComponentName.unflattenFromString(recentsComponent)
+ .getPackageName();
+ mIsRecentsComponent = Optional.of(recentsPackage != null
+ && recentsPackage.equals(ActivityThread.currentPackageName()));
+ return mIsRecentsComponent.get();
+ } catch (Resources.NotFoundException e) {
+ return false;
+ }
+ }
+
+ /**
* Gets the state of the display, such as whether it is on or off.
*
* @return The state of the display: one of {@link #STATE_OFF}, {@link #STATE_ON},
@@ -1292,7 +1438,7 @@ public final class Display {
* {@link #STATE_UNKNOWN}.
*/
public int getState() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
return mIsValid ? mDisplayInfo.state : STATE_UNKNOWN;
}
@@ -1376,7 +1522,7 @@ public final class Display {
// For debugging purposes
@Override
public String toString() {
- synchronized (this) {
+ synchronized (mLock) {
updateDisplayInfoLocked();
final DisplayAdjustments adjustments = getDisplayAdjustments();
mDisplayInfo.getAppMetrics(mTempMetrics, adjustments);
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 655f42308a1f..a8aaeb7846a2 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -24,6 +24,7 @@ import static android.view.DisplayInfoProto.LOGICAL_WIDTH;
import static android.view.DisplayInfoProto.NAME;
import android.annotation.Nullable;
+import android.app.WindowConfiguration;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -615,11 +616,29 @@ public final class DisplayInfo implements Parcelable {
getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
}
+ /**
+ * Populates {@code outMetrics} with details of the logical display. Bounds are limited
+ * by the logical size of the display.
+ *
+ * @param outMetrics the {@link DisplayMetrics} to be populated
+ * @param compatInfo the {@link CompatibilityInfo} to be applied
+ * @param configuration the {@link Configuration}
+ */
public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Configuration configuration) {
getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
}
+ /**
+ * Similar to {@link #getLogicalMetrics}, but the limiting bounds are determined from
+ * {@link WindowConfiguration#getMaxBounds()}
+ */
+ public void getMaxBoundsMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
+ Configuration configuration) {
+ Rect bounds = configuration.windowConfiguration.getMaxBounds();
+ getMetricsWithSize(outMetrics, compatInfo, configuration, bounds.width(), bounds.height());
+ }
+
public int getNaturalWidth() {
return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
logicalWidth : logicalHeight;
diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java
index 79d8c14aa0df..5e0579d8a672 100644
--- a/core/java/android/view/InputEventReceiver.java
+++ b/core/java/android/view/InputEventReceiver.java
@@ -159,6 +159,16 @@ public abstract class InputEventReceiver {
}
/**
+ * Called when a drag event is received, from native code.
+ *
+ * @param isExiting if false, the window associated with this input channel has just received
+ * drag
+ * if true, the window associated with this input channel has just lost drag
+ */
+ public void onDragEvent(boolean isExiting, float x, float y) {
+ }
+
+ /**
* Called when a batched input event is pending.
*
* The batched input event will continue to accumulate additional movement
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 9523bcdb8e39..ed840ce3061b 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -70,7 +70,7 @@ import java.util.function.Consumer;
* <p>Content capture provides real-time, continuous capture of application activity, display and
* events to an intelligence service that is provided by the Android system. The intelligence
* service then uses that info to mediate and speed user journey through different apps. For
- * example, when the user receives a restaurant address in a chat app and switchs to a map app
+ * example, when the user receives a restaurant address in a chat app and switches to a map app
* to search for that restaurant, the intelligence service could offer an autofill dialog to
* let the user automatically select its address.
*
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index de4554b9e624..6ade5e622eab 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -105,7 +105,7 @@ public interface InputMethod {
*/
@MainThread
default void initializeInternal(IBinder token, int displayId,
- IInputMethodPrivilegedOperations privilegedOperations) {
+ IInputMethodPrivilegedOperations privilegedOperations, int configChanges) {
updateInputMethodDisplay(displayId);
attachToken(token);
}
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 5d876a6f62d3..25712f8bf9b8 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -18,19 +18,23 @@ package android.view.inputmethod;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
+import android.inputmethodservice.InputMethodService;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
@@ -60,6 +64,7 @@ import java.util.List;
* @attr ref android.R.styleable#InputMethod_isDefault
* @attr ref android.R.styleable#InputMethod_supportsSwitchingToNextInputMethod
* @attr ref android.R.styleable#InputMethod_supportsInlineSuggestions
+ * @attr ref android.R.styleable#InputMethod_configChanges
*/
public final class InputMethodInfo implements Parcelable {
static final String TAG = "InputMethodInfo";
@@ -118,6 +123,12 @@ public final class InputMethodInfo implements Parcelable {
private final boolean mInlineSuggestionsEnabled;
/**
+ * The flag for configurations IME assumes the responsibility for handling in
+ * {@link InputMethodService#onConfigurationChanged(Configuration)}}.
+ */
+ private final int mHandledConfigChanges;
+
+ /**
* @param service the {@link ResolveInfo} corresponds in which the IME is implemented.
* @return a unique ID to be returned by {@link #getId()}. We have used
* {@link ComponentName#flattenToShortString()} for this purpose (and it is already
@@ -203,6 +214,8 @@ public final class InputMethodInfo implements Parcelable {
false);
inlineSuggestionsEnabled = sa.getBoolean(
com.android.internal.R.styleable.InputMethod_supportsInlineSuggestions, false);
+ mHandledConfigChanges = sa.getInt(
+ com.android.internal.R.styleable.InputMethod_configChanges, 0);
sa.recycle();
final int depth = parser.getDepth();
@@ -287,6 +300,7 @@ public final class InputMethodInfo implements Parcelable {
mIsVrOnly = source.readBoolean();
mService = ResolveInfo.CREATOR.createFromParcel(source);
mSubtypes = new InputMethodSubtypeArray(source);
+ mHandledConfigChanges = source.readInt();
mForceDefault = false;
}
@@ -298,7 +312,22 @@ public final class InputMethodInfo implements Parcelable {
this(buildFakeResolveInfo(packageName, className, label), false /* isAuxIme */,
settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
- false /* inlineSuggestionsEnabled */, false /* isVrOnly */);
+ false /* inlineSuggestionsEnabled */, false /* isVrOnly */,
+ 0 /* handledConfigChanges */);
+ }
+
+ /**
+ * Temporary API for creating a built-in input method for test.
+ * @hide
+ */
+ @TestApi
+ public InputMethodInfo(@NonNull String packageName, @NonNull String className,
+ @NonNull CharSequence label, @NonNull String settingsActivity,
+ int handledConfigChanges) {
+ this(buildFakeResolveInfo(packageName, className, label), false /* isAuxIme */,
+ settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
+ false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
+ false /* inlineSuggestionsEnabled */, false /* isVrOnly */, handledConfigChanges);
}
/**
@@ -310,7 +339,7 @@ public final class InputMethodInfo implements Parcelable {
boolean forceDefault) {
this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, forceDefault,
true /* supportsSwitchingToNextInputMethod */, false /* inlineSuggestionsEnabled */,
- false /* isVrOnly */);
+ false /* isVrOnly */, 0 /* handledconfigChanges */);
}
/**
@@ -321,7 +350,8 @@ public final class InputMethodInfo implements Parcelable {
List<InputMethodSubtype> subtypes, int isDefaultResId, boolean forceDefault,
boolean supportsSwitchingToNextInputMethod, boolean isVrOnly) {
this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, forceDefault,
- supportsSwitchingToNextInputMethod, false /* inlineSuggestionsEnabled */, isVrOnly);
+ supportsSwitchingToNextInputMethod, false /* inlineSuggestionsEnabled */, isVrOnly,
+ 0 /* handledConfigChanges */);
}
/**
@@ -331,7 +361,7 @@ public final class InputMethodInfo implements Parcelable {
public InputMethodInfo(ResolveInfo ri, boolean isAuxIme, String settingsActivity,
List<InputMethodSubtype> subtypes, int isDefaultResId, boolean forceDefault,
boolean supportsSwitchingToNextInputMethod, boolean inlineSuggestionsEnabled,
- boolean isVrOnly) {
+ boolean isVrOnly, int handledConfigChanges) {
final ServiceInfo si = ri.serviceInfo;
mService = ri;
mId = new ComponentName(si.packageName, si.name).flattenToShortString();
@@ -343,6 +373,7 @@ public final class InputMethodInfo implements Parcelable {
mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
mInlineSuggestionsEnabled = inlineSuggestionsEnabled;
mIsVrOnly = isVrOnly;
+ mHandledConfigChanges = handledConfigChanges;
}
private static ResolveInfo buildFakeResolveInfo(String packageName, String className,
@@ -489,6 +520,17 @@ public final class InputMethodInfo implements Parcelable {
}
}
+ /**
+ * Returns the bit mask of kinds of configuration changes that this IME
+ * can handle itself (without being restarted by the system).
+ *
+ * @attr ref android.R.styleable#InputMethod_configChanges
+ */
+ @ActivityInfo.Config
+ public int getConfigChanges() {
+ return mHandledConfigChanges;
+ }
+
public void dump(Printer pw, String prefix) {
pw.println(prefix + "mId=" + mId
+ " mSettingsActivityName=" + mSettingsActivityName
@@ -579,6 +621,7 @@ public final class InputMethodInfo implements Parcelable {
dest.writeBoolean(mIsVrOnly);
mService.writeToParcel(dest, flags);
mSubtypes.writeToParcel(dest);
+ dest.writeInt(mHandledConfigChanges);
}
/**
diff --git a/core/java/android/view/textclassifier/TextClassificationConstants.java b/core/java/android/view/textclassifier/TextClassificationConstants.java
index d0959f97e438..5f3159cd09c8 100644
--- a/core/java/android/view/textclassifier/TextClassificationConstants.java
+++ b/core/java/android/view/textclassifier/TextClassificationConstants.java
@@ -91,8 +91,9 @@ public final class TextClassificationConstants {
"system_textclassifier_api_timeout_in_second";
/**
- * The max amount of characters before and after the selected text that are passed to the
- * TextClassifier for the smart selection.
+ * The maximum amount of characters before and after the selected text that is passed to the
+ * TextClassifier for the smart selection. e.g. If this value is 100, then 100 characters before
+ * the selection and 100 characters after the selection will be passed to the TextClassifier.
*/
private static final String SMART_SELECTION_TRIM_DELTA = "smart_selection_trim_delta";
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java
index cf3358b0dfbb..9f90b3bf1322 100644
--- a/core/java/android/view/translation/UiTranslationController.java
+++ b/core/java/android/view/translation/UiTranslationController.java
@@ -25,6 +25,7 @@ import android.annotation.NonNull;
import android.annotation.WorkerThread;
import android.app.Activity;
import android.content.Context;
+import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
@@ -54,6 +55,11 @@ import java.util.function.Consumer;
*/
public class UiTranslationController {
+ // TODO(b/182433547): remove Build.IS_DEBUGGABLE before ship. Enable the logging in debug build
+ // to help the debug during the development phase
+ public static final boolean DEBUG = Log.isLoggable(UiTranslationManager.LOG_TAG, Log.DEBUG)
+ || Build.IS_DEBUGGABLE;
+
private static final String TAG = "UiTranslationController";
@NonNull
private final Activity mActivity;
@@ -93,6 +99,8 @@ public class UiTranslationController {
if (!mActivity.isResumed()) {
return;
}
+ Log.i(TAG, "updateUiTranslationState state: " + stateToString(state)
+ + (DEBUG ? ", views: " + views : ""));
switch (state) {
case STATE_UI_TRANSLATION_STARTED:
final Pair<TranslationSpec, TranslationSpec> specs =
@@ -149,8 +157,69 @@ public class UiTranslationController {
translator.dump(outerPrefix, pw);
pw.println();
}
+ synchronized (mLock) {
+ final int viewSize = mViews.size();
+ pw.print(outerPrefix); pw.print("number views: "); pw.println(viewSize);
+ for (int i = 0; i < viewSize; i++) {
+ pw.print(outerPrefix); pw.print("#"); pw.println(i);
+ final AutofillId autofillId = mViews.keyAt(i);
+ final View view = mViews.valueAt(i).get();
+ pw.print(pfx); pw.print("autofillId: "); pw.println(autofillId);
+ pw.print(pfx); pw.print("view:"); pw.println(view);
+ }
+ }
+ // TODO(b/182433547): we will remove debug rom condition before S release then we change
+ // change this back to "DEBUG"
+ if (Log.isLoggable(UiTranslationManager.LOG_TAG, Log.DEBUG)) {
+ dumpViewByTraversal(outerPrefix, pw);
+ }
+ }
+
+ private void dumpViewByTraversal(String outerPrefix, PrintWriter pw) {
+ final ArrayList<ViewRootImpl> roots =
+ WindowManagerGlobal.getInstance().getRootViews(mActivity.getActivityToken());
+ pw.print(outerPrefix); pw.println("Dump views:");
+ for (int rootNum = 0; rootNum < roots.size(); rootNum++) {
+ final View rootView = roots.get(rootNum).getView();
+ if (rootView instanceof ViewGroup) {
+ dumpChildren((ViewGroup) rootView, outerPrefix, pw);
+ } else {
+ dumpViewInfo(rootView, outerPrefix, pw);
+ }
+ }
+ }
+
+ private void dumpChildren(ViewGroup viewGroup, String outerPrefix, PrintWriter pw) {
+ final int childCount = viewGroup.getChildCount();
+ for (int i = 0; i < childCount; ++i) {
+ final View child = viewGroup.getChildAt(i);
+ if (child instanceof ViewGroup) {
+ pw.print(outerPrefix); pw.println("Children: ");
+ pw.print(outerPrefix); pw.print(outerPrefix); pw.println(child);
+ dumpChildren((ViewGroup) child, outerPrefix, pw);
+ } else {
+ pw.print(outerPrefix); pw.println("End Children: ");
+ pw.print(outerPrefix); pw.print(outerPrefix); pw.print(child);
+ dumpViewInfo(child, outerPrefix, pw);
+ }
+ }
}
+ private void dumpViewInfo(View view, String outerPrefix, PrintWriter pw) {
+ final AutofillId autofillId = view.getAutofillId();
+ pw.print(outerPrefix); pw.print("autofillId: "); pw.print(autofillId);
+ // TODO: print TranslationTransformation
+ boolean isContainsView = false;
+ synchronized (mLock) {
+ final WeakReference<View> viewRef = mViews.get(autofillId);
+ if (viewRef != null && viewRef.get() != null) {
+ isContainsView = true;
+ }
+ }
+ pw.print(outerPrefix); pw.print("isContainsView: "); pw.println(isContainsView);
+ }
+
+
/**
* The method is used by {@link Translator}, it will be called when the translation is done. The
* translation result can be get from here.
@@ -171,6 +240,9 @@ public class UiTranslationController {
return;
}
final int resultCount = translatedResult.size();
+ if (DEBUG) {
+ Log.v(TAG, "onTranslationCompleted: receive " + resultCount + " responses.");
+ }
synchronized (mLock) {
for (int i = 0; i < resultCount; i++) {
final ViewTranslationResponse response = translatedResult.get(i);
@@ -180,7 +252,7 @@ public class UiTranslationController {
}
final View view = mViews.get(autofillId).get();
if (view == null) {
- Log.w(TAG, "onTranslationCompleted: the Veiew for autofill id " + autofillId
+ Log.w(TAG, "onTranslationCompleted: the view for autofill id " + autofillId
+ " may be gone.");
continue;
}
@@ -208,6 +280,10 @@ public class UiTranslationController {
@WorkerThread
private void sendTranslationRequest(Translator translator,
List<ViewTranslationRequest> requests) {
+ if (requests.size() == 0) {
+ Log.wtf(TAG, "No ViewTranslationRequest was collected.");
+ return;
+ }
final TranslationRequest request = new TranslationRequest.Builder()
.setViewTranslationRequests(requests)
.build();
@@ -233,7 +309,8 @@ public class UiTranslationController {
requests.add(request);
}
if (currentCount == (foundViews.size() - 1)) {
- Log.v(TAG, "onUiTranslationStarted: send " + requests.size() + " request.");
+ Log.v(TAG, "onUiTranslationStarted: collect " + requests.size()
+ + " requests.");
mWorkerHandler.sendMessage(PooledLambda.obtainMessage(
UiTranslationController::sendTranslationRequest,
UiTranslationController.this, translator, requests));
@@ -287,6 +364,9 @@ public class UiTranslationController {
for (int i = 0; i < viewCounts; i++) {
final View view = views.valueAt(i).get();
if (view == null) {
+ if (DEBUG) {
+ Log.d(TAG, "View was gone for autofillid = " + views.keyAt(i));
+ }
continue;
}
action.accept(view);
diff --git a/core/java/android/view/translation/UiTranslationManager.java b/core/java/android/view/translation/UiTranslationManager.java
index a3a6a2e52138..7c73e701b7c8 100644
--- a/core/java/android/view/translation/UiTranslationManager.java
+++ b/core/java/android/view/translation/UiTranslationManager.java
@@ -43,6 +43,14 @@ public final class UiTranslationManager {
private static final String TAG = "UiTranslationManager";
/**
+ * The tag which uses for enabling debug log dump. To enable it, we can use command "adb shell
+ * setprop log.tag.UiTranslation DEBUG".
+ *
+ * @hide
+ */
+ public static final String LOG_TAG = "UiTranslation";
+
+ /**
* The state caller request to disable utranslation,, it is no longer need to ui translation.
*
* @hide
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index dc42ad583543..45352e4d5ba2 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -20,6 +20,9 @@ import android.annotation.ColorInt;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.compat.Compatibility;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
@@ -58,6 +61,29 @@ import java.lang.annotation.RetentionPolicy;
* {@link #draw(Canvas)} method.</p>
*/
public class EdgeEffect {
+ /**
+ * This sets the default value for {@link #setType(int)} to {@link #TYPE_STRETCH} instead
+ * of {@link #TYPE_GLOW}. The type can still be overridden by the theme, view attribute,
+ * or by calling {@link #setType(int)}.
+ *
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+ public static final long USE_STRETCH_EDGE_EFFECT_BY_DEFAULT = 171228096L;
+
+ /**
+ * This sets the default value for {@link #setType(int)} to {@link #TYPE_STRETCH} instead
+ * of {@link #TYPE_GLOW} for views that instantiate with
+ * {@link #EdgeEffect(Context, AttributeSet)}, indicating use of S+ EdgeEffect support. The
+ * type can still be overridden by the theme, view attribute, or by calling
+ * {@link #setType(int)}.
+ *
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+ public static final long USE_STRETCH_EDGE_EFFECT_FOR_SUPPORTED = 178807038L;
/**
* The default blend mode used by {@link EdgeEffect}.
@@ -76,6 +102,28 @@ public class EdgeEffect {
*/
public static final int TYPE_STRETCH = 1;
+ /**
+ * The velocity threshold before the spring animation is considered settled.
+ * The idea here is that velocity should be less than 1 pixel per frame (~16ms).
+ */
+ private static final double VELOCITY_THRESHOLD = 1.0 / 0.016;
+
+ /**
+ * The value threshold before the spring animation is considered close enough to
+ * the destination to be settled. This should be around 1 pixel.
+ */
+ private static final double VALUE_THRESHOLD = 1;
+
+ /**
+ * The natural frequency of the stretch spring.
+ */
+ private static final double NATURAL_FREQUENCY = 14.4222;
+
+ /**
+ * The damping ratio of the stretch spring.
+ */
+ private static final double DAMPING_RATIO = 0.875;
+
/** @hide */
@IntDef({TYPE_GLOW, TYPE_STRETCH})
@Retention(RetentionPolicy.SOURCE)
@@ -119,20 +167,19 @@ public class EdgeEffect {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private float mGlowScaleY;
private float mDistance;
+ private float mVelocity; // only for stretch animations
private float mGlowAlphaStart;
private float mGlowAlphaFinish;
private float mGlowScaleYStart;
private float mGlowScaleYFinish;
- private float mDistanceStart;
- private float mDistanceFinish;
private long mStartTime;
private float mDuration;
private float mStretchIntensity = DEFAULT_MAX_STRETCH_INTENSITY;
private float mStretchDistance = -1f;
- private final Interpolator mInterpolator;
+ private final Interpolator mInterpolator = new DecelerateInterpolator();
private static final int STATE_IDLE = 0;
private static final int STATE_PULL = 1;
@@ -166,7 +213,7 @@ public class EdgeEffect {
* @param context Context used to provide theming and resource information for the EdgeEffect
*/
public EdgeEffect(Context context) {
- this(context, null);
+ this(context, null, Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_BY_DEFAULT));
}
/**
@@ -175,18 +222,26 @@ public class EdgeEffect {
* @param attrs The attributes of the XML tag that is inflating the view
*/
public EdgeEffect(@NonNull Context context, @Nullable AttributeSet attrs) {
- mPaint.setAntiAlias(true);
+ this(context, attrs,
+ Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_BY_DEFAULT)
+ || Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_FOR_SUPPORTED));
+ }
+
+ private EdgeEffect(@NonNull Context context, @Nullable AttributeSet attrs,
+ boolean defaultStretch) {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.EdgeEffect);
final int themeColor = a.getColor(
com.android.internal.R.styleable.EdgeEffect_colorEdgeEffect, 0xff666666);
mEdgeEffectType = a.getInt(
- com.android.internal.R.styleable.EdgeEffect_edgeEffectType, TYPE_GLOW);
+ com.android.internal.R.styleable.EdgeEffect_edgeEffectType,
+ defaultStretch ? TYPE_STRETCH : TYPE_GLOW);
a.recycle();
+
+ mPaint.setAntiAlias(true);
mPaint.setColor((themeColor & 0xffffff) | 0x33000000);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setBlendMode(DEFAULT_BLEND_MODE);
- mInterpolator = new DecelerateInterpolator();
}
/**
@@ -239,6 +294,8 @@ public class EdgeEffect {
*/
public void finish() {
mState = STATE_IDLE;
+ mDistance = 0;
+ mVelocity = 0;
}
/**
@@ -293,7 +350,8 @@ public class EdgeEffect {
mDuration = PULL_TIME;
mPullDistance += deltaDistance;
- mDistanceStart = mDistanceFinish = mDistance = Math.max(0f, mPullDistance);
+ mDistance = Math.max(0f, mPullDistance);
+ mVelocity = 0;
final float absdd = Math.abs(deltaDistance);
mGlowAlpha = mGlowAlphaStart = Math.min(MAX_ALPHA,
@@ -387,11 +445,10 @@ public class EdgeEffect {
mState = STATE_RECEDE;
mGlowAlphaStart = mGlowAlpha;
mGlowScaleYStart = mGlowScaleY;
- mDistanceStart = mDistance;
mGlowAlphaFinish = 0.f;
mGlowScaleYFinish = 0.f;
- mDistanceFinish = 0.f;
+ mVelocity = 0.f;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
mDuration = RECEDE_TIME;
@@ -408,30 +465,36 @@ public class EdgeEffect {
* @param velocity Velocity at impact in pixels per second.
*/
public void onAbsorb(int velocity) {
- mState = STATE_ABSORB;
- velocity = Math.min(Math.max(MIN_VELOCITY, Math.abs(velocity)), MAX_VELOCITY);
-
- mStartTime = AnimationUtils.currentAnimationTimeMillis();
- mDuration = 0.15f + (velocity * 0.02f);
-
- // The glow depends more on the velocity, and therefore starts out
- // nearly invisible.
- mGlowAlphaStart = GLOW_ALPHA_START;
- mGlowScaleYStart = Math.max(mGlowScaleY, 0.f);
- mDistanceStart = mDistance;
-
- // Growth for the size of the glow should be quadratic to properly
- // respond
- // to a user's scrolling speed. The faster the scrolling speed, the more
- // intense the effect should be for both the size and the saturation.
- mGlowScaleYFinish = Math.min(0.025f + (velocity * (velocity / 100) * 0.00015f) / 2, 1.f);
- // Alpha should change for the glow as well as size.
- mGlowAlphaFinish = Math.max(
- mGlowAlphaStart, Math.min(velocity * VELOCITY_GLOW_FACTOR * .00001f, MAX_ALPHA));
- mTargetDisplacement = 0.5f;
-
- // Use glow values to estimate the absorption for stretch distance.
- mDistanceFinish = calculateDistanceFromGlowValues(mGlowScaleYFinish, mGlowAlphaFinish);
+ if (mEdgeEffectType == TYPE_STRETCH) {
+ mState = STATE_RECEDE;
+ mVelocity = velocity / mHeight;
+ mDistance = 0;
+ mStartTime = AnimationUtils.currentAnimationTimeMillis();
+ } else {
+ mState = STATE_ABSORB;
+ mVelocity = 0;
+ velocity = Math.min(Math.max(MIN_VELOCITY, Math.abs(velocity)), MAX_VELOCITY);
+
+ mStartTime = AnimationUtils.currentAnimationTimeMillis();
+ mDuration = 0.15f + (velocity * 0.02f);
+
+ // The glow depends more on the velocity, and therefore starts out
+ // nearly invisible.
+ mGlowAlphaStart = GLOW_ALPHA_START;
+ mGlowScaleYStart = Math.max(mGlowScaleY, 0.f);
+
+ // Growth for the size of the glow should be quadratic to properly
+ // respond
+ // to a user's scrolling speed. The faster the scrolling speed, the more
+ // intense the effect should be for both the size and the saturation.
+ mGlowScaleYFinish = Math.min(0.025f + (velocity * (velocity / 100) * 0.00015f) / 2,
+ 1.f);
+ // Alpha should change for the glow as well as size.
+ mGlowAlphaFinish = Math.max(
+ mGlowAlphaStart,
+ Math.min(velocity * VELOCITY_GLOW_FACTOR * .00001f, MAX_ALPHA));
+ mTargetDisplacement = 0.5f;
+ }
}
/**
@@ -539,8 +602,8 @@ public class EdgeEffect {
canvas.drawCircle(centerX, centerY, mRadius, mPaint);
canvas.restoreToCount(count);
} else if (canvas instanceof RecordingCanvas) {
- if (mState != STATE_PULL) {
- update();
+ if (mState == STATE_RECEDE) {
+ updateSpring();
}
RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
if (mTmpMatrix == null) {
@@ -597,7 +660,7 @@ public class EdgeEffect {
}
boolean oneLastFrame = false;
- if (mState == STATE_RECEDE && mDistance == 0) {
+ if (mState == STATE_RECEDE && mDistance == 0 && mVelocity == 0) {
mState = STATE_IDLE;
oneLastFrame = true;
}
@@ -634,7 +697,7 @@ public class EdgeEffect {
mGlowAlpha = mGlowAlphaStart + (mGlowAlphaFinish - mGlowAlphaStart) * interp;
mGlowScaleY = mGlowScaleYStart + (mGlowScaleYFinish - mGlowScaleYStart) * interp;
- mDistance = mDistanceStart + (mDistanceFinish - mDistanceStart) * interp;
+ mDistance = calculateDistanceFromGlowValues(mGlowScaleY, mGlowAlpha);
mDisplacement = (mDisplacement + mTargetDisplacement) / 2;
if (t >= 1.f - EPSILON) {
@@ -646,12 +709,10 @@ public class EdgeEffect {
mGlowAlphaStart = mGlowAlpha;
mGlowScaleYStart = mGlowScaleY;
- mDistanceStart = mDistance;
// After absorb, the glow should fade to nothing.
mGlowAlphaFinish = 0.f;
mGlowScaleYFinish = 0.f;
- mDistanceFinish = 0.f;
break;
case STATE_PULL:
mState = STATE_PULL_DECAY;
@@ -660,12 +721,10 @@ public class EdgeEffect {
mGlowAlphaStart = mGlowAlpha;
mGlowScaleYStart = mGlowScaleY;
- mDistanceStart = mDistance;
// After pull, the glow should fade to nothing.
mGlowAlphaFinish = 0.f;
mGlowScaleYFinish = 0.f;
- mDistanceFinish = 0.f;
break;
case STATE_PULL_DECAY:
mState = STATE_RECEDE;
@@ -677,6 +736,35 @@ public class EdgeEffect {
}
}
+ private void updateSpring() {
+ final long time = AnimationUtils.currentAnimationTimeMillis();
+ final float deltaT = (time - mStartTime) / 1000f; // Convert from millis to seconds
+ if (deltaT < 0.001f) {
+ return; // Must have at least 1 ms difference
+ }
+ final double mDampedFreq = NATURAL_FREQUENCY * Math.sqrt(1 - DAMPING_RATIO * DAMPING_RATIO);
+
+ // We're always underdamped, so we can use only those equations:
+ double cosCoeff = mDistance;
+ double sinCoeff = (1 / mDampedFreq) * (DAMPING_RATIO * NATURAL_FREQUENCY
+ * mDistance + mVelocity);
+ double distance = Math.pow(Math.E, -DAMPING_RATIO * NATURAL_FREQUENCY * deltaT)
+ * (cosCoeff * Math.cos(mDampedFreq * deltaT)
+ + sinCoeff * Math.sin(mDampedFreq * deltaT));
+ double velocity = distance * (-NATURAL_FREQUENCY) * DAMPING_RATIO
+ + Math.pow(Math.E, -DAMPING_RATIO * NATURAL_FREQUENCY * deltaT)
+ * (-mDampedFreq * cosCoeff * Math.sin(mDampedFreq * deltaT)
+ + mDampedFreq * sinCoeff * Math.cos(mDampedFreq * deltaT));
+ mDistance = (float) distance;
+ mVelocity = (float) velocity;
+ mStartTime = time;
+ if (isAtEquilibrium()) {
+ mState = STATE_IDLE;
+ mDistance = 0;
+ mVelocity = 0;
+ }
+ }
+
/**
* @return The estimated pull distance as calculated from mGlowScaleY.
*/
@@ -692,4 +780,15 @@ public class EdgeEffect {
}
return alpha / PULL_DISTANCE_ALPHA_GLOW_FACTOR;
}
+
+ /**
+ * @return true if the spring used for calculating the stretch animation is
+ * considered at rest or false if it is still animating.
+ */
+ private boolean isAtEquilibrium() {
+ double velocity = mVelocity * mHeight; // in pixels/second
+ double displacement = mDistance * mHeight; // in pixels
+ return Math.abs(velocity) < VELOCITY_THRESHOLD
+ && Math.abs(displacement) < VALUE_THRESHOLD;
+ }
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index fdc66fcb81d8..9e97f9aaed42 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -195,6 +195,7 @@ import android.view.textclassifier.TextLinks;
import android.view.textservice.SpellCheckerSubtype;
import android.view.textservice.TextServicesManager;
import android.view.translation.TranslationRequestValue;
+import android.view.translation.UiTranslationController;
import android.view.translation.ViewTranslationRequest;
import android.view.translation.ViewTranslationResponse;
import android.widget.RemoteViews.RemoteView;
@@ -13835,6 +13836,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public ViewTranslationRequest onCreateTranslationRequest() {
if (mText == null || mText.length() == 0) {
+ // TODO(b/182433547): remove before S release
+ if (UiTranslationController.DEBUG) {
+ Log.w(LOG_TAG, "Cannot create translation request for the empty text.");
+ }
return null;
}
// Not translate password, editable text and not important for translation
@@ -13842,6 +13847,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// text selection apis, not support in S.
boolean isPassword = isAnyPasswordInputType() || hasPasswordTransformationMethod();
if (isTextEditable() || isPassword || isTextSelectable()) {
+ // TODO(b/182433547): remove before S release
+ if (UiTranslationController.DEBUG) {
+ Log.w(LOG_TAG, "Cannot create translation request. editable = " + isTextEditable()
+ + ", isPassword = " + isPassword + ", selectable = " + isTextSelectable());
+ }
return null;
}
// TODO(b/176488462): apply the view's important for translation property
@@ -13870,6 +13880,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Restore to original text content.
if (mTranslationTransformation != null) {
setTransformationMethod(mTranslationTransformation.getOriginalTransformationMethod());
+ } else {
+ // TODO(b/182433547): remove before S release
+ Log.w(LOG_TAG, "onPauseUiTranslation(): no translated text.");
}
}
@@ -13889,7 +13902,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mTranslationTransformation != null) {
setTransformationMethod(mTranslationTransformation);
} else {
- Log.w(LOG_TAG, "onResumeTranslatedText(): no translated text.");
+ // TODO(b/182433547): remove before S release
+ Log.w(LOG_TAG, "onRestoreUiTranslation(): no translated text.");
}
}
@@ -13910,6 +13924,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mTranslationTransformation != null) {
setTransformationMethod(mTranslationTransformation.getOriginalTransformationMethod());
mTranslationTransformation = null;
+ } else {
+ // TODO(b/182433547): remove before S release
+ Log.w(LOG_TAG, "onFinishUiTranslation(): no translated text.");
}
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 6cfd49888fac..d4d853624700 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1119,7 +1119,7 @@ public class ChooserActivity extends ResolverActivity implements
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(
Context.CLIPBOARD_SERVICE);
- clipboardManager.setPrimaryClip(clipData);
+ clipboardManager.setPrimaryClipAsPackage(clipData, getReferrerPackageName());
Toast.makeText(getApplicationContext(), R.string.copied, Toast.LENGTH_SHORT).show();
// Log share completion via copy
diff --git a/core/java/com/android/internal/graphics/palette/Mean.java b/core/java/com/android/internal/graphics/palette/Mean.java
index 894f91b6261c..bde036349d3b 100644
--- a/core/java/com/android/internal/graphics/palette/Mean.java
+++ b/core/java/com/android/internal/graphics/palette/Mean.java
@@ -22,20 +22,19 @@ import java.util.Random;
* Represents a centroid in Kmeans algorithms.
*/
public class Mean {
- private static final Random RANDOM = new Random(0);
-
public float[] center;
/**
* Constructor.
*
* @param upperBound maximum value of a dimension in the space Kmeans is optimizing in
+ * @param random used to generate a random center
*/
- Mean(int upperBound) {
+ Mean(int upperBound, Random random) {
center =
new float[]{
- RANDOM.nextInt(upperBound + 1), RANDOM.nextInt(upperBound + 1),
- RANDOM.nextInt(upperBound + 1)
+ random.nextInt(upperBound + 1), random.nextInt(upperBound + 1),
+ random.nextInt(upperBound + 1)
};
}
diff --git a/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java b/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java
index a87a34f4ae11..b4f216ba87fa 100644
--- a/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java
+++ b/core/java/com/android/internal/graphics/palette/WSMeansQuantizer.java
@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Random;
import java.util.Set;
@@ -57,13 +58,27 @@ public class WSMeansQuantizer implements Quantizer {
}
if (maxColors > means.length) {
+ // Always initialize Random with the same seed. Ensures the results of quantization
+ // are consistent, even when random centroids are required.
+ Random random = new Random(0x42688);
int randomMeansToCreate = maxColors - means.length;
for (int i = 0; i < randomMeansToCreate; i++) {
- mMeans[means.length + i] = new Mean(100);
+ mMeans[means.length + i] = new Mean(100, random);
}
}
for (int pixel : pixels) {
+ // These are pixels from the bitmap that is being quantized.
+ // Depending on the bitmap & downscaling, it may have pixels that are less than opaque
+ // Ignore those pixels.
+ ///
+ // Note: they don't _have_ to be ignored, for example, we could instead turn them
+ // opaque. Traditionally, including outside Android, quantizers ignore transparent
+ // pixels, so that strategy was chosen.
+ int alpha = (pixel >> 24);
+ if (alpha < 255) {
+ continue;
+ }
Integer currentCount = mCountByColor.get(pixel);
if (currentCount == null) {
currentCount = 0;
@@ -105,8 +120,12 @@ public class WSMeansQuantizer implements Quantizer {
/** Create random starting centroids for K-means. */
public static float[][] randomMeans(int maxColors, int upperBound) {
float[][] means = new float[maxColors][];
+
+ // Always initialize Random with the same seed. Ensures the results of quantization
+ // are consistent, even when random centroids are required.
+ Random random = new Random(0x42688);
for (int i = 0; i < maxColors; i++) {
- means[i] = new Mean(upperBound).center;
+ means[i] = new Mean(upperBound, random).center;
}
return means;
}
diff --git a/core/java/com/android/internal/graphics/palette/WuQuantizer.java b/core/java/com/android/internal/graphics/palette/WuQuantizer.java
index 66206bf8297a..a2652ea6d5e1 100644
--- a/core/java/com/android/internal/graphics/palette/WuQuantizer.java
+++ b/core/java/com/android/internal/graphics/palette/WuQuantizer.java
@@ -78,7 +78,12 @@ public class WuQuantizer implements Quantizer {
// All of the sample Wu implementations are reimplementations of a snippet of C code from
// the early 90s. They all cap the maximum # of colors at 256, and it is impossible to tell
// if this is a requirement, a consequence of QUANT_SIZE, or arbitrary.
- this.mMaxColors = Math.min(MAX_COLORS, maxColorCount);
+ //
+ // Also, the number of maximum colors should be capped at the number of pixels - otherwise,
+ // If extraction is run on a set of pixels whose count is less than max colors,
+ // then colors.length < max colors, and accesses to colors[index] throw an
+ // ArrayOutOfBoundsException.
+ this.mMaxColors = Math.min(Math.min(MAX_COLORS, maxColorCount), colors.length);
Box[] cube = new Box[mMaxColors];
int red, green, blue;
@@ -119,17 +124,13 @@ public class WuQuantizer implements Quantizer {
}
}
- // If extraction is run on a set of pixels whose count is less than the
- // number of max colors, then colors.length < max colors, and accesses
- // to colors[index] inside the for loop throw an ArrayOutOfBoundsException.
- int numColorsToCreate = (int) Math.min(mMaxColors, colors.length);
- for (k = 0; k < numColorsToCreate; ++k) {
+ for (k = 0; k < mMaxColors; ++k) {
weight = getVolume(cube[k], mWt);
if (weight > 0) {
red = (int) (getVolume(cube[k], mMr) / weight);
green = (int) (getVolume(cube[k], mMg) / weight);
blue = (int) (getVolume(cube[k], mMb) / weight);
- colors[k] = ((red & 0x0ff) << 16) | ((green & 0x0ff) << 8) | (blue & 0x0ff);
+ colors[k] = (255 << 24) | (red << 16) | (green << 8) | blue;
} else {
colors[k] = 0;
}
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index c897002c88e9..7f0178e29d85 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -16,7 +16,6 @@
package com.android.internal.jank;
-import static android.view.SurfaceControl.JankData.BUFFER_STUFFING;
import static android.view.SurfaceControl.JankData.DISPLAY_HAL;
import static android.view.SurfaceControl.JankData.JANK_APP_DEADLINE_MISSED;
import static android.view.SurfaceControl.JankData.JANK_NONE;
@@ -42,6 +41,7 @@ import android.view.SurfaceControl.JankData.JankType;
import android.view.ThreadedRenderer;
import android.view.ViewRootImpl;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor.Session;
import com.android.internal.util.FrameworkStatsLog;
@@ -163,6 +163,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
}, 50);
}
};
+
+ // This callback has a reference to FrameTracker, remember to remove it to avoid leakage.
viewRootWrapper.addSurfaceChangedCallback(mSurfaceChangedCallback);
}
@@ -187,9 +189,13 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
*/
public synchronized void end() {
mEndVsyncId = mChoreographer.getVsyncId();
- Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
- if (mEndVsyncId == mBeginVsyncId) {
+ // Cancel the session if:
+ // 1. The session begins and ends at the same vsync id.
+ // 2. The session never begun.
+ if (mEndVsyncId == mBeginVsyncId || mBeginVsyncId == INVALID_ID) {
cancel();
+ } else {
+ Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
}
// We don't remove observer here,
// will remove it when all the frame metrics in this duration are called back.
@@ -200,11 +206,18 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
* Cancel the trace session of the CUJ.
*/
public synchronized void cancel() {
- if (mBeginVsyncId == INVALID_ID || mEndVsyncId != INVALID_ID) return;
- Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
+ // We don't need to end the trace section if it never begun.
+ if (mBeginVsyncId != INVALID_ID) {
+ Trace.endAsyncSection(mSession.getName(), (int) mBeginVsyncId);
+ }
mCancelled = true;
+
+ // Always remove the observers in cancel call to avoid leakage.
removeObservers();
- if (mListener != null) {
+
+ // Notify the listener the session has been cancelled.
+ // We don't notify the listeners if the session never begun.
+ if (mListener != null && mBeginVsyncId != INVALID_ID) {
mListener.onNotifyCujEvents(mSession, InteractionJankMonitor.ACTION_SESSION_CANCEL);
}
}
@@ -393,7 +406,11 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
}
}
- private void removeObservers() {
+ /**
+ * Remove all the registered listeners, observers and callbacks.
+ */
+ @VisibleForTesting
+ public void removeObservers() {
mRendererWrapper.removeObserver(mObserver);
mSurfaceControlWrapper.removeJankStatsListener(this);
if (mSurfaceChangedCallback != null) {
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index b3e8db205220..14b870575769 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -120,8 +120,13 @@ public class BinderCallsStats implements BinderInternal.Observer {
UidEntry uidEntry = mUidEntries.get(mSendUidsToObserver.valueAt(i));
if (uidEntry != null) {
ArrayMap<CallStatKey, CallStat> callStats = uidEntry.mCallStats;
+ final int csize = callStats.size();
+ final ArrayList<CallStat> tmpCallStats = new ArrayList<>(csize);
+ for (int j = 0; j < csize; j++) {
+ tmpCallStats.add(callStats.valueAt(j).clone());
+ }
mCallStatsObserver.noteCallStats(uidEntry.workSourceUid,
- uidEntry.incrementalCallCount, callStats.values()
+ uidEntry.incrementalCallCount, tmpCallStats
);
uidEntry.incrementalCallCount = 0;
for (int j = callStats.size() - 1; j >= 0; j--) {
@@ -830,6 +835,23 @@ public class BinderCallsStats implements BinderInternal.Observer {
}
@Override
+ public CallStat clone() {
+ CallStat clone = new CallStat(callingUid, binderClass, transactionCode,
+ screenInteractive);
+ clone.recordedCallCount = recordedCallCount;
+ clone.callCount = callCount;
+ clone.cpuTimeMicros = cpuTimeMicros;
+ clone.maxCpuTimeMicros = maxCpuTimeMicros;
+ clone.latencyMicros = latencyMicros;
+ clone.maxLatencyMicros = maxLatencyMicros;
+ clone.maxRequestSizeBytes = maxRequestSizeBytes;
+ clone.maxReplySizeBytes = maxReplySizeBytes;
+ clone.exceptionCount = exceptionCount;
+ clone.incrementalCallCount = incrementalCallCount;
+ return clone;
+ }
+
+ @Override
public String toString() {
// This is expensive, but CallStat.toString() is only used for debugging.
String methodName = new BinderTransactionNameResolver().getMethodName(binderClass,
diff --git a/core/java/com/android/internal/os/SelectedProcessCpuThreadReader.java b/core/java/com/android/internal/os/SelectedProcessCpuThreadReader.java
new file mode 100644
index 000000000000..2ffff73f18cf
--- /dev/null
+++ b/core/java/com/android/internal/os/SelectedProcessCpuThreadReader.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.annotation.Nullable;
+import android.os.Process;
+
+/**
+ * Reads CPU usage statistics about a selected process identified by its cmdline.
+ *
+ * Handles finding the pid for the process and delegates CPU usage reading from the eBPF map to
+ * KernelSingleProcessCpuThreadReader. Exactly one long-lived instance of the process is expected.
+ * Otherwise, no statistics are returned.
+ *
+ * See also SystemServerCpuThreadReader.
+ */
+public final class SelectedProcessCpuThreadReader {
+ private final String[] mCmdline;
+
+ private int mPid;
+ private KernelSingleProcessCpuThreadReader mKernelCpuThreadReader;
+
+ public SelectedProcessCpuThreadReader(String cmdline) {
+ mCmdline = new String[] { cmdline };
+ }
+
+ /** Returns CPU times, per thread group, since tracking started. */
+ @Nullable
+ public KernelSingleProcessCpuThreadReader.ProcessCpuUsage readAbsolute() {
+ int[] pids = Process.getPidsForCommands(mCmdline);
+ if (pids == null || pids.length != 1) {
+ return null;
+ }
+ int pid = pids[0];
+ if (mPid == pid) {
+ return mKernelCpuThreadReader.getProcessCpuUsage();
+ }
+ mPid = pid;
+ mKernelCpuThreadReader = KernelSingleProcessCpuThreadReader.create(mPid);
+ mKernelCpuThreadReader.startTrackingThreadCpuTimes();
+ return null;
+ }
+}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index d5b778e9c9e1..47b0f8c2be0c 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -651,8 +651,6 @@ public class ZygoteInit {
*/
private static void performSystemServerDexOpt(String classPath) {
final String[] classPathElements = classPath.split(":");
- final IInstalld installd = IInstalld.Stub
- .asInterface(ServiceManager.getService("installd"));
final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
String classPathForElement = "";
@@ -689,6 +687,10 @@ public class ZygoteInit {
final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
final String seInfo = null;
final int targetSdkVersion = 0; // SystemServer targets the system's SDK version
+ // Wait for installd to be made available
+ IInstalld installd = IInstalld.Stub.asInterface(
+ ServiceManager.waitForService("installd"));
+
try {
installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
instructionSet, dexoptNeeded, outputPath, dexFlags, systemServerFilter,
diff --git a/core/java/com/android/internal/protolog/BaseProtoLogImpl.java b/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
index bed85aed3625..83309fc61009 100644
--- a/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/BaseProtoLogImpl.java
@@ -359,18 +359,6 @@ public class BaseProtoLogImpl {
+ "\nLogging definitions loaded: " + mViewerConfig.knownViewerStringsNumber();
}
- /**
- * Writes the log buffer to a new file for the bugreport.
- *
- * This method is synchronized with {@code #startProtoLog(PrintWriter)} and
- * {@link #stopProtoLog(PrintWriter, boolean)}.
- */
- public void writeProtoLogToFile() {
- synchronized (mProtoLogEnabledLock) {
- writeProtoLogToFileLocked();
- }
- }
-
private void writeProtoLogToFileLocked() {
try {
long offset =
diff --git a/core/java/com/android/internal/security/OWNERS b/core/java/com/android/internal/security/OWNERS
new file mode 100644
index 000000000000..41d1d6687c42
--- /dev/null
+++ b/core/java/com/android/internal/security/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 36824
+
+per-file VerityUtils.java = victorhsieh@google.com
diff --git a/services/core/java/com/android/server/security/TEST_MAPPING b/core/java/com/android/internal/security/TEST_MAPPING
index 9a5e90e8681f..9a5e90e8681f 100644
--- a/services/core/java/com/android/server/security/TEST_MAPPING
+++ b/core/java/com/android/internal/security/TEST_MAPPING
diff --git a/services/core/java/com/android/server/security/VerityUtils.java b/core/java/com/android/internal/security/VerityUtils.java
index 48a60387fee7..ef703a996001 100644
--- a/services/core/java/com/android/server/security/VerityUtils.java
+++ b/core/java/com/android/internal/security/VerityUtils.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.security;
+package com.android.internal.security;
import android.annotation.NonNull;
import android.os.Build;
@@ -42,7 +42,7 @@ import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/** Provides fsverity related operations. */
-abstract public class VerityUtils {
+public abstract class VerityUtils {
private static final String TAG = "VerityUtils";
/**
@@ -156,8 +156,8 @@ abstract public class VerityUtils {
return SetupResult.failed();
}
return SetupResult.ok(Os.dup(rfd), contentSize);
- } catch (IOException | SecurityException | DigestException | NoSuchAlgorithmException |
- SignatureNotFoundException | ErrnoException e) {
+ } catch (IOException | SecurityException | DigestException | NoSuchAlgorithmException
+ | SignatureNotFoundException | ErrnoException e) {
Slog.e(TAG, "Failed to set up apk verity: ", e);
return SetupResult.failed();
} finally {
@@ -243,14 +243,20 @@ abstract public class VerityUtils {
private final FileDescriptor mFileDescriptor;
private final int mContentSize;
+ /** @deprecated */
+ @Deprecated
public static SetupResult ok(@NonNull FileDescriptor fileDescriptor, int contentSize) {
return new SetupResult(RESULT_OK, fileDescriptor, contentSize);
}
+ /** @deprecated */
+ @Deprecated
public static SetupResult skipped() {
return new SetupResult(RESULT_SKIPPED, null, -1);
}
+ /** @deprecated */
+ @Deprecated
public static SetupResult failed() {
return new SetupResult(RESULT_FAILED, null, -1);
}
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index ee94ef8ddda3..85114e59cc2d 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -42,7 +42,8 @@ oneway interface IPhoneStateListener {
// Uses CellIdentity which is Parcelable here; will convert to CellLocation in client.
void onCellLocationChanged(in CellIdentity location);
- void onCallStateChanged(int state, String incomingNumber);
+ void onLegacyCallStateChanged(int state, String incomingNumber);
+ void onCallStateChanged(int state);
void onDataConnectionStateChanged(int state, int networkType);
void onDataActivity(int direction);
void onSignalStrengthsChanged(in SignalStrength signalStrength);
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index dc6880e4f997..90c728293eb0 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -175,7 +175,7 @@ public class LatencyTracker {
mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED);
for (int action : ACTIONS_ALL) {
mTraceThresholdPerAction[action] =
- properties.getInt(getTraceTriggerNameForAction(action), -1);
+ properties.getInt(getNameOfAction(STATSD_ACTION[action]), -1);
}
}
}
diff --git a/core/java/com/android/internal/util/ScreenRecordHelper.java b/core/java/com/android/internal/util/ScreenRecordHelper.java
deleted file mode 100644
index ec7ed4e0008a..000000000000
--- a/core/java/com/android/internal/util/ScreenRecordHelper.java
+++ /dev/null
@@ -1,49 +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.internal.util;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-
-/**
- * Helper class to initiate a screen recording
- */
-public class ScreenRecordHelper {
- private final Context mContext;
-
- /**
- * Create a new ScreenRecordHelper for the given context
- * @param context
- */
- public ScreenRecordHelper(Context context) {
- mContext = context;
- }
-
- /**
- * Show dialog of screen recording options to user.
- */
- public void launchRecordPrompt() {
- final ComponentName launcherComponent = ComponentName.unflattenFromString(
- mContext.getResources().getString(
- com.android.internal.R.string.config_screenRecorderComponent));
- final Intent intent = new Intent();
- intent.setComponent(launcherComponent);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(intent);
- }
-}
diff --git a/core/java/com/android/internal/view/IInputMethod.aidl b/core/java/com/android/internal/view/IInputMethod.aidl
index c33637353984..8d82e33dc29f 100644
--- a/core/java/com/android/internal/view/IInputMethod.aidl
+++ b/core/java/com/android/internal/view/IInputMethod.aidl
@@ -35,7 +35,8 @@ import com.android.internal.view.InlineSuggestionsRequestInfo;
* {@hide}
*/
oneway interface IInputMethod {
- void initializeInternal(IBinder token, int displayId, IInputMethodPrivilegedOperations privOps);
+ void initializeInternal(IBinder token, int displayId, IInputMethodPrivilegedOperations privOps,
+ int configChanges);
void onCreateInlineSuggestionsRequest(in InlineSuggestionsRequestInfo requestInfo,
in IInlineSuggestionsRequestCallback cb);
diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java
index e143498293f3..2695b9c7651f 100644
--- a/core/java/com/android/internal/widget/ImageFloatingTextView.java
+++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java
@@ -36,8 +36,10 @@ import android.widget.TextView;
@RemoteViews.RemoteView
public class ImageFloatingTextView extends TextView {
- /** Number of lines from the top to indent */
- private int mIndentLines;
+ /** Number of lines from the top to indent. */
+ private int mIndentLines = 0;
+ /** Whether or not there is an image to indent for. */
+ private boolean mHasImage = false;
/** Resolved layout direction */
private int mResolvedDirection = LAYOUT_DIRECTION_UNDEFINED;
@@ -96,7 +98,7 @@ public class ImageFloatingTextView extends TextView {
// we set the endmargin on the requested number of lines.
int[] margins = null;
- if (mIndentLines > 0) {
+ if (mHasImage && mIndentLines > 0) {
margins = new int[mIndentLines + 1];
for (int i = 0; i < mIndentLines; i++) {
margins[i] = mImageEndMargin;
@@ -111,9 +113,24 @@ public class ImageFloatingTextView extends TextView {
return builder.build();
}
+ /**
+ * @param imageEndMargin the end margin (in pixels) to indent the first few lines of the text
+ */
@RemotableViewMethod
public void setImageEndMargin(int imageEndMargin) {
- mImageEndMargin = imageEndMargin;
+ if (mImageEndMargin != imageEndMargin) {
+ mImageEndMargin = imageEndMargin;
+ invalidateTextIfIndenting();
+ }
+ }
+
+ /**
+ * @param imageEndMarginDp the end margin (in dp) to indent the first few lines of the text
+ */
+ @RemotableViewMethod
+ public void setImageEndMarginDp(float imageEndMarginDp) {
+ setImageEndMargin(
+ (int) (imageEndMarginDp * getResources().getDisplayMetrics().density));
}
@Override
@@ -121,7 +138,7 @@ public class ImageFloatingTextView extends TextView {
int availableHeight = MeasureSpec.getSize(heightMeasureSpec) - mPaddingTop - mPaddingBottom;
if (getLayout() != null && getLayout().getHeight() != availableHeight) {
// We've been measured before and the new size is different than before, lets make sure
- // we reset the maximum lines, otherwise we may be cut short
+ // we reset the maximum lines, otherwise the last line of text may be partially cut off
mMaxLinesForHeight = -1;
nullLayouts();
}
@@ -130,7 +147,7 @@ public class ImageFloatingTextView extends TextView {
if (layout.getHeight() > availableHeight) {
// With the existing layout, not all of our lines fit on the screen, let's find the
// first one that fits and ellipsize at that one.
- int maxLines = layout.getLineCount() - 1;
+ int maxLines = layout.getLineCount();
while (maxLines > 1 && layout.getLineBottom(maxLines - 1) > availableHeight) {
maxLines--;
}
@@ -152,31 +169,43 @@ public class ImageFloatingTextView extends TextView {
if (layoutDirection != mResolvedDirection && isLayoutDirectionResolved()) {
mResolvedDirection = layoutDirection;
- if (mIndentLines > 0) {
- // Invalidate layout.
- nullLayouts();
- requestLayout();
- }
+ invalidateTextIfIndenting();
+ }
+ }
+
+ private void invalidateTextIfIndenting() {
+ if (mHasImage && mIndentLines > 0) {
+ // Invalidate layout.
+ nullLayouts();
+ requestLayout();
}
}
+ /**
+ * @param hasImage whether there is an image to wrap text around.
+ */
@RemotableViewMethod
public void setHasImage(boolean hasImage) {
- setNumIndentLines(hasImage ? 2 : 0);
+ setHasImageAndNumIndentLines(hasImage, mIndentLines);
}
/**
* @param lines the number of lines at the top that should be indented by indentEnd
- * @return whether a change was made
*/
- public boolean setNumIndentLines(int lines) {
- if (mIndentLines != lines) {
- mIndentLines = lines;
- // Invalidate layout.
+ @RemotableViewMethod
+ public void setNumIndentLines(int lines) {
+ setHasImageAndNumIndentLines(mHasImage, lines);
+ }
+
+ private void setHasImageAndNumIndentLines(boolean hasImage, int lines) {
+ int oldEffectiveLines = mHasImage ? mIndentLines : 0;
+ int newEffectiveLines = hasImage ? lines : 0;
+ mIndentLines = lines;
+ mHasImage = hasImage;
+ if (oldEffectiveLines != newEffectiveLines) {
+ // always invalidate layout.
nullLayouts();
requestLayout();
- return true;
}
- return false;
}
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index d6d33873adaa..a153fab10214 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -1,4 +1,3 @@
-
package {
default_applicable_licenses: ["frameworks_base_core_jni_license"],
}
@@ -69,10 +68,9 @@ cc_library_shared {
"liblog",
"libminikin",
"libz",
- "libziparchive",
],
- static_libs: ["libnativehelper_lazy"],
+ static_libs: ["libnativehelper_lazy", "libziparchive_for_incfs", ],
export_include_dirs: [
".",
@@ -214,10 +212,12 @@ cc_library_shared {
"com_android_internal_os_Zygote.cpp",
"com_android_internal_os_ZygoteCommandBuffer.cpp",
"com_android_internal_os_ZygoteInit.cpp",
+ "com_android_internal_security_VerityUtils.cpp",
"hwbinder/EphemeralStorage.cpp",
"fd_utils.cpp",
"android_hardware_input_InputWindowHandle.cpp",
"android_hardware_input_InputApplicationHandle.cpp",
+ "permission_utils.cpp",
],
static_libs: [
@@ -236,6 +236,7 @@ cc_library_shared {
"audioflinger-aidl-cpp",
"av-types-aidl-cpp",
"android.hardware.camera.device@3.2",
+ "media_permission-aidl-cpp",
"libandroidicu",
"libbpf_android",
"libnetdbpf",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index ddd861380fab..3bc0ef4ee3a0 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -97,6 +97,7 @@ extern int register_android_media_AudioVolumeGroupChangeHandler(JNIEnv *env);
extern int register_android_media_MicrophoneInfo(JNIEnv *env);
extern int register_android_media_ToneGenerator(JNIEnv *env);
extern int register_android_media_midi(JNIEnv *env);
+extern int register_android_media_permission_Identity(JNIEnv* env);
namespace android {
@@ -200,6 +201,7 @@ extern int register_com_android_internal_os_KernelSingleUidTimeReader(JNIEnv *en
extern int register_com_android_internal_os_Zygote(JNIEnv *env);
extern int register_com_android_internal_os_ZygoteCommandBuffer(JNIEnv *env);
extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env);
+extern int register_com_android_internal_security_VerityUtils(JNIEnv* env);
extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
// Namespace for Android Runtime flags applied during boot time.
@@ -1534,6 +1536,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_Zygote),
REG_JNI(register_com_android_internal_os_ZygoteCommandBuffer),
REG_JNI(register_com_android_internal_os_ZygoteInit),
+ REG_JNI(register_com_android_internal_security_VerityUtils),
REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
REG_JNI(register_android_hardware_Camera),
REG_JNI(register_android_hardware_camera2_CameraMetadata),
@@ -1562,6 +1565,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_media_RemoteDisplay),
REG_JNI(register_android_media_ToneGenerator),
REG_JNI(register_android_media_midi),
+ REG_JNI(register_android_media_permission_Identity),
REG_JNI(register_android_opengl_classes),
REG_JNI(register_android_server_NetworkManagementSocketTagger),
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 0e0f98ec1fc4..7d3febbd5d14 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -22,6 +22,7 @@
#include <jni.h>
#include <nativehelper/JNIHelp.h>
#include "core_jni_helpers.h"
+#include "permission_utils.h"
#include <utils/Log.h>
#include <media/AudioRecord.h>
@@ -39,6 +40,9 @@
// ----------------------------------------------------------------------------
+using android::media::permission::convertIdentity;
+using android::media::permission::Identity;
+
using namespace android;
// ----------------------------------------------------------------------------
@@ -181,12 +185,11 @@ static sp<AudioRecord> setAudioRecord(JNIEnv* env, jobject thiz, const sp<AudioR
}
// ----------------------------------------------------------------------------
-static jint
-android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
- jobject jaa, jintArray jSampleRate, jint channelMask, jint channelIndexMask,
- jint audioFormat, jint buffSizeInBytes, jintArray jSession, jstring opPackageName,
- jlong nativeRecordInJavaObj)
-{
+static jint android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
+ jobject jaa, jintArray jSampleRate, jint channelMask,
+ jint channelIndexMask, jint audioFormat,
+ jint buffSizeInBytes, jintArray jSession,
+ jobject jIdentity, jlong nativeRecordInJavaObj) {
//ALOGV(">> Entering android_media_AudioRecord_setup");
//ALOGV("sampleRate=%d, audioFormat=%d, channel mask=%x, buffSizeInBytes=%d "
// "nativeRecordInJavaObj=0x%llX",
@@ -262,10 +265,8 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
size_t frameSize = channelCount * bytesPerSample;
size_t frameCount = buffSizeInBytes / frameSize;
- ScopedUtfChars opPackageNameStr(env, opPackageName);
-
// create an uninitialized AudioRecord object
- lpRecorder = new AudioRecord(String16(opPackageNameStr.c_str()));
+ lpRecorder = new AudioRecord(convertIdentity(env, jIdentity));
// read the AudioAttributes values
auto paa = JNIAudioAttributeHelper::makeUnique();
@@ -373,8 +374,6 @@ native_init_failure:
return (jint) AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED;
}
-
-
// ----------------------------------------------------------------------------
static jint
android_media_AudioRecord_start(JNIEnv *env, jobject thiz, jint event, jint triggerSession)
@@ -893,9 +892,11 @@ static jint android_media_AudioRecord_get_port_id(JNIEnv *env, jobject thiz) {
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
static const JNINativeMethod gMethods[] = {
+ // name, signature, funcPtr
{"native_start", "(II)I", (void *)android_media_AudioRecord_start},
{"native_stop", "()V", (void *)android_media_AudioRecord_stop},
- {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIII[ILjava/lang/String;J)I",
+ {"native_setup",
+ "(Ljava/lang/Object;Ljava/lang/Object;[IIIII[ILandroid/media/permission/Identity;J)I",
(void *)android_media_AudioRecord_setup},
{"native_finalize", "()V", (void *)android_media_AudioRecord_finalize},
{"native_release", "()V", (void *)android_media_AudioRecord_release},
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 94bd28a59e7c..f102edc79e7f 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2204,13 +2204,11 @@ android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP(
return jStatus;
}
-static jint
-android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
- jobject jSurroundFormats, jboolean reported)
-{
+static jint android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
+ jobject jSurroundFormats) {
ALOGV("getSurroundFormats");
- if (jSurroundFormats == NULL) {
+ if (jSurroundFormats == nullptr) {
ALOGE("jSurroundFormats is NULL");
return (jint)AUDIO_JAVA_BAD_VALUE;
}
@@ -2221,10 +2219,10 @@ android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
jint jStatus;
unsigned int numSurroundFormats = 0;
- audio_format_t *surroundFormats = NULL;
- bool *surroundFormatsEnabled = NULL;
- status_t status = AudioSystem::getSurroundFormats(
- &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
+ audio_format_t *surroundFormats = nullptr;
+ bool *surroundFormatsEnabled = nullptr;
+ status_t status = AudioSystem::getSurroundFormats(&numSurroundFormats, surroundFormats,
+ surroundFormatsEnabled);
if (status != NO_ERROR) {
ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
jStatus = nativeToJavaStatus(status);
@@ -2236,8 +2234,8 @@ android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
}
surroundFormats = (audio_format_t *)calloc(numSurroundFormats, sizeof(audio_format_t));
surroundFormatsEnabled = (bool *)calloc(numSurroundFormats, sizeof(bool));
- status = AudioSystem::getSurroundFormats(
- &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
+ status = AudioSystem::getSurroundFormats(&numSurroundFormats, surroundFormats,
+ surroundFormatsEnabled);
jStatus = nativeToJavaStatus(status);
if (status != NO_ERROR) {
ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
@@ -2258,6 +2256,50 @@ exit:
return jStatus;
}
+static jint android_media_AudioSystem_getReportedSurroundFormats(JNIEnv *env, jobject thiz,
+ jobject jSurroundFormats) {
+ ALOGV("getReportedSurroundFormats");
+
+ if (jSurroundFormats == nullptr) {
+ ALOGE("jSurroundFormats is NULL");
+ return (jint)AUDIO_JAVA_BAD_VALUE;
+ }
+ if (!env->IsInstanceOf(jSurroundFormats, gArrayListClass)) {
+ ALOGE("jSurroundFormats not an arraylist");
+ return (jint)AUDIO_JAVA_BAD_VALUE;
+ }
+ jint jStatus;
+ unsigned int numSurroundFormats = 0;
+ audio_format_t *surroundFormats = nullptr;
+ status_t status = AudioSystem::getReportedSurroundFormats(&numSurroundFormats, surroundFormats);
+ if (status != NO_ERROR) {
+ ALOGE_IF(status != NO_ERROR, "AudioSystem::getReportedSurroundFormats error %d", status);
+ jStatus = nativeToJavaStatus(status);
+ goto exit;
+ }
+ if (numSurroundFormats == 0) {
+ jStatus = (jint)AUDIO_JAVA_SUCCESS;
+ goto exit;
+ }
+ surroundFormats = (audio_format_t *)calloc(numSurroundFormats, sizeof(audio_format_t));
+ status = AudioSystem::getReportedSurroundFormats(&numSurroundFormats, surroundFormats);
+ jStatus = nativeToJavaStatus(status);
+ if (status != NO_ERROR) {
+ ALOGE_IF(status != NO_ERROR, "AudioSystem::getReportedSurroundFormats error %d", status);
+ goto exit;
+ }
+ for (size_t i = 0; i < numSurroundFormats; i++) {
+ jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor,
+ audioFormatFromNative(surroundFormats[i]));
+ env->CallObjectMethod(jSurroundFormats, gArrayListMethods.add, surroundFormat);
+ env->DeleteLocalRef(surroundFormat);
+ }
+
+exit:
+ free(surroundFormats);
+ return jStatus;
+}
+
static jint
android_media_AudioSystem_setSurroundFormatEnabled(JNIEnv *env, jobject thiz,
jint audioFormat, jboolean enabled)
@@ -2619,8 +2661,10 @@ static const JNINativeMethod gMethods[] =
(void *)android_media_AudioSystem_getOffloadSupport},
{"getMicrophones", "(Ljava/util/ArrayList;)I",
(void *)android_media_AudioSystem_getMicrophones},
- {"getSurroundFormats", "(Ljava/util/Map;Z)I",
+ {"getSurroundFormats", "(Ljava/util/Map;)I",
(void *)android_media_AudioSystem_getSurroundFormats},
+ {"getReportedSurroundFormats", "(Ljava/util/ArrayList;)I",
+ (void *)android_media_AudioSystem_getReportedSurroundFormats},
{"setSurroundFormatEnabled", "(IZ)I",
(void *)android_media_AudioSystem_setSurroundFormatEnabled},
{"setAssistantUid", "(I)I", (void *)android_media_AudioSystem_setAssistantUid},
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index cae6db57e99c..62767a676e8b 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -48,6 +48,7 @@
using namespace android;
using ::android::media::VolumeShaper;
+using ::android::media::permission::Identity;
// ----------------------------------------------------------------------------
static const char* const kClassPathName = "android/media/AudioTrack";
@@ -328,7 +329,10 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we
// create the native AudioTrack object
ScopedUtfChars opPackageNameStr(env, opPackageName);
- lpTrack = new AudioTrack(opPackageNameStr.c_str());
+ // TODO b/182469354: make consistent with AudioRecord
+ Identity identity = Identity();
+ identity.packageName = std::string(opPackageNameStr.c_str());
+ lpTrack = new AudioTrack(identity);
// read the AudioAttributes values
auto paa = JNIAudioAttributeHelper::makeUnique();
@@ -390,8 +394,8 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we
sessionId, // audio session ID
offload ? AudioTrack::TRANSFER_SYNC_NOTIF_CALLBACK
: AudioTrack::TRANSFER_SYNC,
- (offload || encapsulationMode) ? &offloadInfo : NULL, -1,
- -1, // default uid, pid values
+ (offload || encapsulationMode) ? &offloadInfo : NULL,
+ Identity(), // default uid, pid values
paa.get());
break;
@@ -416,8 +420,8 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we
true, // thread can call Java
sessionId, // audio session ID
AudioTrack::TRANSFER_SHARED,
- NULL, // default offloadInfo
- -1, -1, // default uid, pid values
+ NULL, // default offloadInfo
+ Identity(), // default uid, pid values
paa.get());
break;
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 5e142fd10de0..ab6633f395a8 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -57,6 +57,7 @@ static struct {
jmethodID dispatchInputEvent;
jmethodID onFocusEvent;
jmethodID onPointerCaptureEvent;
+ jmethodID onDragEvent;
jmethodID onBatchedInputEventPending;
} gInputEventReceiverClassInfo;
@@ -400,6 +401,18 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
finishInputEvent(seq, true /* handled */);
continue;
}
+ case AINPUT_EVENT_TYPE_DRAG: {
+ const DragEvent* dragEvent = static_cast<DragEvent*>(inputEvent);
+ if (kDebugDispatchCycle) {
+ ALOGD("channel '%s' ~ Received drag event: isExiting=%s",
+ getInputChannelName().c_str(), toString(dragEvent->isExiting()));
+ }
+ env->CallVoidMethod(receiverObj.get(), gInputEventReceiverClassInfo.onDragEvent,
+ jboolean(dragEvent->isExiting()), dragEvent->getX(),
+ dragEvent->getY());
+ finishInputEvent(seq, true /* handled */);
+ continue;
+ }
default:
assert(false); // InputConsumer should prevent this from ever happening
@@ -547,6 +560,8 @@ int register_android_view_InputEventReceiver(JNIEnv* env) {
gInputEventReceiverClassInfo.onPointerCaptureEvent =
GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onPointerCaptureEvent",
"(Z)V");
+ gInputEventReceiverClassInfo.onDragEvent =
+ GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onDragEvent", "(ZFF)V");
gInputEventReceiverClassInfo.onBatchedInputEventPending =
GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onBatchedInputEventPending",
"(I)V");
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index 9746a07a1b77..96326f591998 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -34,6 +34,8 @@
#include "core_jni_helpers.h"
+using android::base::Result;
+
namespace android {
// Log debug messages about the dispatch cycle.
@@ -197,16 +199,9 @@ status_t NativeInputEventSender::receiveFinishedSignals(JNIEnv* env) {
ScopedLocalRef<jobject> senderObj(env, NULL);
bool skipCallbacks = false;
for (;;) {
- uint32_t publishedSeq;
- bool handled;
- std::function<void(uint32_t seq, bool handled, nsecs_t consumeTime)> callback =
- [&publishedSeq, &handled](uint32_t inSeq, bool inHandled,
- nsecs_t inConsumeTime) -> void {
- publishedSeq = inSeq;
- handled = inHandled;
- };
- status_t status = mInputPublisher.receiveFinishedSignal(callback);
- if (status) {
+ Result<InputPublisher::Finished> result = mInputPublisher.receiveFinishedSignal();
+ if (!result.ok()) {
+ const status_t status = result.error().code();
if (status == WOULD_BLOCK) {
return OK;
}
@@ -215,7 +210,7 @@ status_t NativeInputEventSender::receiveFinishedSignals(JNIEnv* env) {
return status;
}
- auto it = mPublishedSeqMap.find(publishedSeq);
+ auto it = mPublishedSeqMap.find(result->seq);
if (it == mPublishedSeqMap.end()) {
continue;
}
@@ -225,9 +220,9 @@ status_t NativeInputEventSender::receiveFinishedSignals(JNIEnv* env) {
if (kDebugDispatchCycle) {
ALOGD("channel '%s' ~ Received finished signal, seq=%u, handled=%s, "
- "pendingEvents=%zu.",
- getInputChannelName().c_str(), seq, handled ? "true" : "false",
- mPublishedSeqMap.size());
+ "pendingEvents=%zu.",
+ getInputChannelName().c_str(), seq, result->handled ? "true" : "false",
+ mPublishedSeqMap.size());
}
if (!skipCallbacks) {
@@ -241,8 +236,9 @@ status_t NativeInputEventSender::receiveFinishedSignals(JNIEnv* env) {
}
env->CallVoidMethod(senderObj.get(),
- gInputEventSenderClassInfo.dispatchInputEventFinished,
- jint(seq), jboolean(handled));
+ gInputEventSenderClassInfo.dispatchInputEventFinished,
+ static_cast<jint>(result->seq),
+ static_cast<jboolean>(result->handled));
if (env->ExceptionCheck()) {
ALOGE("Exception dispatching finished signal.");
skipCallbacks = true;
diff --git a/core/jni/com_android_internal_os_KernelCpuBpfTracking.cpp b/core/jni/com_android_internal_os_KernelCpuBpfTracking.cpp
index 6b41b2ec8f93..d644e3709045 100644
--- a/core/jni/com_android_internal_os_KernelCpuBpfTracking.cpp
+++ b/core/jni/com_android_internal_os_KernelCpuBpfTracking.cpp
@@ -30,13 +30,13 @@ static jboolean KernelCpuBpfTracking_startTrackingInternal(JNIEnv *, jobject) {
static jlongArray KernelCpuBpfTracking_getFreqsInternal(JNIEnv *env, jobject) {
auto freqs = android::bpf::getCpuFreqs();
- if (!freqs) return NULL;
+ if (!freqs) return nullptr;
std::vector<uint64_t> allFreqs;
for (const auto &vec : *freqs) std::copy(vec.begin(), vec.end(), std::back_inserter(allFreqs));
auto ar = env->NewLongArray(allFreqs.size());
- if (ar != NULL) {
+ if (ar != nullptr) {
env->SetLongArrayRegion(ar, 0, allFreqs.size(),
reinterpret_cast<const jlong *>(allFreqs.data()));
}
@@ -45,7 +45,7 @@ static jlongArray KernelCpuBpfTracking_getFreqsInternal(JNIEnv *env, jobject) {
static jintArray KernelCpuBpfTracking_getFreqsClustersInternal(JNIEnv *env, jobject) {
auto freqs = android::bpf::getCpuFreqs();
- if (!freqs) return NULL;
+ if (!freqs) return nullptr;
std::vector<uint32_t> freqsClusters;
uint32_t clusters = freqs->size();
@@ -54,7 +54,7 @@ static jintArray KernelCpuBpfTracking_getFreqsClustersInternal(JNIEnv *env, jobj
}
auto ar = env->NewIntArray(freqsClusters.size());
- if (ar != NULL) {
+ if (ar != nullptr) {
env->SetIntArrayRegion(ar, 0, freqsClusters.size(),
reinterpret_cast<const jint *>(freqsClusters.data()));
}
diff --git a/core/jni/com_android_internal_os_KernelCpuTotalBpfMapReader.cpp b/core/jni/com_android_internal_os_KernelCpuTotalBpfMapReader.cpp
index ad43014d321f..472bd23c0f8d 100644
--- a/core/jni/com_android_internal_os_KernelCpuTotalBpfMapReader.cpp
+++ b/core/jni/com_android_internal_os_KernelCpuTotalBpfMapReader.cpp
@@ -22,7 +22,7 @@ namespace android {
static jlongArray KernelCpuTotalBpfMapReader_readInternal(JNIEnv *env, jobject) {
auto freqTimes = android::bpf::getTotalCpuFreqTimes();
- if (!freqTimes) return JNI_FALSE;
+ if (!freqTimes) return nullptr;
std::vector<uint64_t> allTimes;
for (const auto &vec : *freqTimes) {
@@ -32,7 +32,7 @@ static jlongArray KernelCpuTotalBpfMapReader_readInternal(JNIEnv *env, jobject)
}
auto ar = env->NewLongArray(allTimes.size());
- if (ar != NULL) {
+ if (ar != nullptr) {
env->SetLongArrayRegion(ar, 0, allTimes.size(),
reinterpret_cast<const jlong *>(allTimes.data()));
}
diff --git a/core/jni/com_android_internal_os_KernelCpuUidBpfMapReader.cpp b/core/jni/com_android_internal_os_KernelCpuUidBpfMapReader.cpp
index 7900d301dbb0..098a4d868269 100644
--- a/core/jni/com_android_internal_os_KernelCpuUidBpfMapReader.cpp
+++ b/core/jni/com_android_internal_os_KernelCpuUidBpfMapReader.cpp
@@ -37,7 +37,7 @@ static jlongArray getUidArray(JNIEnv *env, jobject sparseAr, uint32_t uid, jsize
jlongArray ar = (jlongArray)env->CallObjectMethod(sparseAr, gSparseArrayClassInfo.get, uid);
if (!ar) {
ar = env->NewLongArray(sz);
- if (ar == NULL) return ar;
+ if (ar == nullptr) return ar;
env->CallVoidMethod(sparseAr, gSparseArrayClassInfo.put, uid, ar);
}
return ar;
@@ -65,7 +65,7 @@ static jboolean KernelCpuUidFreqTimeBpfMapReader_readBpfData(JNIEnv *env, jobjec
static uint64_t lastUpdate = 0;
uint64_t newLastUpdate = lastUpdate;
auto sparseAr = env->GetObjectField(thiz, gmData);
- if (sparseAr == NULL) return false;
+ if (sparseAr == nullptr) return false;
auto data = android::bpf::getUidsUpdatedCpuFreqTimes(&newLastUpdate);
if (!data.has_value()) return false;
@@ -75,7 +75,7 @@ static jboolean KernelCpuUidFreqTimeBpfMapReader_readBpfData(JNIEnv *env, jobjec
for (const auto &subVec : times) s += subVec.size();
}
jlongArray ar = getUidArray(env, sparseAr, uid, s);
- if (ar == NULL) return false;
+ if (ar == nullptr) return false;
copy2DVecToArray(env, ar, times);
}
lastUpdate = newLastUpdate;
@@ -91,7 +91,7 @@ static jboolean KernelCpuUidActiveTimeBpfMapReader_readBpfData(JNIEnv *env, jobj
static uint64_t lastUpdate = 0;
uint64_t newLastUpdate = lastUpdate;
auto sparseAr = env->GetObjectField(thiz, gmData);
- if (sparseAr == NULL) return false;
+ if (sparseAr == nullptr) return false;
auto data = android::bpf::getUidsUpdatedConcurrentTimes(&newLastUpdate);
if (!data.has_value()) return false;
@@ -99,7 +99,7 @@ static jboolean KernelCpuUidActiveTimeBpfMapReader_readBpfData(JNIEnv *env, jobj
// TODO: revise calling code so we can divide by NSEC_PER_MSEC here instead
for (auto &time : times.active) time /= NSEC_PER_MSEC;
jlongArray ar = getUidArray(env, sparseAr, uid, times.active.size());
- if (ar == NULL) return false;
+ if (ar == nullptr) return false;
env->SetLongArrayRegion(ar, 0, times.active.size(),
reinterpret_cast<const jlong *>(times.active.data()));
}
@@ -111,7 +111,7 @@ static jlongArray KernelCpuUidActiveTimeBpfMapReader_getDataDimensions(JNIEnv *e
jlong nCpus = get_nprocs_conf();
auto ar = env->NewLongArray(1);
- if (ar != NULL) env->SetLongArrayRegion(ar, 0, 1, &nCpus);
+ if (ar != nullptr) env->SetLongArrayRegion(ar, 0, 1, &nCpus);
return ar;
}
@@ -124,7 +124,7 @@ static jboolean KernelCpuUidClusterTimeBpfMapReader_readBpfData(JNIEnv *env, job
static uint64_t lastUpdate = 0;
uint64_t newLastUpdate = lastUpdate;
auto sparseAr = env->GetObjectField(thiz, gmData);
- if (sparseAr == NULL) return false;
+ if (sparseAr == nullptr) return false;
auto data = android::bpf::getUidsUpdatedConcurrentTimes(&newLastUpdate);
if (!data.has_value()) return false;
@@ -134,7 +134,7 @@ static jboolean KernelCpuUidClusterTimeBpfMapReader_readBpfData(JNIEnv *env, job
for (const auto &subVec : times.policy) s += subVec.size();
}
jlongArray ar = getUidArray(env, sparseAr, uid, s);
- if (ar == NULL) return false;
+ if (ar == nullptr) return false;
copy2DVecToArray(env, ar, times.policy);
}
lastUpdate = newLastUpdate;
@@ -143,12 +143,12 @@ static jboolean KernelCpuUidClusterTimeBpfMapReader_readBpfData(JNIEnv *env, job
static jlongArray KernelCpuUidClusterTimeBpfMapReader_getDataDimensions(JNIEnv *env, jobject) {
auto times = android::bpf::getUidConcurrentTimes(0);
- if (!times.has_value()) return NULL;
+ if (!times.has_value()) return nullptr;
std::vector<jlong> clusterCores;
for (const auto &vec : times->policy) clusterCores.push_back(vec.size());
auto ar = env->NewLongArray(clusterCores.size());
- if (ar != NULL) env->SetLongArrayRegion(ar, 0, clusterCores.size(), clusterCores.data());
+ if (ar != nullptr) env->SetLongArrayRegion(ar, 0, clusterCores.size(), clusterCores.data());
return ar;
}
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 836074f1d5f7..cf96fe63f82c 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -184,6 +184,17 @@ static constexpr int PROCESS_PRIORITY_MIN = 19;
/** The numeric value for the normal priority a process should have. */
static constexpr int PROCESS_PRIORITY_DEFAULT = 0;
+/** Exponential back off parameters for storage dir check. */
+static constexpr unsigned int STORAGE_DIR_CHECK_RETRY_MULTIPLIER = 2;
+static constexpr unsigned int STORAGE_DIR_CHECK_INIT_INTERVAL_US = 50;
+static constexpr unsigned int STORAGE_DIR_CHECK_MAX_INTERVAL_US = 1000;
+/**
+ * Lower bound time we allow storage dir check to sleep.
+ * If it exceeds 2s, PROC_START_TIMEOUT_MSG will kill the starting app anyway,
+ * so it's fine to assume max retries is 5 mins.
+ */
+static constexpr int STORAGE_DIR_CHECK_TIMEOUT_US = 1000 * 60 * 5;
+
/**
* A helper class containing accounting information for USAPs.
*/
@@ -1458,6 +1469,31 @@ static void isolateJitProfile(JNIEnv* env, jobjectArray pkg_data_info_list,
}
}
+static void WaitUntilDirReady(const std::string& target, fail_fn_t fail_fn) {
+ unsigned int sleepIntervalUs = STORAGE_DIR_CHECK_INIT_INTERVAL_US;
+
+ // This is just an approximate value as it doesn't need to be very accurate.
+ unsigned int sleepTotalUs = 0;
+
+ const char* dir_path = target.c_str();
+ while (sleepTotalUs < STORAGE_DIR_CHECK_TIMEOUT_US) {
+ if (access(dir_path, F_OK) == 0) {
+ return;
+ }
+ // Failed, so we add exponential backoff and retry
+ usleep(sleepIntervalUs);
+ sleepTotalUs += sleepIntervalUs;
+ sleepIntervalUs = std::min<unsigned int>(
+ sleepIntervalUs * STORAGE_DIR_CHECK_RETRY_MULTIPLIER,
+ STORAGE_DIR_CHECK_MAX_INTERVAL_US);
+ }
+ // Last chance and get the latest errno if it fails.
+ if (access(dir_path, F_OK) == 0) {
+ return;
+ }
+ fail_fn(CREATE_ERROR("Error dir is not ready %s: %s", dir_path, strerror(errno)));
+}
+
static void BindMountStorageToLowerFs(const userid_t user_id, const uid_t uid,
const char* dir_name, const char* package, fail_fn_t fail_fn) {
bool hasSdcardFs = IsSdcardfsUsed();
@@ -1468,6 +1504,10 @@ static void BindMountStorageToLowerFs(const userid_t user_id, const uid_t uid,
source = StringPrintf("/mnt/pass_through/%d/emulated/%d/%s/%s", user_id, user_id, dir_name,
package);
}
+
+ // Directory might be not ready, as prepareStorageDirs() is running asynchronously in ProcessList,
+ // so wait until dir is created.
+ WaitUntilDirReady(source, fail_fn);
std::string target = StringPrintf("/storage/emulated/%d/%s/%s", user_id, dir_name, package);
// As the parent is mounted as tmpfs, we need to create the target dir here.
diff --git a/services/core/jni/com_android_server_security_VerityUtils.cpp b/core/jni/com_android_internal_security_VerityUtils.cpp
index dda44fb72cfc..411a392a075c 100644
--- a/services/core/jni/com_android_server_security_VerityUtils.cpp
+++ b/core/jni/com_android_internal_security_VerityUtils.cpp
@@ -19,8 +19,8 @@
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedPrimitiveArray.h>
#include <nativehelper/ScopedUtfChars.h>
-#include "jni.h"
#include <utils/Log.h>
+#include "jni.h"
#include <errno.h>
#include <fcntl.h>
@@ -39,7 +39,7 @@ namespace android {
namespace {
-int enableFsverity(JNIEnv* env, jobject /* clazz */, jstring filePath, jbyteArray signature) {
+int enableFsverity(JNIEnv *env, jobject /* clazz */, jstring filePath, jbyteArray signature) {
ScopedUtfChars path(env, filePath);
if (path.c_str() == nullptr) {
return EINVAL;
@@ -124,11 +124,11 @@ const JNINativeMethod sMethods[] = {
{"measureFsverityNative", "(Ljava/lang/String;[B)I", (void *)measureFsverity},
};
-} // namespace
+} // namespace
-int register_android_server_security_VerityUtils(JNIEnv* env) {
- return jniRegisterNativeMethods(env,
- "com/android/server/security/VerityUtils", sMethods, NELEM(sMethods));
+int register_com_android_internal_security_VerityUtils(JNIEnv *env) {
+ return jniRegisterNativeMethods(env, "com/android/internal/security/VerityUtils", sMethods,
+ NELEM(sMethods));
}
-} // namespace android
+} // namespace android
diff --git a/core/jni/permission_utils.cpp b/core/jni/permission_utils.cpp
new file mode 100644
index 000000000000..2b7ef9999491
--- /dev/null
+++ b/core/jni/permission_utils.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "permission_utils.h"
+#include "core_jni_helpers.h"
+
+static struct {
+ jfieldID fieldUid; // Identity.uid
+ jfieldID fieldPid; // Identity.pid
+ jfieldID fieldPackageName; // Identity.packageName
+ jfieldID fieldAttributionTag; // Identity.attributionTag
+} javaIdentityFields;
+
+static const JNINativeMethod method_table[] = {
+ // no static methods, currently
+};
+
+int register_android_media_permission_Identity(JNIEnv* env) {
+ jclass identityClass = android::FindClassOrDie(env, "android/media/permission/Identity");
+ javaIdentityFields.fieldUid = android::GetFieldIDOrDie(env, identityClass, "uid", "I");
+ javaIdentityFields.fieldPid = android::GetFieldIDOrDie(env, identityClass, "pid", "I");
+ javaIdentityFields.fieldPackageName =
+ android::GetFieldIDOrDie(env, identityClass, "packageName", "Ljava/lang/String;");
+ javaIdentityFields.fieldAttributionTag =
+ android::GetFieldIDOrDie(env, identityClass, "attributionTag", "Ljava/lang/String;");
+
+ return android::RegisterMethodsOrDie(env, "android/media/permission/Identity", method_table,
+ NELEM(method_table));
+}
+
+namespace android::media::permission {
+
+Identity convertIdentity(JNIEnv* env, const jobject& jIdentity) {
+ Identity identity;
+
+ identity.uid = env->GetIntField(jIdentity, javaIdentityFields.fieldUid);
+ identity.pid = env->GetIntField(jIdentity, javaIdentityFields.fieldPid);
+
+ jstring packageNameStr = static_cast<jstring>(
+ env->GetObjectField(jIdentity, javaIdentityFields.fieldPackageName));
+ if (packageNameStr == nullptr) {
+ identity.packageName = std::nullopt;
+ } else {
+ identity.packageName = std::string(ScopedUtfChars(env, packageNameStr).c_str());
+ }
+
+ jstring attributionTagStr = static_cast<jstring>(
+ env->GetObjectField(jIdentity, javaIdentityFields.fieldAttributionTag));
+ if (attributionTagStr == nullptr) {
+ identity.attributionTag = std::nullopt;
+ } else {
+ identity.attributionTag = std::string(ScopedUtfChars(env, attributionTagStr).c_str());
+ }
+
+ return identity;
+}
+
+} // namespace android::media::permission
diff --git a/core/jni/permission_utils.h b/core/jni/permission_utils.h
new file mode 100644
index 000000000000..d625bb6ba30a
--- /dev/null
+++ b/core/jni/permission_utils.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/media/permission/Identity.h>
+#include <jni.h>
+
+namespace android::media::permission {
+
+Identity convertIdentity(JNIEnv* env, const jobject& jIdentity);
+}
+
+int register_android_media_permission_Identity(JNIEnv* env);
diff --git a/core/proto/android/app/OWNERS b/core/proto/android/app/OWNERS
index 296abd18aadc..cc479e61b855 100644
--- a/core/proto/android/app/OWNERS
+++ b/core/proto/android/app/OWNERS
@@ -1 +1 @@
-per-file location_time_zone_manager.proto = nfuller@google.com, mingaleev@google.com
+per-file location_time_zone_manager.proto, time_zone_detector.proto = nfuller@google.com, mingaleev@google.com
diff --git a/core/proto/android/app/location_time_zone_manager.proto b/core/proto/android/app/location_time_zone_manager.proto
index f44d5495f132..891e9fca36aa 100644
--- a/core/proto/android/app/location_time_zone_manager.proto
+++ b/core/proto/android/app/location_time_zone_manager.proto
@@ -17,6 +17,7 @@
syntax = "proto2";
package android.app.time;
+import "frameworks/base/core/proto/android/app/time_zone_detector.proto";
import "frameworks/base/core/proto/android/privacy.proto";
option java_multiple_files = true;
@@ -31,15 +32,6 @@ message LocationTimeZoneManagerServiceStateProto {
repeated TimeZoneProviderStateProto secondary_provider_states = 3;
}
-// Represents a GeolocationTimeZoneSuggestion that can be / has been passed to the time zone
-// detector.
-message GeolocationTimeZoneSuggestionProto {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- repeated string zone_ids = 1;
- repeated string debug_info = 2;
-}
-
// The state tracked for a LocationTimeZoneProvider.
message TimeZoneProviderStateProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/app/time_zone_detector.proto b/core/proto/android/app/time_zone_detector.proto
new file mode 100644
index 000000000000..b33ca1d4f476
--- /dev/null
+++ b/core/proto/android/app/time_zone_detector.proto
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.app.time;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "TimeZoneDetectorProto";
+
+// Represents a GeolocationTimeZoneSuggestion that can be / has been passed to the time zone
+// detector.
+message GeolocationTimeZoneSuggestionProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ repeated string zone_ids = 1;
+ repeated string debug_info = 2;
+}
+
+/*
+ * An obfuscated and simplified time zone suggestion for metrics use.
+ *
+ * The suggestion's time zone IDs (which relate to location) are obfuscated by
+ * mapping them to an ordinal. When the ordinal is assigned consistently across
+ * several objects (i.e. so the same time zone ID is always mapped to the same
+ * ordinal), this allows comparisons between those objects. For example, we can
+ * answer "did these two suggestions agree?", "does the suggestion match the
+ * device's current time zone?", without leaking knowledge of location. Ordinals
+ * are also significantly more compact than full IANA TZDB IDs, albeit highly
+ * unstable and of limited use.
+ */
+message MetricsTimeZoneSuggestion {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ enum Type {
+ CERTAIN = 1;
+ UNCERTAIN = 2;
+ }
+ optional Type type = 1;
+
+ // The ordinals for time zone(s) in the suggestion. Always empty for
+ // UNCERTAIN, and can be empty for CERTAIN, for example when the device is in
+ // a disputed area / on an ocean.
+ repeated uint32 time_zone_ordinals = 2;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8e1da0819515..99ad6d100e55 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -506,6 +506,8 @@
<protected-broadcast android:name="android.app.action.ACTION_PASSWORD_FAILED" />
<protected-broadcast android:name="android.app.action.ACTION_PASSWORD_SUCCEEDED" />
<protected-broadcast android:name="com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION" />
+ <protected-broadcast android:name="com.android.server.ACTION_PROFILE_OFF_DEADLINE" />
+ <protected-broadcast android:name="com.android.server.ACTION_TURN_PROFILE_ON_NOTIFICATION" />
<protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_ADDED" />
<protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNLOCKED" />
@@ -2706,9 +2708,10 @@
<permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"
android:protectionLevel="signature|privileged|vendorPrivileged|oem|verifier" />
- <!-- @SystemApi @hide Allows an application to start foreground services from background -->
+ <!-- Allows an application to start foreground services from background, can only be granted to
+ privileged apps or app that is SMS/EMERGENCY/SYSTEM GALLERY roles. -->
<permission android:name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND"
- android:protectionLevel="signature|privileged|vendorPrivileged|oem|verifier" />
+ android:protectionLevel="signature|privileged|vendorPrivileged|oem|verifier|role"/>
<!-- @SystemApi Must be required by activities that handle the intent action
{@link Intent#ACTION_SEND_SHOW_SUSPENDED_APP_DETAILS}. This is for use by apps that
@@ -5256,15 +5259,20 @@
<permission android:name="android.permission.MANAGE_MUSIC_RECOGNITION"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi Allows an application to manage speech recognition service.
+ @hide <p>Not for use by third-party applications.</p> -->
+ <permission android:name="android.permission.MANAGE_SPEECH_RECOGNITION"
+ android:protectionLevel="signature" />
+
<!-- @SystemApi Allows an application to manage the content suggestions service.
@hide <p>Not for use by third-party applications.</p> -->
<permission android:name="android.permission.MANAGE_CONTENT_SUGGESTIONS"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature" />
<!-- @SystemApi Allows an application to manage the app predictions service.
@hide <p>Not for use by third-party applications.</p> -->
<permission android:name="android.permission.MANAGE_APP_PREDICTIONS"
- android:protectionLevel="signature|appPredictor" />
+ android:protectionLevel="signature|appPredictor" />
<!-- @SystemApi Allows an application to manage the search ui service.
@hide <p>Not for use by third-party applications.</p> -->
diff --git a/core/res/res/layout/notification_template_text_multiline.xml b/core/res/res/layout/notification_template_text_multiline.xml
index d632ac9527d1..ec493bcc5082 100644
--- a/core/res/res/layout/notification_template_text_multiline.xml
+++ b/core/res/res/layout/notification_template_text_multiline.xml
@@ -22,7 +22,7 @@
android:layout_gravity="top"
android:layout_marginTop="@dimen/notification_text_margin_top"
android:minHeight="@dimen/notification_text_height"
- android:ellipsize="marquee"
+ android:ellipsize="end"
android:fadingEdge="horizontal"
android:gravity="top"
android:maxLines="2"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 648d2a1034d0..7d7b73166170 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Laat die program toe om jou fotoversameling te wysig."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lees liggings in jou mediaversameling"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Laat die program toe om liggings in jou mediaversameling te lees."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Gebruik biometrie"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gebruik biometrie of skermslot"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifieer dat dit jy is"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gebruik jou biometrie om voort te gaan"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometriese hardeware is nie beskikbaar nie"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Stawing is gekanselleer"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nie herken nie"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Stawing is gekanselleer"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Geen PIN, patroon of wagwoord is gestel nie"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Kon nie staaf nie"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gebruik skermslot"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Voer jou toesteleiebewys in om voort te gaan."</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Gedeeltelike vingerafdruk is bespeur. Probeer asseblief weer."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kon nie vingerafdruk verwerk nie. Probeer asseblief weer."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Vingerafdruksensor is vuil. Maak dit skoon en probeer weer."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Hierdie toetstel het nie \'n vingerafdruksensor nie."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor is tydelik gedeaktiveer."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gebruik vingerafdruk"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gebruik vingerafdruk of skermslot"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gebruik jou vingerafdruk om voort te gaan"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Gesigslot word nie op hierdie toestel gesteun nie."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor is tydelik gedeaktiveer."</string>
<string name="face_name_template" msgid="3877037340223318119">"Gesig <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Gebruik gesigslot"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gebruik gesig- of skermslot"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gebruik gesigslot om voort te gaan"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Gesig-ikoon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Nuus en tydskrifte"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kaarte en navigasie"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktiwiteit"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Toeganklikheid"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Toestelberging"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-ontfouting"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"uur"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index eb98c69b92be..254ca9cfad36 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"መተግበሪያው የፎቶ ስብስብዎን እንዲቀይረው ያስችለዋል።"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"አካባቢዎችን ከሚዲያ ስብስብዎ ማንበብ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"መተግበሪያው አካባቢዎችን ከሚዲያ ስብስብዎ እንዲያነብብ ያስችለዋል።"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ባዮሜትሪኮችን ይጠቀሙ"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ባዮሜትሪክስ ወይም ማያ ገጽ መቆለፊያን ይጠቀሙ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"እርስዎን መሆንዎን ያረጋግጡ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ለመቀጠል ባዮሜትሪክዎን ይጠቀሙ"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ባዮሜትራዊ ሃርድዌር አይገኝም"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ማረጋገጥ ተሰርዟል"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"አልታወቀም"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ማረጋገጥ ተሰርዟል"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ምንም ፒን፣ ሥርዓተ ጥለት ወይም የይለፍ ቃል አልተቀናበረም"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"ማረጋገጥ ላይ ስህተት"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"የማያ ገጽ መቆለፊን ይጠቀሙ"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ለመቀጠል የመሣሪያዎን የመግቢያ ማስረጃ ያስገቡ"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ከፊል የጣት አሻራ ተገኝቷል። እባክዎ እንደገና ይሞክሩ።"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ጣት አሻራን መስራት አልተቻለም። እባክዎ እንደገና ይሞክሩ።"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"የጣት አሻራ ዳሳሽ ቆሽሿል። እባክዎ ያጽዱት እና እንደገና ይሞክሩ።"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"የጣት አሻራ ይጠቀሙ"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"የጣት አሻራ ወይም የማያ ገጽ መቆለፊያ ይጠቀሙ"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ለመቀጠል የእርስዎን የጣት አሻራ ይጠቀሙ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"በመልክ መክፈት መስጫ በዚህ መሣሪያ ላይ አይደገፍም።"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string>
<string name="face_name_template" msgid="3877037340223318119">"ፊት <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"በመልክ መክፈትን ይጠቀሙ"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"የመልክ ወይም የማያ ገጽ መቆለፊያን ይጠቀሙ"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ለመቀጠል በመልክ መክፈትን ይጠቀሙ"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"የፊት አዶ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ዜና እና መጽሔቶች"</string>
<string name="app_category_maps" msgid="6395725487922533156">"ካርታዎች እና ዳሰሳ"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ውጤታማነት"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"ተደራሽነት"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"የመሣሪያ ማከማቻ"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"የዩኤስቢ ማረሚያ"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ሰዓት"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index d6759b6453b8..89ed573fd1f0 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -562,23 +562,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"للسماح للتطبيق بتعديل مجموعة صورك."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"قراءة المواقع من مجموعة الوسائط التابعة لك"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"للسماح للتطبيق بقراءة المواقع من مجموعة الوسائط التابعة لك."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"استخدام المقاييس الحيوية"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"استخدام المقاييس الحيوية أو قفل الشاشة"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"إثبات هويتك"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"استخدام المقاييس الحيوية للمتابعة"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"معدّات المقاييس الحيوية غير متاحة."</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"تم إلغاء المصادقة."</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"لم يتم التعرف عليها."</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"تم إلغاء المصادقة."</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"لم يتم ضبط رقم تعريف شخصي أو نقش أو كلمة مرور."</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"خطأ في المصادقة"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"استخدام قفل الشاشة"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"إدخال بيانات اعتماد الجهاز للمتابعة"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"تم اكتشاف جزء من بصمة الإصبع فقط؛ يرجى إعادة المحاولة."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"تعذرت معالجة بصمة الإصبع. يُرجى إعادة المحاولة."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"زر استشعار بصمات الأصابع متّسخ. يُرجى تنظيفه وإعادة المحاولة."</string>
@@ -601,10 +596,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استخدام بصمة الإصبع"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استخدام بصمة الإصبع أو قفل الشاشة"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"يمكنك استخدام بصمة الإصبع للمتابعة."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -650,12 +643,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"\"فتح القفل بالوجه\" غير متوفر على هذا الجهاز."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
<string name="face_name_template" msgid="3877037340223318119">"الوجه <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"استخدام ميزة \"فتح القفل بالوجه\""</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"استخدام ميزة \"فتح القفل بالوجه\" أو ميزة \"قفل الشاشة\""</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"استخدام ميزة \"فتح القفل بالوجه\" للمتابعة"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"رمز الوجه"</string>
@@ -2018,7 +2008,7 @@
<string name="notification_phishing_alert_content_description" msgid="494227305355958790">"تنبيه بشأن تصيّد احتيالي"</string>
<string name="notification_work_profile_content_description" msgid="5296477955677725799">"الملف الشخصي للعمل"</string>
<string name="notification_alerted_content_description" msgid="6139691253611265992">"تمّ تفعيل التنبيه"</string>
- <string name="notification_verified_content_description" msgid="6401483602782359391">"تم التحقّق"</string>
+ <string name="notification_verified_content_description" msgid="6401483602782359391">"تم التحقّق من المتّصل"</string>
<string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"توسيع"</string>
<string name="expand_button_content_description_expanded" msgid="7484217944948667489">"تصغير"</string>
<string name="expand_action_accessibility" msgid="1947657036871746627">"تبديل التوسيع"</string>
@@ -2094,8 +2084,7 @@
<string name="app_category_news" msgid="1172762719574964544">"الأخبار والمجلات"</string>
<string name="app_category_maps" msgid="6395725487922533156">"الخرائط والتنقل"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"الإنتاجية"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"أدوات تمكين الوصول"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"مساحة التخزين للجهاز"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"‏تصحيح أخطاء USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ساعة"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 0a4c397de8c3..67d2ce05a348 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"এপক আপোনাৰ ফট’ সংগ্ৰহ সালসলনি কৰিবলৈ দিয়ে।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"আপোনাৰ মিডিয়া সংগ্ৰহৰ অৱস্থান পঢ়িবলৈ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"এপক আপোনাৰ মিডিয়া সংগ্ৰহৰ অৱস্থান পঢ়িবলৈ দিয়ে।"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"বায়\'মেট্ৰিক ব্যৱহাৰ কৰক"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"বায়\'মেট্ৰিক অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"এইয়া আপুনিয়েই বুলি সত্যাপন কৰক"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"অব্যাহত ৰাখিবলৈ আপোনাৰ বায়\'মেট্ৰিক ব্যৱহাৰ কৰক"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"বায়োমেট্ৰিক হাৰ্ডৱেৰ উপলব্ধ নহয়"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"বিশ্বাসযোগ্যতাৰ প্ৰমাণীকৰণ বাতিল কৰা হৈছে"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"চিনাক্ত কৰিব পৰা নাই"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"বিশ্বাসযোগ্যতাৰ প্ৰমাণীকৰণ বাতিল কৰা হৈছে"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"কোনো পিন, আৰ্হি বা পাছৱৰ্ড ছেট কৰা নাই"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"আসোঁৱাহৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰি থকা হৈছে"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"স্ক্ৰীন ল\'ক ব্যৱহাৰ কৰক"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"অব্যাহত ৰাখিবলৈ আপোনাৰ ডিভাইচৰ ক্ৰেডেনশ্বিয়েল দিয়ক"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ফিংগাৰপ্ৰিণ্ট আংশিকভাৱে চিনাক্ত কৰা হৈছে। অনুগ্ৰহ কৰি আকৌ চেষ্টা কৰক৷"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ফিগাৰপ্ৰিণ্টৰ প্ৰক্ৰিয়া সম্পাদন কৰিবপৰা নগ\'ল। অনুগ্ৰহ কৰি আকৌ চেষ্টা কৰক৷"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো লেতেৰা হৈ আছে। অনুগ্ৰহ কৰি পৰিষ্কাৰ কৰি আকৌ চেষ্টা কৰক।"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ফিংগাৰপ্ৰিণ্ট অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"অব্যাহত ৰাখিবলৈ আপোনাৰ ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"এই ডিভাইচটোত মুখাৱয়বৰদ্বাৰা আনলক কৰা সুবিধাটো নচলে।"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
<string name="face_name_template" msgid="3877037340223318119">"মুখমণ্ডল <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"মুখাৱয়বৰে আনলক কৰা ব্যৱহাৰ কৰক"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"মুখাৱয়বৰে আনলক কৰা অথবা স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"অব্যাহত ৰাখিবলৈ মুখাৱয়বৰে আনলক কৰা ব্যৱহাৰ কৰক"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"মুখমণ্ডলৰ আইকন"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"বাতৰি আৰু আলোচনী"</string>
<string name="app_category_maps" msgid="6395725487922533156">"মেপ আৰু দিক্-নিৰ্দেশনা"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"উৎপাদনশীলতা"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"সাধ্য সুবিধা"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"ডিভাইচৰ সঞ্চয়াগাৰ"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"ইউএছবি ডিবাগিং"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ঘণ্টা"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index afb5c397dde5..76b5f1b9aded 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Tətbiqin foto kolleksiyanıza düzəliş etməsinə icazə verir."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"media kolleksiyanızdan məkanları oxuyun"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Tətbiqin media kolleksiyanızdan məkanları oxumasına icazə verin."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrik məlumatlardan istifadə edin"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrik məlumatlardan və ya ekran kilidindən istifadə edin"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Kimliyinizi doğrulayın"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Davam etmək üçün biometrik məlumatlarınızdan istifadə edin"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrik proqram əlçatan deyil"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Doğrulama ləğv edildi"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Tanınmır"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Doğrulama ləğv edildi"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Pin, nümunə və ya parol ayarlanmayıb"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Doğrulama zamanı xəta baş verdi"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekran kilidindən istifadə edin"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Davam etmək üçün cihazın giriş məlumatlarını daxil edin"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Barmaq izi yarımçıq müəyyən olundu. Lütfən, yenidən cəhd edin."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Barmaq izi tanınmadı. Lütfən, yenidən cəhd edin."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Barmaq izi sensoru çirklidir. Lütfən, təmizləyin və yenidən cəhd edin."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor müvəqqəti deaktivdir."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Barmaq izindən istifadə edin"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Barmaq izi və ya ekran kilidindən istifadə edin"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Davam etmək üçün barmaq izinizi istifadə edin"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Üz kilidi bu cihazda dəstəklənmir."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor müvəqqəti deaktivdir."</string>
<string name="face_name_template" msgid="3877037340223318119">"Üz <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Üz ilə kiliddən çıxarmadan istifadə edin"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Üz və ya ekran kilidindən istifadə edin"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Davam etmək üçün üz ilə kiliddən çıxarmadan istifadə edin"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Üz işarəsi"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Xəbər və Jurnallar"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Xəritə və Naviqasiya"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Məhsuldarlıq"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Əlçatımlılıq"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Cihaz yaddaşı"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB sazlama"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"saat"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 0d23fa56d55b..97781c7849a9 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Dozvoljava aplikaciji da menja kolekciju slika."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz medijske kolekcije"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Dozvoljava aplikaciji da čita lokacije iz medijske kolekcije."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Koristite biometriju"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristite biometriju ili zaključavanje ekrana"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite svoj identitet"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Koristite biometrijski podatak da biste nastavili"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Potvrda identiteta je otkazana"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Potvrda identiteta je otkazana"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Niste podesili ni PIN, ni šablon, ni lozinku"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Greška pri potvrdi identiteta"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristite zaključavanje ekrana"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Unesite akreditiv za uređaj da biste nastavili"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Otkriven je delimični otisak prsta. Probajte ponovo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nije uspela obrada otiska prsta. Probajte ponovo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Senzor za otiske prstiju je prljav. Očistite ga i pokušajte ponovo."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristite otisak prsta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristite otisak prsta ili zaključavanje ekrana"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Otključavanje licem nije podržano na ovom uređaju"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je privremeno onemogućen."</string>
<string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Koristite otključavanje licem"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Koristite zaključavanje licem ili zaključavanje ekrana"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Koristite otključavanje licem da biste nastavili"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona lica"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Novosti i časopisi"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mape i navigacija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivnost"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pristupačnost"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Memorijski prostor uređaja"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Otklanjanje grešaka sa USB-a"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"sat"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 87b4ce7faa5a..32672472f145 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Праграма зможа змяняць фотакалекцыю."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"паказваць месцазнаходжанне ў калекцыі мультымедыя"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Праграма зможа паказваць месцазнаходжанне ў калекцыі мультымедыя."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Выкарыстоўваць біяметрыю"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Выкарыстоўваць біяметрыю ці блакіроўку экрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Спраўдзіце, што гэта вы"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Каб працягнуць, скарыстайце свае біяметрычныя даныя"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Біяметрычнае абсталяванне недаступнае"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аўтэнтыфікацыя скасавана"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Не распазнана"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Аўтэнтыфікацыя скасавана"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Не заданы PIN-код, узор разблакіроўкі або пароль"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Памылка аўтэнтыфікацыі"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ужываць блакіроўку экрана"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Каб працягнуць, увядзіце ўліковыя даныя вашай прылады"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Адсканіравана толькі частка адбітка пальца. Паспрабуйце яшчэ раз."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не атрымалася апрацаваць адбітак пальца. Паспрабуйце яшчэ раз."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сканер адбіткаў пальцаў брудны. Ачысціце яго і паспрабуйце яшчэ раз."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Выкарыстоўваць адбітак пальца"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Выкарыстоўваць адбітак пальца ці блакіроўку экрана"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Каб працягнуць, выкарыстоўвайце свой адбітак пальца"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"На гэтай прыладзе распазнаванне твару не падтрымліваецца."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Датчык часова выключаны."</string>
<string name="face_name_template" msgid="3877037340223318119">"Твар <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Ужываць распазнаванне твару"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Выкарыстоўваць распазнаванне твару ці блакіроўку экрана"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Каб працягнуць, скарыстайце распазнаванне твару"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Значок твару"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Навіны і часопісы"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карты і навігацыя"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Прадукцыйнасць"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Спецыяльныя магчымасці"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Сховішча на прыладзе"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Адладка USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"гадз"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 7e847e0a66af..ac55c913a64e 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Разрешава на приложението да променя колекцията ви от снимки."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"да чете местоположенията от мултимедийната ви колекция"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Разрешава на приложението да чете местоположенията от мултимедийната ви колекция."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Използване на биометр. данни"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Използване на биометрични данни или опцията за заключване на екрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Потвърдете, че сте вие"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Използвайте биометричните си данни, за да продължите"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометричният хардуер не е налице"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Удостоверяването бе анулирано"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Не е разпознато"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Удостоверяването бе анулирано"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Няма зададен ПИН код, фигура или парола"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при удостоверяването"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ползване на заключв. на екрана"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Въведете идентификационните данни на устройството, за да продължите"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Открит е частичен отпечатък. Моля, опитайте отново."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатъкът не бе обработен. Моля, опитайте отново."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сензорът за отпечатъци е мръсен. Моля, почистете го и опитайте отново."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорът е временно деактивиран."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Използване на отпечатък"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Използване на отпечатък или опцията за заключване на екрана"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Използвайте отпечатъка си, за да продължите"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Отключването с лице не се поддържа на това устройство."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Сензорът е временно деактивиран."</string>
<string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Използване на отключв. с лице"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Използване на отключването с лице или опцията за заключване на екрана"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Използвайте функцията за отключване с лице, за да продължите"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Икона на лице"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Новини и списания"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карти и навигация"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Производителност"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Достъпност"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Хранилище на устройството"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Отстраняване на грешки през USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"час"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 4d3d79394521..ff25441fbe7d 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"অ্যাপকে আপনার ফটো সংগ্রহ পরিবর্তন করার অনুমতি দিন।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ডিয়া সংগ্রহ থেকে লোকেশন দেখতে দিন"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"আপনার মিডিয়া সংগ্রহ থেকে লোকেশন দেখতে অ্যাপকে অনুমতি দিন।"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"বায়োমেট্রিক্স ব্যবহার করুন"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"বায়োমেট্রিক্স অথবা স্ক্রিন লক ব্যবহার করুন"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"আপনার পরিচয় যাচাই করুন"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"চালিয়ে যেতে আপনার বায়োমেট্রিক্স ব্যবহার করুন"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"বায়োমেট্রিক হার্ডওয়্যার পাওয়া যাবে না"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"যাচাইকরণ বাতিল হয়েছে"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"স্বীকৃত নয়"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"যাচাইকরণ বাতিল হয়েছে"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"পিন, প্যাটার্ন অথবা পাসওয়ার্ড সেট করা নেই"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"যাচাইকরণে সমস্যা হয়েছে"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"স্ক্রিন লক ব্যবহার করুন"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"চালিয়ে যেতে আপনার ডিভাইসের ক্রেডেনশিয়াল ব্যবহার করুন"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"আঙ্গুলের ছাপ আংশিক শনাক্ত করা হয়েছে৷ অনুগ্রহ করে আবার চেষ্টা করুন৷"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"আঙ্গুলের ছাপ প্রক্রিয়া করা যায়নি৷ অনুগ্রহ করে আবার চেষ্টা করুন৷"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"আঙ্গুলের ছাপ নেওয়ার সেন্সরটি অপরিস্কার৷ পরিষ্কার করে আবার চেষ্টা করুন৷"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইসে আঙ্গুলের ছাপ নেওয়ার সেন্সর নেই।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"আঙ্গুলের ছাপ ব্যবহার করুন"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"আঙ্গুলের ছাপ অথবা স্ক্রিন লক ব্যবহার করুন"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"চালিয়ে যেতে আঙ্গুলের ছাপ ব্যবহার করুন"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"এই ডিভাইসে মুখের সাহায্যে আনলক করার সুবিধাটি কাজ করে না।"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> ফেস"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"মুখের সাহায্যে আনলক ব্যবহার করুন"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"মুখ অথবা স্ক্রিন লক ব্যবহার করুন"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"চালিয়ে যেতে মুখের সাহায্যে আনলক ব্যবহার করুন"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ফেস আইকন"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"খবর ও পত্রিকাগুলি"</string>
<string name="app_category_maps" msgid="6395725487922533156">"ম্যাপ ও নেভিগেশান"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"উৎপাদনশীলতা"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"অ্যাক্সেসিবিলিটি"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"ডিভাইসের স্টোরেজ"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB ডিবাগিং"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ঘণ্টা"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 2e24175bbaa4..25129e489a05 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Omogućava aplikaciji da mijenja vašu kolekciju fotografija."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz kolekcije medija"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Omogućava aplikaciji da čita lokacije iz vaše kolekcije medija."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Koristi biometriju"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristi biometriju ili zaključavanje ekrana"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite identitet"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Koristite biometriju da nastavite"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikacija je otkazana"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentifikacija je otkazana"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nije postavljen PIN, uzorak niti lozinka"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Greška pri autentifikaciji"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristi zaključavanje ekrana"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Unesite akreditiv uređaja da nastavite"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Otkriven je djelimični otisak prsta. Pokušajte ponovo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Obrada otiska prsta nije uspjela. Pokušajte ponovo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Senzor za otisak prsta je prljav. Očistite ga i pokušajte ponovo."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristi otisak prsta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristi otisak prsta ili zaključavanje ekrana"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Otključavanje licem nije podržano na ovom uređaju."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je privremeno onemogućen."</string>
<string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Koristi otključavanje licem"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Koristi otključavanje licem ili zaključavanje ekrana"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Koristite otključavanje licem da nastavite"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona lica"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Vijesti i časopisi"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mape i navigacija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivnost"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pristupačnost"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Memorija uređaja"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Otklanjanje grešaka putem USB-a"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"sat"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 70caa2cff7fe..6f2af9203553 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permet que l\'aplicació modifiqui la teva col·lecció de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"llegir les ubicacions de les teves col·leccions multimèdia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permet que l\'aplicació llegeixi les ubicacions de les teves col·leccions multimèdia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utilitza la biometria"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Fes servir la biometria o el bloqueig de pantalla"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que ets tu"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilitza la teva biometria per continuar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Maquinari biomètric no disponible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"S\'ha cancel·lat l\'autenticació"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"No s\'ha reconegut"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"S\'ha cancel·lat l\'autenticació"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No s\'ha definit cap PIN, patró o contrasenya"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error en l\'autenticació"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utilitza el bloqueig de pantalla"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Utilitza les credencials del teu dispositiu per continuar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"S\'ha detectat una empremta digital parcial. Torna-ho a provar."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No s\'ha pogut processar l\'empremta digital. Torna-ho a provar."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"El sensor d\'empremtes dactilars està brut. Neteja\'l i torna-ho a provar."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes dactilars."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor està desactivat temporalment."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilitza l\'empremta digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilitza l\'empremta digital o el bloqueig de pantalla"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Fes servir l\'empremta digital per continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"El desbloqueig facial no és compatible amb el dispositiu."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"El sensor està desactivat temporalment."</string>
<string name="face_name_template" msgid="3877037340223318119">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Utilitza el desbloqueig facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utilitza el desbloqueig facial o de pantalla"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilitza el desbloqueig facial per continuar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icona facial"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Notícies i revistes"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapes i navegació"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivitat"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibilitat"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Emmagatzematge del dispositiu"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuració per USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 0f732669f467..bd9866279e96 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Umožňuje aplikaci upravit vaši sbírku fotek."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čtení míst ze sbírky médií"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Umožňuje aplikaci číst místa z vaší sbírky médií."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Použít biometrii"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Použít biometrii nebo zámek obrazovky"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrďte, že jste to vy"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Pokračujte biometrickým ověřením"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrický hardware není k dispozici"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Ověření bylo zrušeno"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nerozpoznáno"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Ověření bylo zrušeno"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Není nastaven žádný PIN, gesto ani heslo"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Při ověřování došlo k chybě"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Použít zámek obrazovky"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Pokračujte zadáním identifikačních úřadů svého zařízení"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Byla zjištěna jen část otisku prstu. Zkuste to znovu."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Zpracování otisku prstu se nezdařilo. Zkuste to znovu."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Senzor otisků prstů je znečištěn. Vyčistěte jej a zkuste to znovu."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zařízení nemá snímač otisků prstů."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasně deaktivován."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použít otisk prstu"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použít otisk prstu nebo zámek obrazovky"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Pokračujte přiložením prstu"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Odemknutí obličejem na tomto zařízení není podporováno."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je dočasně deaktivován."</string>
<string name="face_name_template" msgid="3877037340223318119">"Obličej <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Použít odemknutí obličejem"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Použít odemknutí obličejem nebo zámek obrazovky"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Pokračujte odemknutím obličejem"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona obličeje"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Zprávy a časopisy"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapy a navigace"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivita"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Přístupnost"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Úložiště zařízení"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Ladění přes USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hodina"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 13afaf251317..70492e01fc1b 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -552,23 +552,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Tillader, at appen kan ændre din billedsamling."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"læse placeringer fra din mediesamling"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Tillader, at appen kan læse placeringer fra din mediesamling."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Brug biometriske systemer"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Brug biometriske systemer eller skærmlås"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Bekræft, at det er dig"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Brug dine biometriske data for at fortsætte"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisk hardware er ikke tilgængelig"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Godkendelsen blev annulleret"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ikke genkendt"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Godkendelsen blev annulleret"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Der er ikke angivet pinkode, mønster eller adgangskode"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Der opstod fejl i forbindelse med godkendelse"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Brug skærmlås"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Angiv dine loginoplysninger for enheden for at fortsætte"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Der blev registreret et delvist fingeraftryk. Prøv igen."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingeraftrykket kunne ikke behandles. Prøv igen."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingeraftrykslæseren er beskidt. Tør den af, og prøv igen."</string>
@@ -591,10 +586,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enhed har ingen fingeraftrykslæser."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidigt deaktiveret."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Brug fingeraftryk"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Brug fingeraftryk eller skærmlås"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Brug dit fingeraftryk for at fortsætte"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -640,12 +633,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Ansigtslås understøttes ikke på denne enhed."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensoren er midlertidigt deaktiveret."</string>
<string name="face_name_template" msgid="3877037340223318119">"Ansigt <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Brug ansigtslås"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Brug ansigts- eller skærmlås"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Brug ansigtslås for at fortsætte"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ansigt"</string>
@@ -1968,8 +1958,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Aviser og blade"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kort og navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitet"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Hjælpefunktioner"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Lagerplads på enheden"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-fejlretning"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"time"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 512b3a555eec..6e458fa30fd5 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Ermöglicht der App, deine Fotosammlung zu ändern."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"Standorte aus meiner Mediensammlung abrufen"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Ermöglicht der App, Standorte aus deiner Mediensammlung abzurufen."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrisches Verfahren nutzen"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrisches Verfahren oder Displaysperre verwenden"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Deine Identität bestätigen"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Mithilfe eines biometrischen Verfahrens fortfahren"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrische Hardware nicht verfügbar"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentifizierung abgebrochen"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nicht erkannt"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentifizierung abgebrochen"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Keine PIN, kein Muster und kein Passwort festgelegt"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Fehler bei der Authentifizierung"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Displaysperre verwenden"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Zum Fortfahren Anmeldedaten des Geräts eingeben"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Fingerabdruck nur teilweise erkannt. Bitte versuche es noch einmal."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingerabdruck konnte nicht verarbeitet werden. Bitte versuche es noch einmal."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingerabdrucksensor ist verschmutzt. Reinige ihn und versuche es noch einmal."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dieses Gerät hat keinen Fingerabdrucksensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Der Sensor ist vorübergehend deaktiviert."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Fingerabdruck verwenden"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Fingerabdruck oder Displaysperre verwenden"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Mithilfe deines Fingerabdrucks fortfahren"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face Unlock wird auf diesem Gerät nicht unterstützt."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Der Sensor ist vorübergehend deaktiviert."</string>
<string name="face_name_template" msgid="3877037340223318119">"Gesicht <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Face Unlock verwenden"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Face Unlock oder Displaysperre verwenden"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Zum Fortfahren Face Unlock verwenden"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Gesichtssymbol"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Nachrichten &amp; Zeitschriften"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Karten &amp; Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Effizienz"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Bedienungshilfen"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Gerätespeicher"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-Fehlerbehebung"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"Stunde"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index d9dc2c55cb09..920f09eb777d 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Επιτρέπει στην εφαρμογή να τροποποιήσει τη συλλογή φωτογραφιών σας."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ανάγνωση τοποθεσιών από τη συλλογή πολυμέσων σας"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Επιτρέπει στην εφαρμογή να διαβάσει τοποθεσίες από τη συλλογή πολυμέσων σας."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Χρήση βιομετρικών"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Χρήση βιομετρικών ή κλειδώματος οθόνης"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Επαλήθευση ταυτότητας"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Χρησιμοποιήστε βιομετρικά για να συνεχίσετε"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Δεν υπάρχει διαθέσιμος βιομετρικός εξοπλισμός"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Ο έλεγχος ταυτότητας ακυρώθηκε"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Δεν αναγνωρίστηκε"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Ο έλεγχος ταυτότητας ακυρώθηκε"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Δεν έχει οριστεί PIN, μοτίβο ή κωδικός πρόσβασης"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Σφάλμα κατά τον έλεγχο ταυτότητας"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Χρήση κλειδώματος οθόνης"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Εισαγάγετε το διαπιστευτήριο της συσκευής σας για να συνεχίσετε"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Εντοπίστηκε μόνο μέρος του δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Δεν ήταν δυνατή η επεξεργασία του δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Ο αισθητήρας δακτυλικού αποτυπώματος δεν είναι καθαρός. Καθαρίστε τον και δοκιμάστε ξανά."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Χρήση δακτυλικού αποτυπώματος"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Χρήση δακτυλικού αποτυπώματος ή κλειδώματος οθόνης"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Χρησιμοποιήστε το δακτυλικό αποτύπωμά σας για να συνεχίσετε"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Το Face Unlock δεν υποστηρίζεται σε αυτήν τη συσκευή."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string>
<string name="face_name_template" msgid="3877037340223318119">"Πρόσωπο <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Χρήση Face Unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Χρήση προσώπου ή κλειδώματος οθόνης"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Χρησιμοποιήστε το Face Unlock για να συνεχίσετε"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Εικ. προσ."</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Ειδήσεις και περιοδικά"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Χάρτες και πλοήγηση"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Παραγωγικότητα"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Προσβασιμότητα"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Αποθηκευτικός χώρος συσκευής"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Εντοπισμός σφαλμάτων USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ώρα"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 73e2ca0d3fe5..43a7fb6662d6 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentication cancelled"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Enter your device credential to continue"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Partial fingerprint detected. Please try again."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingerprint sensor is dirty. Please clean and try again."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"News &amp; Magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps &amp; Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivity"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibility"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Device storage"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB debugging"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hour"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 67130e1fb5c5..04390c74bb32 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentication cancelled"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Enter your device credential to continue"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Partial fingerprint detected. Please try again."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingerprint sensor is dirty. Please clean and try again."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"News &amp; Magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps &amp; Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivity"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibility"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Device storage"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB debugging"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hour"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 1d36494b7b8b..84224ed85d10 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentication cancelled"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Enter your device credential to continue"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Partial fingerprint detected. Please try again."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingerprint sensor is dirty. Please clean and try again."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"News &amp; Magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps &amp; Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivity"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibility"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Device storage"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB debugging"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hour"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 016c55c3352c..d740e01c502e 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Allows the app to modify your photo collection."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"read locations from your media collection"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Allows the app to read locations from your media collection."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Use biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Use biometrics or screen lock"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verify that it’s you"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use your biometric to continue"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometric hardware unavailable"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentication cancelled"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Not recognised"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentication cancelled"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No pin, pattern or password set"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error while authenticating"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Use screen lock"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Enter your device credential to continue"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Partial fingerprint detected. Please try again."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Couldn\'t process fingerprint. Please try again."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingerprint sensor is dirty. Please clean and try again."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Use fingerprint"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Use fingerprint or screen lock"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock is not supported on this device."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporarily disabled."</string>
<string name="face_name_template" msgid="3877037340223318119">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Use face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Use face or screen lock"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use face unlock to continue"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"News &amp; Magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps &amp; Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivity"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibility"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Device storage"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB debugging"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hour"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index bd7da803e42b..6125c167fa7d 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que la app modifique tu colección de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"leer ubicaciones de tu colección de contenido multimedia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que la app lea las ubicaciones de tu colección de contenido multimedia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar datos biométricos"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar datos biométricos o bloqueo de pantalla"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Comprueba que eres tú"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Usa tus datos biométricos para continuar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"No hay hardware biométrico disponible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Se canceló la autenticación"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"No se reconoció"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Se canceló la autenticación"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No se estableció ningún PIN, patrón ni contraseña"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error de autenticación"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueo de pantalla"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Ingresa las credenciales de tu dispositivo para continuar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Se detectó parcialmente la huella dactilar. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No se pudo procesar la huella dactilar. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"El sensor de huellas dactilares está sucio. Limpia el sensor y vuelve a intentarlo."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas dactilares."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Se inhabilitó temporalmente el sensor."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar bloqueo de huella dactilar o pantalla"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utiliza tu huella dactilar para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"No se admite el desbloqueo facial en este dispositivo."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Se inhabilitó temporalmente el sensor."</string>
<string name="face_name_template" msgid="3877037340223318119">"Rostro <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueo facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar bloqueo facial o de pantalla"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Usa el desbloqueo facial para continuar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ícono cara"</string>
@@ -1576,8 +1566,8 @@
<string name="expires_on" msgid="1623640879705103121">"Expira el:"</string>
<string name="serial_number" msgid="3479576915806623429">"Número de serie:"</string>
<string name="fingerprints" msgid="148690767172613723">"Huellas digitales:"</string>
- <string name="sha256_fingerprint" msgid="7103976380961964600">"Huella dactilar SHA-256"</string>
- <string name="sha1_fingerprint" msgid="2339915142825390774">"Huella dactilar SHA-1:"</string>
+ <string name="sha256_fingerprint" msgid="7103976380961964600">"Huella digital SHA-256"</string>
+ <string name="sha1_fingerprint" msgid="2339915142825390774">"Huella digital SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Ver todas"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Elige actividad"</string>
<string name="share_action_provider_share_with" msgid="1904096863622941880">"Compartir con"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Noticias y revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas y navegación"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productividad"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accesibilidad"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Almacenamiento del dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuración por USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index d771977431c3..0e163d2b263b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que la aplicación modifique tu colección de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"leer las ubicaciones de tu colección de contenido multimedia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que la aplicación lea las ubicaciones de tu colección de contenido multimedia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar biometría"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometría o bloqueo de pantalla"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que eres tú"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Usa tu biometría para continuar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico no disponible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticación cancelada"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"No se reconoce"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autenticación cancelada"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"No se ha definido el PIN, el patrón o la contraseña"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"No se ha podido autenticar"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueo de pantalla"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Introduce las credenciales del dispositivo para continuar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Se ha detectado una huella digital parcial. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No se ha podido procesar la huella digital. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"El sensor de huellas digitales está sucio. Límpialo y vuelve a intentarlo."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor está inhabilitado en estos momentos."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar huella digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar huella digital o bloqueo de pantalla"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Usa tu huella digital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"El desbloqueo facial no está disponible en este dispositivo."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"El sensor está inhabilitado en estos momentos."</string>
<string name="face_name_template" msgid="3877037340223318119">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueo facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar desbloqueo facial o bloqueo de pantalla"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Usa el desbloqueo facial para continuar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icono cara"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Noticias y revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas y navegación"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productividad"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accesibilidad"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Almacenamiento del dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuración por USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index ec02fad6683c..9f6df6e8ff35 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Võimaldab rakendusel muuta teie fotokogu."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"Lugeda teie meediakogus olevaid asukohti"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Võimaldab rakendusel lugeda teie meediakogus olevaid asukohti."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biomeetria kasutamine"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biomeetria või ekraaniluku kasutamine"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Kinnitage oma isik"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Jätkamiseks kasutage biomeetriat"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biomeetriline riistvara ei ole saadaval"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentimine tühistati"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ei tuvastatud"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentimine tühistati"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN-koodi, mustrit ega parooli pole määratud"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Viga autentimisel"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekraaniluku kasutamine"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Jätkamiseks sisestage seadme mandaat"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Tuvastati osaline sõrmejälg. Proovige uuesti."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Sõrmejälge ei õnnestunud töödelda. Proovige uuesti."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Sõrmejäljeandur on must. Puhastage see ja proovige uuesti."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Selles seadmes pole sõrmejäljeandurit."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Andur on ajutiselt keelatud."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Sõrmejälg <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sõrmejälje kasutamine"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sõrmejälje või ekraaniluku kasutamine"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Jätkamiseks kasutage sõrmejälge"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Seade ei toeta Face Unlocki."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Andur on ajutiselt keelatud."</string>
<string name="face_name_template" msgid="3877037340223318119">"Nägu <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Face Unlocki kasutamine"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Face Unlocki või ekraaniluku kasutamine"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Jätkamiseks kasutage Face Unlocki"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Näoikoon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Uudised ja ajakirjad"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kaardid ja navigeerimine"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktiivsus"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Juurdepääsetavus"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Seadme salvestusruum"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB silumine"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"tund"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 8ee77a600739..72d083363594 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -313,8 +313,8 @@
<string name="permgroupdesc_storage" msgid="6351503740613026600">"atzitu gailuko argazkiak, multimedia-edukia eta fitxategiak"</string>
<string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofonoa"</string>
<string name="permgroupdesc_microphone" msgid="1047786732792487722">"grabatu audioa"</string>
- <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Ariketa fisikoa"</string>
- <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ariketa fisikoak atzitu"</string>
+ <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Jarduera fisiko"</string>
+ <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"jarduera fisikoa atzitu"</string>
<string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="7585150538459320326">"atera argazkiak eta grabatu bideoak"</string>
<string name="permgrouplab_calllog" msgid="7926834372073550288">"Deien erregistroa"</string>
@@ -445,8 +445,8 @@
<string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Aplikazioak edonoiz erabil dezake mikrofonoa audioa grabatzeko."</string>
<string name="permlab_sim_communication" msgid="176788115994050692">"bidali aginduak SIM txartelera"</string>
<string name="permdesc_sim_communication" msgid="4179799296415957960">"SIM txartelera aginduak bidaltzeko aukera ematen die aplikazioei. Oso arriskutsua da."</string>
- <string name="permlab_activityRecognition" msgid="1782303296053990884">"hauteman ariketa fisikoa"</string>
- <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Aplikazioak ariketa fisikoa hauteman dezake."</string>
+ <string name="permlab_activityRecognition" msgid="1782303296053990884">"hauteman jarduera fisiko"</string>
+ <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Aplikazioak jarduera fisiko hauteman dezake."</string>
<string name="permlab_camera" msgid="6320282492904119413">"atera argazkiak eta grabatu bideoak"</string>
<string name="permdesc_camera" msgid="5240801376168647151">"Aplikazioak abian den bitartean erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko."</string>
<string name="permlab_backgroundCamera" msgid="7549917926079731681">"Argazkiak atera eta bideoak grabatu atzeko planoan."</string>
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Argazki-bilduma aldatzeko baimena ematen die aplikazioei."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"multimedia-edukien bildumako kokapena irakurri"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Multimedia-edukien bildumako kokapena irakurtzeko baimena ematen die aplikazioei."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Erabili sistema biometrikoak"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Erabili sistema biometrikoak edo pantailaren blokeoa"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Egiaztatu zeu zarela"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Aurrera egiteko, erabili sistema biometrikoak"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometrikoa ez dago erabilgarri"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Utzi da autentifikazioa"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ez da ezagutu"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Utzi egin da autentifikazioa"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Ez da ezarri PIN koderik, eredurik edo pasahitzik"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Errorea autentifikatzean"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Erabili pantailaren blokeoa"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Aurrera egiteko, idatzi gailuaren kredentzialak"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Hatz-marka ez da osorik hauteman. Saiatu berriro."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ezin izan da prozesatu hatz-marka. Saiatu berriro."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Hatz-marken sentsorea zikina dago. Garbi ezazu, eta saiatu berriro."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sentsorea aldi baterako desgaitu da."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> hatza"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Erabili hatz-marka"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Erabili hatz-marka edo pantailaren blokeoa"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Aurrera egiteko, erabili hatz-marka"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Gailu honek ez du onartzen aurpegiaren bidez desblokeatzea."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sentsorea aldi baterako desgaitu da."</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> aurpegia"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Erabili aurpegiaren bidez desblokeatzeko eginbidea"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Erabili aurpegia edo pantailaren blokeoa"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Aurrera egiteko, erabili aurpegiaren bidez desblokeatzeko eginbidea"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Aurpegiaren ikonoa"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Albisteak eta aldizkariak"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapak eta nabigazioa"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktibitatea"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Erabilerraztasuna"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Gailuaren memoria"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB bidezko arazketa"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ordu"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 42b8c85f7eb9..76d0c1e794f9 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"به برنامه اجازه می‌دهد مجموعه عکستان را تغییر دهد."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"خواندن مکان‌ها از مجموعه رسانه شما"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"به برنامه اجازه می‌دهد مکان‌ها را از مجموعه رسانه‌تان بخواند."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"استفاده از زیست‌سنجشی"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"استفاده از زیست‌سنجشی یا قفل صفحه"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"تأیید کنید این شما هستید"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"برای ادامه، از زیست‌سنجشی استفاده کنید"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"سخت‌افزار زیست‌سنجی دردسترس نیست"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"اصالت‌سنجی لغو شد"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"شناسایی نشد"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"اصالت‌سنجی لغو شد"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"پین، الگو یا گذرواژه‌ای تنظیم نشده است"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"خطا هنگام اصالت‌سنجی"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"از قفل صفحه استفاده کنید"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"برای ادامه، اطلاعات کاربری دستگاهتان را وارد کنید"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"بخشی از اثر انگشت شناسایی شد. لطفاً دوباره امتحان کنید."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"اثرانگشت پردازش نشد. لطفاً دوباره امتحان کنید."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"حسگر اثر انگشت کثیف است. لطفاً آن را تمیز کنید و دوباره امتحان نمایید."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"حسگر به‌طور موقت غیرفعال است."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"استفاده از اثر انگشت"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"استفاده از اثر انگشت یا قفل صفحه"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"برای ادامه، از اثر انگشتتان استفاده کنید"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"«بازگشایی با چهره» در این دستگاه پشتیبانی نمی‌شود."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"حسگر به‌طور موقت غیرفعال است."</string>
<string name="face_name_template" msgid="3877037340223318119">"چهره <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"استفاده از «بازگشایی با چهره»"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"استفاده از قفل صفحه یا چهره"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"برای ادامه، از «بازگشایی با چهره» استفاده کنید"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"نماد چهره"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"اخبار و مجله"</string>
<string name="app_category_maps" msgid="6395725487922533156">"نقشه و پیمایش"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"بهره‌وری"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"دسترس‌پذیری"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"فضای ذخیره‌سازی دستگاه"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"‏اشکال‌زدایی USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ساعت"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index be0cd2358b8b..2e0d6cddc3d4 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Antaa sovelluksen muokata kuvakokoelmaasi."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lukea mediakokoelmasi sijainteja"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Antaa sovelluksen lukea mediakokoelmasi sijainteja."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Käytä biometriikkaa"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Käytä biometriikkaa tai näytön lukitusta"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Vahvista henkilöllisyytesi"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Jatka käyttämällä biometriikkaa"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrinen laitteisto ei käytettävissä"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Todennus peruutettu"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ei tunnistettu"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Todennus peruutettu"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN-koodia, kuviota tai salasanaa ei ole asetettu"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Virhe todennuksessa"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Käytä näytön lukitusta"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Jatka lisäämällä laitteesi kirjautumistiedot"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Sormenjälki havaittiin vain osittain. Yritä uudelleen."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Sormenjäljen prosessointi epäonnistui. Yritä uudelleen."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Sormenjälkitunnistin on likainen. Puhdista tunnistin ja yritä uudelleen."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Laitteessa ei ole sormenjälkitunnistinta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tunnistin poistettu väliaikaisesti käytöstä."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Käytä sormenjälkeä"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Käytä sormenjälkeä tai näytön lukitusta"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Jatka sormenjäljen avulla"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Tämä laite ei tue Face Unlockia."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Tunnistin poistettu väliaikaisesti käytöstä."</string>
<string name="face_name_template" msgid="3877037340223318119">"Kasvot <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Käytä Face Unlockia"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Käytä Face Unlockia tai näytön lukitusta"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Jatka käyttämällä Face Unlockia"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Kasvokuvake"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Uutiset ja lehdet"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kartat ja navigointi"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Tuottavuus"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Esteettömyys"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Laitteen tallennustila"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-vianetsintä"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"tunnit"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 5c26e683d354..1ebc60465f47 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Autorise l\'application à modifier votre collection de photos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lire les positions issues de votre collection multimédia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Autorise l\'application à lire les positions indiquées dans votre collection multimédia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utiliser les données biométriques"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utiliser les données biométriques ou le verrouillage de l\'écran"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmez que c\'est vous"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilisez votre méthode d\'authentification biométrique pour continuer"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Matériel biométrique indisponible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentification annulée"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Données biométriques non reconnues"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentification annulée"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Aucun NIP, schéma ou mot de passe défini"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Erreur d\'authentification"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utiliser le verrouillage de l\'écran"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Entrez votre authentifiant d\'appareil pour continuer"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Empreinte digitale partielle détectée. Veuillez réessayer."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Le capteur d\'empreintes digitales est sale. Veuillez le nettoyer et réessayer."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Cet appareil ne possède pas de capteur d\'empreintes digitales."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Le capteur a été désactivé temporairement."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser l\'empreinte digitale ou le verrouillage de l\'écran"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilisez votre empreinte digitale pour continuer"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Cet appar. ne prend pas en charge le déverr. par reconn. faciale."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Le capteur a été désactivé temporairement."</string>
<string name="face_name_template" msgid="3877037340223318119">"Visage <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Utiliser le déverrouillage par reconnaissance faciale"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utiliser la reconnaissance faciale ou le verrouillage de l\'écran"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilisez le déverrouillage par reconnaissance faciale pour continuer"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icône visage"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Actualités et magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Cartes et navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivité"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibilité"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Mémoire de l\'appareil"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Débogage USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"heures"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 3d8856df65bf..ce36dbc9ba21 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Autorise l\'application à modifier votre bibliothèque photo."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"consulter des positions issues de votre bibliothèque multimédia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Autorise l\'application à consulter des positions issues de votre bibliothèque multimédia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utiliser la biométrie"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utiliser la biométrie ou le verrouillage de l\'écran"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmez votre identité"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilisez la biométrie pour continuer"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Matériel biométrique indisponible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Authentification annulée"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Non reconnu"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Authentification annulée"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Aucun code, schéma ni mot de passe n\'est défini"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Erreur d\'authentification"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utiliser verrouillage écran"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Saisissez l\'identifiant de l\'appareil pour continuer"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Empreinte digitale partiellement détectée. Veuillez réessayer."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Le lecteur d\'empreinte digitale est sale. Veuillez le nettoyer, puis réessayer."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Capteur temporairement désactivé."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utiliser l\'empreinte digitale"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utiliser votre empreinte digitale ou le verrouillage de l\'écran"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilisez votre empreinte digitale pour continuer"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face Unlock n\'est pas compatible avec cet appareil."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Capteur temporairement désactivé."</string>
<string name="face_name_template" msgid="3877037340223318119">"Visage <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Utiliser Face Unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utiliser Face Lock ou le verrouillage de l\'écran"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilisez Face Unlock pour continuer"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icône visage"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Actualités et magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Plans et navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivité"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibilité"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Mémoire de l\'appareil"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Débogage USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"heures"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 1c5ab13035f3..9d95af8badc2 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que a aplicación modifique a túa colección de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler localizacións da túa colección multimedia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que a aplicación lea as localizacións da túa colección multimedia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utilizar desbloqueo biométrico"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utilizar desbloqueo biométrico ou credencial do dispositivo"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que es ti"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Para continuar, utiliza o desbloqueo biométrico"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"O hardware biométrico non está dispoñible"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Cancelouse a autenticación"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Non se recoñeceu"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Cancelouse a autenticación"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Non se estableceu ningún PIN, padrón ou contrasinal"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Produciuse un erro ao realizar a autenticación"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar credencial do dispositivo"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Para continuar, mete a credencial do dispositivo"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Detectouse unha impresión dixital parcial. Téntao de novo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Non se puido procesar a impresión dixital. Téntao de novo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"O sensor de impresión dixital está sucio. Límpao e téntao de novo."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo non ten sensor de impresión dixital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Desactivouse o sensor temporalmente."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar impresión dixital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar impresión dixital ou credencial do dispositivo"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utiliza a túa impresión dixital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Este dispositivo non admite o desbloqueo facial."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Desactivouse o sensor temporalmente."</string>
<string name="face_name_template" msgid="3877037340223318119">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Utilizar desbloqueo facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utilizar desbloqueo facial ou credencial do dispositivo"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Para continuar, utiliza o desbloqueo facial"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icona cara"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Noticias e revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas e navegación"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produtividade"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accesibilidade"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Almacenamento do dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuración por USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index fd3a06baa3fa..334ba2d8b532 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"એપને તમારો ફોટો સંગ્રહ સંશોધિત કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"આપના મીડિયા સંગ્રહમાંથી સ્થાનો વાંચવા"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"એપને તમારા મીડિયા સંગ્રહમાંથી સ્થાનો વાંચવાની મંજૂરી આપે છે."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"બાયોમેટ્રિક્સનો ઉપયોગ કરો"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"બાયોમેટ્રિક્સ અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"તે તમે જ છો એ ચકાસો"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"આગળ વધવા માટે બાયોમેટ્રિકનો ઉપયોગ કરો"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"બાયોમેટ્રિક હાર્ડવેર ઉપલબ્ધ નથી"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"પ્રમાણીકરણ રદ કર્યું"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"ઓળખાયેલ નથી"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"પ્રમાણીકરણ રદ કર્યું"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"કોઈ પિન, પૅટર્ન અથવા પાસવર્ડ સેટ કરેલો નથી"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"પ્રમાણિત કરવામાં ભૂલ આવી"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ચાલુ રાખવા માટે તમારા ડિવાઇસની લૉગ ઇન વિગત દાખલ કરો"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"આંશિક ફિંગરપ્રિન્ટ મળી. કૃપા કરીને ફરી પ્રયાસ કરો."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ફિંગરપ્રિન્ટ પ્રક્રિયા કરી શકાઈ નથી. કૃપા કરીને ફરી પ્રયાસ કરો."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ફિંગરપ્રિન્ટ સેન્સર ગંદું છે. કૃપા કરીને સાફ કરો અને ફરી પ્રયાસ કરો."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ફિંગરપ્રિન્ટ અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ચાલુ રાખવા માટે તમારી ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"આ ડિવાઇસ પર ફેસ અનલૉક કરવાની સુવિધા નથી."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string>
<string name="face_name_template" msgid="3877037340223318119">"ચહેરાનું <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ફેસ અનલૉકનો ઉપયોગ કરો"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ફેસ લૉક અથવા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"આગળ વધવા માટે ફેસ અનલૉકનો ઉપયોગ કરો"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ચહેરા આઇકન"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"સમાચાર અને સામાયિકો"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps અને નેવિગેશન"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ઉત્પાદકતા"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"ઍક્સેસિબિલિટી"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"ડિવાઇસ સ્ટૉરેજ"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB ડિબગિંગ"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"કલાક"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index be64e904b908..16e848f83d6d 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"इससे ऐप्लिकेशन को आपके फ़ोटो संग्रह में बदलाव करने की मंज़ूरी दी जाती है."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"अपने मीडिया संग्रह से जगह की जानकारी ऐक्सेस करने की अनुमति दें"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"इससे ऐप्लिकेशन को आपके मीडिया संग्रह से जगह की जानकारी ऐक्सेस करने की अनुमति दी जाती है."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"बायोमेट्रिक्स इस्तेमाल करें"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"बायोमेट्रिक्स या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"अपनी पहचान की पुष्टि करें"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"जारी रखने के लिए, बायोमेट्रिक्स इस्तेमाल करें"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"बायोमेट्रिक हार्डवेयर उपलब्ध नहीं है"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"प्रमाणीकरण रद्द किया गया"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"पहचान नहीं हो पाई"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"प्रमाणीकरण रद्द किया गया"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"पिन, पैटर्न या पासवर्ड सेट नहीं है"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"गड़बड़ी की पुष्टि की जा रही है"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"जारी रखने के लिए, अपने डिवाइस का क्रेडेंशियल डालें"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"अधूरा फ़िंगरप्रिंट प्रोसेस हो सका. कृपया फिर से कोशिश करें."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फ़िंगरप्रिंट प्रोसेस नहीं हो सका. कृपया दोबारा कोशिश करें."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"फ़िंगरप्रिंट सेंसर गंदा है. कृपया साफ़ करें और फिर कोशिश करें."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फ़िंगरप्रिंट इस्तेमाल करें"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फ़िंगरप्रिंट या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"जारी रखने के लिए फ़िंगरप्रिंट का इस्तेमाल करें"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"इस डिवाइस पर \'मालिक का चेहरा पहचानकर अनलॉक\' काम नहीं करती है."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
<string name="face_name_template" msgid="3877037340223318119">"चेहरा <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"\'फ़ेस अनलॉक\' इस्तेमाल करें"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"चेहरा पहचानने की सुविधा या स्क्रीन लॉक का क्रेडेंशियल इस्तेमाल करें"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"जारी रखने के लिए, \'फ़ेस अनलॉक\' इस्तेमाल करें"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"चेहरे का आइकॉन"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"समाचार और पत्रिकाएं"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps और नेविगेशन ऐप्लिकेशन"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"उत्पादकता"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"सुलभता"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"डिवाइस में जगह"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB डीबग करना"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"घंटा"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3a6ce2179c96..15c36c9ba604 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Omogućuje aplikaciji izmjenu vaše zbirke fotografija."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz vaše medijske zbirke"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Omogućuje aplikaciji čitanje lokacija iz vaše medijske zbirke."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Upotreba biometrije"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Upotreba biometrijske autentifikacije ili zaključavanja zaslona"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite da ste to vi"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Upotrijebite svoju biometrijsku autentifikaciju da biste nastavili"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikacija otkazana"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentifikacija otkazana"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nisu postavljeni PIN, uzorak ni zaporka"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Pogreška prilikom autentifikacije"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Upotreba zaključavanja zaslona"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Unesite vjerodajnicu uređaja da biste nastavili"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Otkriven je djelomični otisak prsta. Pokušajte ponovo."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Obrada otiska prsta nije uspjela. Pokušajte ponovo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Senzor otiska prsta nije čist. Očistite ga i pokušajte ponovo."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor otiska prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Upotreba otiska prsta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Upotreba otiska prsta ili zaključavanja zaslona"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Otključavanje licem nije podržano na ovom uređaju."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je privremeno onemogućen."</string>
<string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Upotreba otključavanja licem"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Upotreba lica ili zaključavanja zaslona"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Upotrijebite otključavanje licem da biste nastavili"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona lica"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Vijesti i časopisi"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Karte i navigacija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivnost"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pristupačnost"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Pohrana na uređaju"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Otklanjanje pogrešaka putem USB-a"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"sat"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 3cd0aba28c04..f28f1b66518f 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Engedélyezi az alkalmazásnak a fényképgyűjtemény módosítását."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"helyek olvasása a médiagyűjteményből"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Engedélyezi az alkalmazásnak a helyek médiagyűjteményből való olvasását."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometriai feloldás használata"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"A folytatás biometriai feloldással vagy képernyőzárral lehetséges"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Igazolja, hogy Ön az"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"A folytatás biometriai feloldással lehetséges"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrikus hardver nem áll rendelkezésre"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Hitelesítés megszakítva"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nem ismerhető fel"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Hitelesítés megszakítva"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nem állított be PIN-kódot, mintát vagy jelszót."</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Hiba történt a hitelesítés közben"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Képernyőzár használata"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"A folytatáshoz adja meg az eszköz hitelesítési adatait"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"A rendszer az ujjlenyomatnak csak egy részletét érzékelte. Próbálkozzon újra."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nem sikerült feldolgozni az ujjlenyomatot. Próbálkozzon újra."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Az ujjlenyomat-olvasó koszos. Tisztítsa meg, majd próbálkozzon újra."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ez az eszköz nem rendelkezik ujjlenyomat-érzékelővel."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Az érzékelő átmenetileg le van tiltva."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Ujjlenyomat használata"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"A folytatás ujjlenyomattal vagy képernyőzárral lehetséges"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"A folytatáshoz használja ujjlenyomatát"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Az eszköz nem támogatja az arcalapú feloldást"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Az érzékelő átmenetileg le van tiltva."</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> arc"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Arcalapú feloldás használata"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"A folytatás arcalapú feloldással vagy képernyőzárral lehetséges"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"A folytatás arcalapú feloldással lehetséges"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Arcikon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Hírlapok és folyóiratok"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Térképek és navigáció"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Irodai alkalmazások"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Kisegítő alkalmazások"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Eszköztárhely"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-hibakeresés"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"óra"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 8d6e42e1e7ff..959cb572333e 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Թույլ է տալիս հավելվածին փոփոխել ձեր լուսանկարների հավաքածուն:"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ճանաչել տեղադրության մասին տվյալները մեդիա բովանդակության հավաքածուից"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Թույլ է տալիս հավելվածին ճանաչել տեղադրության մասին տվյալները ձեր մեդիա բովանդակության հավաքածուից:"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Կենսաչափական համակարգեր"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Օգտագործել կենսաչափական համակարգեր կամ էկրանի կողպում"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Հաստատեք ձեր ինքնությունը"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Շարունակելու համար օգտագործեք կենսաչափական համակարգեր"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Կենսաչափական սարքը հասանելի չէ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Նույնականացումը չեղարկվեց"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Չհաջողվեց ճանաչել"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Նույնականացումը չեղարկվեց"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Ավելացրեք PIN կոդ, նախշ կամ գաղտնաբառ։"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Չհաջողվեց նույնականացնել"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Էկրանի կողպում"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Շարունակելու համար մուտքագրեք սարքի նույնականացման տվյալները"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Մատնահետքն ամբողջությամբ չի սկանավորվել: Փորձեք նորից:"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Չհաջողվեց մշակել մատնահետքը: Նորից փորձեք:"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Մատնահետքերի սենսորն աղտոտված է: Մաքրեք այն և փորձեք նորից:"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Տվիչը ժամանակավորապես անջատված է:"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Օգտագործել մատնահետք"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Օգտագործել մատնահետք կամ էկրանի կողպում"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Շարունակելու համար անհրաժեշտ է ձեր մատնահետքը"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Դեմքով ապակողպումն այս սարքում չի աջակցվում"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Տվիչը ժամանակավորապես անջատված է:"</string>
<string name="face_name_template" msgid="3877037340223318119">"Դեմք <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Օգտագործել դեմքով ապակողպում"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Օգտագործել դեմքով ապակողպում կամ էկրանի կողպում"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Շարունակելու համար օգտագործեք դեմքով ապակողպում"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Դեմքի պատկերակ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Նորություններ և ամսագրեր"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Քարտեզներ և նավարկում"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Արդյունավետություն"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Հատուկ գործառույթներ"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Սարքի հիշողություն"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-ով վրիպազերծում"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ժամ"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 28d2ed8963b0..9f692098f12a 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Mengizinkan aplikasi untuk memodifikasi koleksi foto Anda."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"membaca lokasi dari koleksi media Anda"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Mengizinkan aplikasi untuk membaca lokasi dari koleksi media Anda."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Gunakan biometrik"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gunakan biometrik atau kunci layar"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifikasi bahwa ini memang Anda"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gunakan biometrik untuk melanjutkan"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometrik tidak tersedia"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentikasi dibatalkan"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Tidak dikenali"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentikasi dibatalkan"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Tidak ada PIN, pola, atau sandi yang disetel"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Error saat mengautentikasi"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gunakan kunci layar"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Masukkan kredensial perangkat untuk melanjutkan"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Sebagian sidik jari terdeteksi. Coba lagi."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Tidak dapat memproses sidik jari. Coba lagi."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Sensor sidik jari kotor. Bersihkan dan coba lagi."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Perangkat ini tidak memiliki sensor sidik jari."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor dinonaktifkan untuk sementara."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan sidik jari"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan sidik jari atau kunci layar"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gunakan sidik jari untuk melanjutkan"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Face unlock tidak didukung di perangkat ini."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor dinonaktifkan untuk sementara."</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> wajah"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Gunakan face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gunakan face lock atau kunci layar"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gunakan face unlock untuk melanjutkan"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikon wajah"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Berita &amp; Majalah"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Peta &amp; Navigasi"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitas"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Aksesibilitas"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Penyimpanan perangkat"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Proses debug USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"jam"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index cd5b35affb86..0e11f033b033 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Leyfir forritinu að breyta myndasafninu þínu."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lesa staðsetningar úr efnissafninu þínu"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Leyfir forritinu að lesa staðsetningar úr efnissafninu þínu."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Nota lífkenni"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Nota lífkenni eða skjálás"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Staðfestu hver þú ert"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Notaðu lífkenni til að halda áfram"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Lífkennavélbúnaður ekki tiltækur"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Hætt við auðkenningu"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Þekktist ekki"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Hætt við auðkenningu"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Ekkert PIN-númer, mynstur eða aðgangsorð stillt"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Villa við auðkenningu"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Nota skjálás"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Færðu inn skilríki tækisins til að halda áfram"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Hluti fingrafars greindist. Reyndu aftur."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ekki var hægt að vinna úr fingrafarinu. Reyndu aftur."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingrafaraskynjarinn er óhreinn. Hreinsaðu hann og reyndu aftur."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Þetta tæki er ekki með fingrafaralesara."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Slökkt tímabundið á skynjara."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Nota fingrafar"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Nota fingrafar eða skjálás"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Notaðu fingrafarið þitt til að halda áfram"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Andlitsopnun er ekki studd í þessu tæki."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Slökkt tímabundið á skynjara."</string>
<string name="face_name_template" msgid="3877037340223318119">"Andlit <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Nota andlitsopnun"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Nota andlit eða skjálás"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Notaðu andlitsopnun til að halda áfram"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Andlitstákn"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Fréttir og tímarit"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kort og leiðsögn"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Aðstoð"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Aðgengi"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Geymslurými tækis"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-villuleit"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"klst."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 83b4a684ae58..b41996e4cb58 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Consente all\'app di modificare la tua raccolta di foto."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lettura delle posizioni dalla tua raccolta multimediale"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Consente all\'app di leggere le posizioni dalla tua raccolta multimediale."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Usa la biometria"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usa la biometria o il blocco schermo"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica la tua identità"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Usa la biometria per continuare"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometrico non disponibile"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticazione annullata"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Non riconosciuto"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autenticazione annullata"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Non hai impostato PIN, sequenza o password"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Errore durante l\'autenticazione"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usa il blocco schermo"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Inserisci la credenziale del dispositivo per continuare"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Rilevata impronta parziale. Riprova."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossibile elaborare l\'impronta. Riprova."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Il sensore di impronte è sporco. Puliscilo e riprova."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Questo dispositivo non dispone di sensore di impronte."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensore temporaneamente disattivato."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usa l\'impronta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usa l\'impronta o il blocco schermo"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilizza la tua impronta per continuare"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"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>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Usa Sblocco con il volto"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usa Sblocco con il volto o il blocco schermo"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Usa Sblocco con il volto per continuare"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Icona volto"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Notizie e riviste"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps e Navigatore"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produttività"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibilità"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Memoria dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Debug USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ora"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index e3cb913fe0fd..be05cc00c3b0 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"מאפשרת לאפליקציה לשנות את אוסף התמונות שלך."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"לקרוא מיקומים מאוסף המדיה שלך"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"מאפשרת לאפליקציה לקרוא מיקומים מאוסף המדיה שלך."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"שימוש במידע ביומטרי"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"שימוש במידע ביומטרי בנעילת מסך"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"אימות זהותך"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"יש להשתמש במידע ביומטרי כדי להמשיך"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"חומרה ביומטרית לא זמינה"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"האימות בוטל"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"לא זוהתה"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"האימות בוטל"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"עוד לא הוגדרו קוד גישה, קו ביטול נעילה או סיסמה"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"שגיאה באימות"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"שימוש בנעילת מסך"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"יש להזין את פרטי הכניסה של המכשיר כדי להמשיך"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"זוהתה טביעת אצבע חלקית. אפשר לנסות שוב."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"לא ניתן היה לעבד את טביעת האצבע. נסה שוב."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"החיישן של טביעות האצבעות מלוכלך. צריך לנקות אותו ולנסות שוב."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר זה אין חיישן טביעות אצבע."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"שימוש בטביעת אצבע או בנעילת מסך"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"יש להשתמש בטביעת האצבע כדי להמשיך"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"המכשיר הזה לא תומך בשחרור נעילה על ידי זיהוי פנים."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"החיישן מושבת באופן זמני."</string>
<string name="face_name_template" msgid="3877037340223318119">"פנים <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"שחרור נעילה על ידי זיהוי פנים"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"שימוש בזיהוי פנים או בנעילת מסך"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"יש להשתמש בשחרור נעילה על ידי זיהוי פנים כדי להמשיך"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"סמל הפנים"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"חדשות וכתבי עת"</string>
<string name="app_category_maps" msgid="6395725487922533156">"מפות וניווט"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"פרודוקטיביות"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"נגישות"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"שטח האחסון במכשיר"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"‏ניקוי באגים ב-USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"שעה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 4b54bdbc2469..e7c343872b95 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"写真コレクションの変更をアプリに許可します。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"メディア コレクションの位置情報の読み取り"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"メディア コレクションの位置情報の読み取りをアプリに許可します。"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"生体認証の使用"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"生体認証または画面ロックの使用"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"本人確認"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"続行するには生体認証を使用してください"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"生体認証ハードウェアが利用できません"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"認証をキャンセルしました"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"認識されませんでした"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"認証をキャンセルしました"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN、パターン、パスワードが設定されていません"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"エラー認証"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"画面ロックの使用"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"続行するにはデバイスの認証情報を入力してください"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"指紋を一部しか検出できませんでした。もう一度お試しください。"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"指紋を処理できませんでした。もう一度お試しください。"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"指紋認証センサーに汚れがあります。汚れを落としてもう一度お試しください。"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"センサーが一時的に無効になっています。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"指紋 <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"指紋の使用"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"指紋または画面ロックの使用"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"続行するには指紋認証を使用してください"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"このデバイスでは、顔認証はご利用いただけません。"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"センサーが一時的に無効になっています。"</string>
<string name="face_name_template" msgid="3877037340223318119">"顔 <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"顔認証の使用"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"顔認証または画面ロックの使用"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"続行するには顔認証を使用してください"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"顔アイコン"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ニュース&雑誌"</string>
<string name="app_category_maps" msgid="6395725487922533156">"地図&ナビ"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"仕事効率化"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"ユーザー補助"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"デバイスのストレージ"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB デバッグ"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"時"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 7a03bb32efcb..3fb6c6954a98 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"აპი შეძლებს თქვენი ფოტოკოლექციის შეცვლას."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"მდებარეობების გაცნობა თქვენი მედიაკოლექციიდან"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"აპი შეძლებს მდებარეობების გაცნობას თქვენი მედიაკოლექციიდან."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"გამოიყენეთ ბიომეტრიული სისტემა"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"გამოიყენეთ ბიომეტრიული სისტემა ან ეკრანის დაბლოკვა"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"დაადასტურეთ ვინაობა"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"გასაგრძელებლად გამოიყენეთ თქვენი ბიომეტრიული მონაცემები"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ბიომეტრიული აპარატურა მიუწვდომელია"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ავტორიზაცია გაუქმდა"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"არ არის ამოცნობილი"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ავტორიზაცია გაუქმდა"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN-კოდი, ნიმუში ან პაროლი დაყენებული არ არის"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"შეცდომა ავთენტიკაციისას"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"გამოიყენეთ ეკრანის დაბლოკვა"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"გასაგრძელებლად შეიყვანეთ თქვენი მოწყობილობის ავტორიზაციის მონაცემი"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"აღმოჩენილია თითის ნაწილობრივი ანაბეჭდი. გთხოვთ, სცადოთ ხელახლა."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"თითის ანაბეჭდის დამუშავება ვერ მოხერხდა. გთხოვთ, ცადოთ ხელახლა."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"თითის ანაბეჭდის სენსორი დაბინძურებულია. გთხოვთ, გაასუფთაოთ და სცადოთ ხელახლა."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"გამოიყენეთ თითის ანაბეჭდი"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"გამოიყენეთ თითის ანაბეჭდი ან ეკრანის დაბლოკვა"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"გასაგრძელებლად გამოიყენეთ თქვენი თითის ანაბეჭდი"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"განბლოკვა სახით ამ მოწყობილობაზე მხარდაჭერილი არ არის."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"სენსორი დროებით გათიშულია."</string>
<string name="face_name_template" msgid="3877037340223318119">"სახე <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"გამოიყენეთ სახით განბლოკვა"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"გამოიყენეთ სახე ან ეკრანის დაბლოკვა"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"გასაგრძელებლად გამოიყენეთ სახით განბლოკვა"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"სახის ხატულა"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ახალი ამბები და ჟურნალები"</string>
<string name="app_category_maps" msgid="6395725487922533156">"რუკები და ნავიგაცია"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"პროდუქტიულობა"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"მარტივი წვდომა"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"მოწყობილობის მეხსიერება"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB გამართვა"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"საათი"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 1c00fe65ba82..4404603f09fc 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Қолданбаға суреттер жинағын өзгертуге мүмкіндік береді."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"медиамазмұн жинағынан геодеректерді оқу"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Қолданбаға медиамазмұн жинағынан геодеректерді оқуға мүмкіндік береді."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Биометриканы пайдалану"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометриканы немесе экран құлпын пайдалану"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Бұл сіз екеніңізді растаңыз"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Жалғастыру үшін биометрикаңызды пайдаланыңыз."</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрикалық жабдық жоқ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аутентификациядан бас тартылды."</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Танылмады"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Аутентификациядан бас тартылды."</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Ешқандай PIN коды, өрнек немесе құпия сөз орнатылмаған."</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Аутентификациялауда қате шықты."</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Экран құлпын пайдалану"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Жалғастыру үшін құрылғының тіркелу деректерін енгізіңіз."</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Саусақ ізі толық анықталмады. Әрекетті қайталаңыз."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Саусақ ізін өңдеу мүмкін емес. Әрекетті қайталаңыз."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сканер лас. Тазалап, әрекетті қайталаңыз."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> саусағы"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Саусақ ізін пайдалану"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Саусақ ізін немесе экран құлпын пайдалану"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Жалғастыру үшін саусақ ізін пайдаланыңыз."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Бұл құрылғыда Face Unlock функциясы істемейді."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Датчик уақытша өшірулі."</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> беті"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Face Unlock функциясын пайдалану"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Face Lock функциясын немесе экран құлпын пайдалану"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Жалғастыру үшін Face Unlock функциясын пайдаланыңыз."</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Бет белгішесі"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Газеттер және журналдар"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карта және навигация"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Өнімділік"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Арнайы мүмкіндіктер"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Құрылғы жады"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB арқылы түзету"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"сағат"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index a2512d2a9d08..fb1155318137 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"អនុញ្ញាតឱ្យ​កម្មវិធី​កែប្រែ​បណ្ដុំ​រូបថត​របស់​អ្នក។"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"អាន​ទីតាំង​ពី​បណ្ដុំ​មេឌៀ​របស់​អ្នក"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"អនុញ្ញាតឱ្យ​កម្មវិធី​អាន​ទីតាំង​ពីបណ្ដុំ​មេឌៀ​របស់​អ្នក។"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ប្រើ​ជីវមាត្រ"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ប្រើជីវមាត្រ ឬ​ការចាក់សោអេក្រង់"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ផ្ទៀងផ្ទាត់ថាជាអ្នក"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ប្រើជីវមាត្រ​របស់អ្នក ដើម្បីបន្ត"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"មិនអាច​ប្រើឧបករណ៍​ស្កេន​ស្នាមម្រាមដៃ​បានទេ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"បាន​បោះបង់​ការ​ផ្ទៀងផ្ទាត់"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"មិនអាចសម្គាល់បានទេ"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"បាន​បោះបង់​ការ​ផ្ទៀងផ្ទាត់"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"គ្មាន​ការកំណត់​កូដ pin លំនាំ ឬពាក្យសម្ងាត់​ទេ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"មានបញ្ហាក្នុង​ការផ្ទៀងផ្ទាត់"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ប្រើ​ការ​ចាក់​សោ​អេក្រង់"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"បញ្ចូល​ព័ត៌មានផ្ទៀងផ្ទាត់​ឧបករណ៍​របស់អ្នក ដើម្បីបន្ត"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"បានផ្តិតយកស្នាមម្រាមដៃមិនពេញលក្ខណៈ។ សូមព្យាយាមម្តងទៀត។"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"មិនអាចដំណើរការស្នាមម្រាមដៃបានទេ។ សូមព្យាយាមម្តងទៀត។"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ឧបករណ៍ចាប់ស្នាមម្រាមដៃគឺប្រឡាក់។ សូមសម្អាត រួចព្យាយាមម្តងទៀត។"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះ​មិនមាន​ឧបករណ៍ចាប់​ស្នាមម្រាមដៃទេ។"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទ​ឧបករណ៍​ចាប់សញ្ញាជា​បណ្តោះអាសន្ន។"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ប្រើស្នាមម្រាមដៃ"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ប្រើស្នាមម្រាមដៃ ឬ​ការចាក់សោអេក្រង់"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ប្រើ​ស្នាមម្រាមដៃ​របស់អ្នក ដើម្បីបន្ត"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"មិនអាចប្រើ​ការដោះសោតាមទម្រង់មុខ​នៅលើ​ឧបករណ៍​នេះ​បានទេ។"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"បានបិទ​ឧបករណ៍​ចាប់សញ្ញាជា​បណ្តោះអាសន្ន។"</string>
<string name="face_name_template" msgid="3877037340223318119">"ផ្ទៃមុខទី <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ប្រើការដោះសោ​តាមទម្រង់មុខ"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ប្រើមុខ ឬ​ការចាក់សោអេក្រង់"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ប្រើការដោះសោ​តាមទម្រង់មុខ ដើម្បីបន្ត"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"រូប​ផ្ទៃមុខ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ព័ត៌មាន និង​ទស្សនាវដ្ដី"</string>
<string name="app_category_maps" msgid="6395725487922533156">"ផែនទី និង​ការ​រុករក"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ផលិត​ភាព"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"ភាពងាយស្រួល"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"ទំហំផ្ទុកឧបករណ៍"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"ការ​កែកំហុសតាម USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ម៉ោង"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index e9110c217d4a..f484344d7891 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ನಿಮ್ಮ ಫೋಟೋ ಸಂಗ್ರಹಣೆಯನ್ನು ಮಾರ್ಪಡಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ನಿಮ್ಮ ಮೀಡಿಯಾ ಸಂಗ್ರಹಣೆಯಿಂದ ಸ್ಥಳಗಳನ್ನು ಓದಿ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ನಿಮ್ಮ ಮೀಡಿಯಾ ಸಂಗ್ರಹಣೆಯಿಂದ ಸ್ಥಳಗಳನ್ನು ಓದಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ಬಯೋಮೆಟ್ರಿಕ್ಸ್ ಬಳಸಿ"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ಬಯೋಮೆಟ್ರಿಕ್ಸ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ಇದು ನೀವೇ ಎಂದು ಪರಿಶೀಲಿಸಿ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಬಯೋಮೆಟ್ರಿಕ್ ಬಳಸಿ"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್‌ವೇರ್‌ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ಪ್ರಮಾಣೀಕರಣವನ್ನು ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ಪ್ರಮಾಣೀಕರಣವನ್ನು ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ಪಿನ್, ಪ್ಯಾಟರ್ನ್ ಅಥವಾ ಪಾಸ್‌ವರ್ಡ್ ಸೆಟ್ ಮಾಡಿಲ್ಲ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"ದೃಢೀಕರಿಸುವಾಗ ದೋಷ ಎದುರಾಗಿದೆ"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಸಾಧನದ ರುಜುವಾತನ್ನು‌ ನಮೂದಿಸಿ"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ಭಾಗಶಃ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಪತ್ತೆಯಾಗಿದೆ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಕೊಳೆಯಾಗಿದೆ. ದಯವಿಟ್ಟು ಅದನ್ನು ಸ್ವಚ್ಛಗೊಳಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬಳಸಿ"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"ಈ ಸಾಧನದಲ್ಲಿ ಫೇಸ್ ಅನ್‌ಲಾಕ್ ವೈಶಿಷ್ಟ್ಯವು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="face_name_template" msgid="3877037340223318119">"ಮುಖದ <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಬಳಸಿ‌‌"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ಫೇಸ್ ಅಥವಾ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ಮುಂದುವರಿಸಲು ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ಮುಖದ ಐಕಾನ್‌"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ಸುದ್ದಿ ಮತ್ತು ನಿಯತಕಾಲಿಕೆಗಳು"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps ಮತ್ತು ನ್ಯಾವಿಗೇಶನ್"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ಉತ್ಪಾದಕತೆ"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"ಪ್ರವೇಶಿಸುವಿಕೆ"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"ಸಾಧನ ಸಂಗ್ರಹಣೆ"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ಗಂಟೆ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 16e2efa6f5c0..78cc1b572e04 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"앱에서 사진 컬렉션을 수정하도록 허용합니다."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"미디어 컬렉션에서 위치 읽기"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"앱에서 미디어 컬렉션의 위치를 읽도록 허용합니다."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"생체 인식 사용"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"생체 인식 또는 화면 잠금을 사용"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"본인 확인"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"생체 인식을 사용하여 계속하세요"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"생체 인식 하드웨어를 사용할 수 없음"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"인증이 취소되었습니다."</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"인식할 수 없음"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"인증이 취소되었습니다."</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN, 패턴, 비밀번호가 설정되지 않음"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"인증 오류"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"화면 잠금 사용"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"계속하려면 기기의 사용자 인증 정보를 입력하세요"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"지문이 일부만 인식되었습니다. 다시 시도해 주세요."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"지문을 인식할 수 없습니다. 다시 시도해 주세요."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"지문 센서를 깨끗이 닦고 다시 시도하세요."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"센서가 일시적으로 사용 중지되었습니다."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"지문 사용"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"지문 또는 화면 잠금 사용"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"계속하려면 지문을 사용하세요."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"이 기기에서는 얼굴인식 잠금해제가 지원되지 않습니다."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"센서가 일시적으로 사용 중지되었습니다."</string>
<string name="face_name_template" msgid="3877037340223318119">"얼굴 <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"얼굴인식 잠금해제 사용"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"얼굴 또는 화면 잠금 사용"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"얼굴인식 잠금해제를 사용하여 계속하세요"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"얼굴 아이콘"</string>
@@ -1699,7 +1689,7 @@
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"기능 간에 전환하려면 세 손가락을 사용하여 위로 스와이프한 다음 잠시 기다립니다."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"확대"</string>
<string name="user_switched" msgid="7249833311585228097">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
- <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>(으)로 전환하는 중…"</string>
+ <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>로 전환하는 중…"</string>
<string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g>님을 로그아웃하는 중…"</string>
<string name="owner_name" msgid="8713560351570795743">"소유자"</string>
<string name="error_message_title" msgid="4082495589294631966">"오류"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"뉴스/잡지"</string>
<string name="app_category_maps" msgid="6395725487922533156">"지도/내비게이션"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"생산성"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"접근성"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"기기 저장용량"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB 디버깅"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"시"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 258422574dd7..5d8b8980d2f5 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Колдонмого сүрөт жыйнагыңызды өзгөртүүгө мүмкүнчүлүк берет."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"медиа жыйнагыңыз сакталган жерлерди окуу"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Колдонмого медиа жыйнагыңыз сакталган жерлерди окууга мүмкүнчүлүк берет."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Биометрикалык жөндөөлөрдү колдонуу"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометрикалык жөндөөнү же экрандын кулпусун колдонуу"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Өзүңүздү ырастаңыз"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Улантуу үчүн биометрикалык жөндөөнү колдонуу"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрикалык аппарат жеткиликсиз"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аныктыгын текшерүү жокко чыгарылды"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Таанылган жок"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Аныктыгын текшерүү жокко чыгарылды"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN код, графикалык ачкыч же сырсөз коюлган жок"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Аутентификация катасы"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Экран кулпусун колдонуу"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Улантуу үчүн түзмөгүңүздүн эсептик дайындарын киргизиңиз"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Манжа изи жарым-жартылай аныкталды. Кайталап көрүңүз."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Манжа изи иштелбей койду. Кайталап көрүңүз."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Манжа изинин сенсору кирдеп калган. Тазалап, кайталап көрүңүз."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Манжа изин колдонуу"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Манжа изин же экрандын кулпусун колдонуу"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Улантуу үчүн манжаңыздын изин колдонуңуз"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Жүзүнөн таануу функциясы бул түзмөктө иштебейт."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Сенсор убактылуу өчүрүлгөн."</string>
<string name="face_name_template" msgid="3877037340223318119">"Жүз <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Жүзүнөн таанып ачууну колдонуу"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Жүзүнөн таанып ачууну же экрандын кулпусун колдонуу"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Улантуу үчүн жүзүнөн таанып ачууну колдонуу"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Жүздүн сүрөтчөсү"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Жаңылыктар жана журналдар"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карталар жана чабыттоо"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Өндүрүш категориясы"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Атайын мүмкүнчүлүктөр"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Түзмөктүн сактагычы"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB аркылуу мүчүлүштүктөрдү аныктоо"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"саат"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 7fb32e7d2034..fcf47edbfc47 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ອະນຸຍາດໃຫ້ແອັບແກ້ໄຂຄໍເລັກຊັນຮູບຂອງທ່ານ."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ອ່ານສະຖານທີ່ຈາກຄໍເລັກຊັນມີເດຍຂອງທ່ານ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ອະນຸຍາດໃຫ້ແອັບອ່ານສະຖານທີ່ຈາກຄໍເລັກຊັນມີເດຍຂອງທ່ານ."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ໃຊ້ລະບົບຊີວະມິຕິ"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ໃຊ້ລະບົບຊີວະມິຕິ ຫຼື ການລັອກໜ້າຈໍ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ຢັ້ງຢືນວ່າແມ່ນທ່ານ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ໃຊ້ລະບົບຊີວະມິຕິຂອງທ່ານເພື່ອດຳເນີນການຕໍ່"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ຮາດແວຊີວະມິຕິບໍ່ສາມາດໃຊ້ໄດ້"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ຍົກເລີກການຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"ບໍ່ຮັບຮູ້"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ຍົກເລີກການຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ບໍ່ໄດ້ຕັ້ງ PIN, ຮູບແບບປົດລັອກ ຫຼື ລະຫັດຜ່ານ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"ເກີດຄວາມຜິດພາດໃນການພິສູດຢືນຢັນ"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ໃຊ້ການລັອກໜ້າຈໍ"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ລະບຸຂໍ້ມູນການເຂົ້າສູ່ລະບົບອຸປະກອນຂອງທ່ານເພື່ອດຳເນີນການຕໍ່"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ກວດ​ພົບ​ລາຍ​ນີ້ວ​ມື​ບາງ​ສ່ວນ​ແລ້ວ. ກະ​ລຸ​ນາ​ລອງ​ໃໝ່​ອີກ."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ບໍ່​ສາ​ມາດ​ດຳ​ເນີນ​ການ​ລາຍ​ນີ້ວ​ມື​ໄດ້. ກະ​ລຸ​ນາ​ລອງ​ໃໝ່​ອີກ."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ເຊັນ​ເຊີ​ລາຍ​ນີ້ວ​ມື​ເປື້ອນ. ກະ​ລຸ​ນາ​ທຳ​ຄວາມ​ສະ​ອາດ ແລະ​ລອງ​ໃໝ່​ອີກ."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ນີ້ວ​ມື <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ໃຊ້ລາຍນິ້ວມື"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ໃຊ້ລາຍນິ້ວມື ຫຼື ການລັອກໜ້າຈໍ"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ໃຊ້​ລາຍ​ນີ້ວ​ມື​ຂອງ​ທ່ານ​ເພື່ອ​ສືບ​ຕໍ່"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"ບໍ່ຮອງຮັບການປົດລັອກດ້ວຍໜ້າຢູ່ອຸປະກອນນີ້."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
<string name="face_name_template" msgid="3877037340223318119">"ໃບໜ້າ <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ໃຊ້ການປົດລັອກດ້ວຍໜ້າ"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ໃຊ້ໃບໜ້າ ຫຼື ການລັອກໜ້າຈໍ"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ໃຊ້ການປົດລັອກດ້ວຍໜ້າເພື່ອດຳເນີນການຕໍ່"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ໄອຄອນໃບໜ້າ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"News &amp; Magazines"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps &amp; Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ຜະລິດຕະພາບ"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"ການຊ່ວຍເຂົ້າເຖິງ"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"ບ່ອນຈັດເກັບຂໍ້ມູນອຸປະກອນ"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"ການດີບັກຜ່ານ USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ຊົ່ວໂມງ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 820d7a029b9e..4afef3be17d4 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Programai leidžiama keisti nuotraukų kolekciją."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"skaityti vietoves iš medijos kolekcijos"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Programai leidžiama skaityti vietoves iš medijos kolekcijos."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Naudoti biometrinius duomenis"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Naudoti biometrinius duomenis arba ekrano užraktą"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Patvirtinkite, kad tai jūs"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Norėdami tęsti, naudokite biometrinius duomenis"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrinė aparatinė įranga nepasiekiama"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikavimas atšauktas"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Neatpažinta"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentifikavimas atšauktas"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nenustatytas PIN kodas, atrakinimo piešinys arba slaptažodis"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Autentifikuojant įvyko klaida"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Naudoti ekrano užraktą"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Jei norite tęsti, įveskite įrenginio prisijungimo duomenis"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Aptiktas dalinis piršto antspaudas. Bandykite dar kartą."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nepavyko apdoroti piršto antspaudo. Bandykite dar kartą."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Piršto antspaudo jutiklis purvinas. Nuvalykite ir bandykite dar kartą."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šiame įrenginyje nėra kontrolinio kodo jutiklio."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Jutiklis laikinai išjungtas."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Naudoti kontrolinį kodą"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Naudoti kontrolinį kodą arba ekrano užraktą"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Naudokite kontrolinį kodą, kad galėtumėte tęsti"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Atrakinimas pagal veidą šiame įrenginyje nepalaikomas."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Jutiklis laikinai išjungtas."</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g> veidas"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Naudoti atrakinimą pagal veidą"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Naudoti atrakinimą pagal veidą arba ekrano užraktą"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Norėdami tęsti, naudokite atrakinimą pagal veidą"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Veido pkt."</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Naujienos ir žurnalai"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Žemėlapiai ir navigacija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktyvumas"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pritaikomumas"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Įrenginio saugykla"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB derinimas"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"valanda"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 91c38a4ac3bd..8fbfb279daf9 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Ļauj lietotnei pārveidot jūsu fotoattēlu kolekciju."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"Lasīt atrašanās vietas no jūsu multivides kolekcijas"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Ļauj lietotnei lasīt atrašanās vietas no jūsu multivides kolekcijas."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrijas izmantošana"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrijas vai ekrāna bloķēšanas izmantošana"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Apstipriniet, ka tas esat jūs"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Lai turpinātu, izmantojiet biometriju"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisko datu aparatūra nav pieejama"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikācija ir atcelta"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Dati nav atpazīti"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentifikācija ir atcelta"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN, kombinācija vai parole nav iestatīta"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Autentifikācijas kļūda"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekrāna bloķēšanas metodes izmantošana"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Lai turpinātu, ievadiet savas ierīces akreditācijas datus"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Noteikts daļējs pirksta nospiedums. Lūdzu, mēģiniet vēlreiz."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nevarēja apstrādāt pirksta nospiedumu. Lūdzu, mēģiniet vēlreiz."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Pirkstu nospiedumu sensors ir netīrs. Lūdzu, notīriet to un mēģiniet vēlreiz."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šajā ierīcē nav pirksta nospieduma sensora."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensors ir īslaicīgi atspējots."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Pirksta nospieduma izmantošana"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Pirksta nospieduma vai ekrāna bloķēšanas metodes izmantošana"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Lai turpinātu, izmantojiet pirksta nospiedumu"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Autorizācija pēc sejas šajā ierīcē netiek atbalstīta"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensors ir īslaicīgi atspējots."</string>
<string name="face_name_template" msgid="3877037340223318119">"Seja <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Autorizācija pēc sejas"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Autorizācijas pēc sejas vai ekrāna bloķēšanas metodes izmantošana"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Lai turpinātu, izmantojiet autorizāciju pēc sejas"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Sejas ikona"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Ziņas un žurnāli"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kartes un navigācija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitāte"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pieejamība"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Ierīces krātuve"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB atkļūdošana"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"stunda"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 88fb8246845f..9d07234910fe 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/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="byteShort" msgid="202579285008794431">"Б"</string>
+ <string name="byteShort" msgid="202579285008794431">"B"</string>
<string name="kilobyteShort" msgid="2214285521564195803">"KB"</string>
<string name="megabyteShort" msgid="6649361267635823443">"MB"</string>
<string name="gigabyteShort" msgid="7515809460261287991">"GB"</string>
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Дозволува апликацијата да ја менува вашата збирка на фотографии."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"да чита локации од вашата збирка на аудиовизуелни содржини"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Дозволува апликацијата да чита локации од вашата збирка на аудиовизуелни содржини."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Користи биометрика"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користи биометрика или заклучен екран"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Потврдете дека сте вие"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Користете ја вашата биометрика за да продолжите"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрискиот хардвер е недостапен"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Проверката е откажана"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Непознат"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Проверката е откажана"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Не е поставен PIN, шема или лозинка"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при проверката"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користи заклучување екран"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Внесете го акредитивот на уредот за да продолжите"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Откриен е делумен отпечаток. Обидете се повторно."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатокот не може да се обработи. Обидете се повторно."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сензорот за отпечатоци е валкан. Исчистете го и обидете се повторно."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорот е привремено оневозможен."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користи отпечаток"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користи отпечаток или заклучување екран"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Користете го отпечатокот за да продолжите"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"„Отклучувањето со лик“ не е поддржано на уредов."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Сензорот е привремено оневозможен."</string>
<string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Користи отклучување со лик"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Користи лик или заклучување екран"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Користете отклучување со лик за да продолжите"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Икона"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Вести и списанија"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карти и навигација"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Продуктивност"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Пристапност"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Простор на уредот"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Отстранување грешки на USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"час"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index f82267d115eb..8d91c5182b16 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"നിങ്ങളുടെ ഫോട്ടോ ശേഖരം പരിഷ്‌ക്കരിക്കുന്നതിന് ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"നിങ്ങളുടെ മീഡിയ ശേഖരത്തിൽ നിന്നും ലൊക്കേഷനുകൾ റീഡ് ചെയ്യുക"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"നിങ്ങളുടെ മീഡിയ ശേഖരത്തിൽ നിന്നും ലൊക്കേഷനുകൾ റീഡ് ചെയ്യുന്നതിന് ആപ്പിനെ അനുവദിക്കുന്നു."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ബയോമെട്രിക്‌സ് ഉപയോഗിക്കുക"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ബയോമെട്രിക്‌സ് അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ഇത് നിങ്ങളാണെന്ന് പരിശോധിച്ചുറപ്പിക്കുക"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"തുടരാൻ ബയോമെട്രിക് ഉപയോഗിക്കുക"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ബയോമെട്രിക് ഹാർ‌ഡ്‌വെയർ ലഭ്യമല്ല"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"പരിശോധിച്ചുറപ്പിക്കൽ റദ്ദാക്കി"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"തിരിച്ചറിഞ്ഞില്ല"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"പരിശോധിച്ചുറപ്പിക്കൽ റദ്ദാക്കി"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"പിന്നോ പാറ്റേണോ പാസ്‌വേഡോ സജ്ജീകരിച്ചിട്ടില്ല"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"പിശക് പരിശോധിച്ചുറപ്പിക്കുന്നു"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"തുടരാൻ നിങ്ങളുടെ ഉപകരണ ക്രെഡൻഷ്യലുകൾ നൽകുക"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ഫിംഗർപ്രിന്റ് ഭാഗികമായി തിരിച്ചറിഞ്ഞു. വീണ്ടും ശ്രമിക്കുക."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ഫിംഗർപ്രിന്റ് പ്രോസസ് ചെയ്യാനായില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ഫിംഗർപ്രിന്റ് സെൻസറിൽ ചെളിയുണ്ട്. അത് വൃത്തിയാക്കി വീണ്ടും ശ്രമിക്കുക."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"കൈവിരൽ <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ഫിംഗർപ്രിന്റ് അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"തുടരുന്നതിന് നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഈ ഉപകരണം പിന്തുണയ്ക്കുന്നില്ല."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string>
<string name="face_name_template" msgid="3877037340223318119">"മുഖം <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഉപയോഗിക്കുക"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"മുഖം അല്ലെങ്കിൽ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"തുടരാൻ മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഉപയോഗിക്കുക"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"മുഖത്തിന്റെ ഐക്കൺ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"വാർത്തകളും മാസികകളും"</string>
<string name="app_category_maps" msgid="6395725487922533156">"മാപ്പുകളും നാവിഗേഷനും"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ഉല്‍‌പ്പാദനക്ഷമത"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"ഉപയോഗസഹായി"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"ഉപകരണ സ്റ്റോറേജ്"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB ഡീബഗ്ഗിംഗ്"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"മണി."</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 203ad3d39060..faec2be635ba 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Таны зургийн цуглуулгыг тохируулах зөвшөөрлийг аппад олгодог."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"медиа цуглуулгаасаа байршлыг унших"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Таны медиа цуглуулгаас байршлыг унших зөвшөөрлийг аппад олгодог."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Биометр ашиглах"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Биометр эсвэл дэлгэцийн түгжээ ашиглах"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Өөрийгөө мөн гэдгийг баталгаажуулаарай"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Үргэлжлүүлэхийн тулд биометрээ ашиглана уу"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрийн техник хангамж боломжгүй байна"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Нотолгоог цуцаллаа"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Таниагүй"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Нотолгоог цуцаллаа"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Тохируулсан пин, хээ эсвэл нууц үг алга"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Баталгаажуулахад алдаа гарлаа"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Дэлгэцийн түгжээг ашиглах"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Үргэлжлүүлэхийн тулд төхөөрөмжийнхөө мандат үнэмлэхийг оруулна уу"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Хурууны хээг дутуу уншуулсан байна. Дахин оролдоно уу."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Хурууны хээ боловсруулж чадахгүй байна. Дахин оролдоно уу."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Хурууны хээ мэдрэгч бохирдсон байна. Цэвэрлэсний дараа дахин оролдоно уу."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Хурууны хээ ашиглах"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Хурууны хээ эсвэл дэлгэцийн түгжээ ашиглах"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Үргэлжлүүлэхийн тулд хурууны хээгээ ашиглаарай"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Царайгаар тайлахыг энэ төхөөрөмж дээр дэмждэггүй."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string>
<string name="face_name_template" msgid="3877037340223318119">"Царай <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Царайгаар тайлахыг ашиглах"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Царай эсвэл дэлгэцийн түгжээ ашиглах"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Үргэлжлүүлэхийн тулд царайгаар тайлахыг ашиглана уу"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Царайны дүрс тэмдэг"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Мэдээ &amp; сэтгүүл"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Газрын зураг &amp; зүг чиг"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Бүтээмж"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Хандалт"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Төхөөрөмжийн сан"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB дебаг хийлт"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"Цаг"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index d8d43a64ab7b..3bf30638d95a 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Membenarkan apl mengubah suai koleksi foto anda."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"baca lokasi daripada koleksi media anda"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Membenarkan apl membaca lokasi daripada koleksi media anda."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Gunakan biometrik"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gunakan biometrik atau kunci skrin"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Sahkan itu anda"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gunakan biometrik anda untuk meneruskan"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Perkakasan biometrik tidak tersedia"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Pengesahan dibatalkan"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Tidak dikenali"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Pengesahan dibatalkan"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Pin, corak atau kata laluan tidak ditetapkan"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Ralat semasa membuat pengesahan"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gunakan kunci skrin"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Masukkan bukti kelayakan peranti anda untuk meneruskan"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Cap jari separa dikesan. Sila cuba lagi."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Tidak dapat memproses cap jari. Sila cuba lagi."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Penderia cap jari kotor. Sila bersihkan dan cuba lagi."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Peranti ini tiada penderia cap jari."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Penderia dilumpuhkan sementara."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gunakan cap jari"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gunakan cap jari atau kunci skrin"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gunakan cap jari anda untuk teruskan"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Wajah buka kunci tidak disokong pada peranti ini."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Penderia dilumpuhkan sementara."</string>
<string name="face_name_template" msgid="3877037340223318119">"Wajah <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Gunakan wajah buka kunci"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gunakan kunci wajah atau skrin"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gunakan wajah buka kunci untuk meneruskan"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikon wajah"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Berita &amp; Majalah"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Peta &amp; Navigasi"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktiviti"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Kebolehaksesan"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Storan peranti"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Penyahpepijatan USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"jam"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 82008b069346..f301483c6b56 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"အက်ပ်အား သင့်ဓာတ်ပုံစုစည်းမှုကို ပြုပြင်ခွင့်ပေးသည်။"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"သင့်မီဒီယာစုစည်းမှုမှ တည်နေရာများကို ဖတ်ခြင်း"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"အက်ပ်အား သင့်မီဒီယာစုစည်းမှုမှ တည်နေရာများကို ဖတ်ခွင့်ပေးသည်။"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ဇီဝမက်ထရစ်အချက်အလက်များ သုံးခြင်း"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ဇီဝမက်ထရစ်အချက်အလက်များ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"သင်ဖြစ်ကြောင်း အတည်ပြုပါ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ရှေ့ဆက်ရန် သင်၏ ဇီဝမက်ထရစ်အချက်အလက်ကို သုံးပါ"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ဇီဝအချက်အလက်သုံး ကွန်ပျူတာစက်ပစ္စည်း မရရှိနိုင်ပါ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်လိုက်သည်"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"မသိ"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်လိုက်သည်"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ပင်နံပါတ်၊ လော့ခ်ပုံစံ သို့မဟုတ် စကားဝှက် သတ်မှတ်မထားပါ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"အထောက်အထားစိစစ်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ရှေ့ဆက်ရန် သင့်စက်ပစ္စည်း၏ အထောက်အထားကို ထည့်သွင်းပါ"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"လက်ဗွေ တစ်ပိုင်းတစ်စ တွေ့ရှိသည်။ ကျေးဇူးပြု၍ ထပ်စမ်းကြည့်ပါ။"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"လက်ဗွေယူ၍ မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"လက်ဗွေဖတ်ကိရိယာ ညစ်ပေနေသည်။ ကျေးဇူးပြု၍ သန့်ရှင်းလိုက်ပြီး ပြန်စမ်းကြည့်ပါ။"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"လက်ဗွေ သုံးခြင်း"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"လက်ဗွေ (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ရှေ့ဆက်ရန် သင့်လက်ဗွေကို သုံးပါ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"ဤစက်ပစ္စည်းတွင် မျက်နှာမှတ် သော့ဖွင့်ခြင်းကို သုံး၍မရပါ။"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string>
<string name="face_name_template" msgid="3877037340223318119">"မျက်နှာ <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"မျက်နှာမှတ်သော့ဖွင့်ခြင်းကို သုံးခြင်း"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"မျက်နှာမှတ်သော့ဖွင့်ခြင်း (သို့) ဖန်သားပြင်လော့ခ်ချခြင်းကို သုံးခြင်း"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ရှေ့ဆက်ရန် မျက်နှာမှတ်သော့ဖွင့်ခြင်းကို သုံးပါ"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"မျက်နှာသင်္ကေတ"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"သတင်းနှင့် မဂ္ဂဇင်းများ"</string>
<string name="app_category_maps" msgid="6395725487922533156">"မြေပုံနှင့် ခရီးလမ်းညွှန်ချက်"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ထုတ်လုပ်နိုင်မှု"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"အများသုံးစွဲနိုင်မှု"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"စက်ပစ္စည်း သိုလှောင်ခန်း"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB အမှားရှာပြင်ခြင်း"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"နာရီ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 1bafd6006e3c..07cf9c06f8fe 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Lar appen gjøre endringer i bildesamlingen din."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lese posisjoner fra mediesamlingen din"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Lar appen lese posisjoner fra mediesamlingen din."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Bruk biometri"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Bruk biometri eller skjermlås"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Bekreft at det er deg"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Bruk biometri for å fortsette"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisk maskinvare er utilgjengelig"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentiseringen er avbrutt"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ikke gjenkjent"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentiseringen er avbrutt"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN-kode, mønster eller passord er ikke angitt"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Feil under autentiseringen"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Bruk skjermlås"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Skriv inn enhetslegitimasjonen din for å fortsette"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Deler av fingeravtrykket er registrert. Prøv på nytt."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kunne ikke registrere fingeravtrykket. Prøv på nytt."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingeravtrykksensoren er skitten. Rengjør den og prøv på nytt."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enheten har ikke fingeravtrykkssensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidig slått av."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Bruk fingeravtrykk"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Bruk fingeravtrykk eller skjermlås"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Bruk fingeravtrykket ditt for å fortsette"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Ansiktslås støttes ikke på denne enheten"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensoren er midlertidig slått av."</string>
<string name="face_name_template" msgid="3877037340223318119">"Ansikt <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Bruk ansiktslås"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Bruk ansikts- eller skjermlås"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Bruk ansiktslås for å fortsette"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ansiktikon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Nyheter og tidsskrifter"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kart og navigering"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitet"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Tilgjengelighet"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Lagring på enheten"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-feilsøking"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"time"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index a15a9a46a4d1..6295d4455ac2 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"यसले एपलाई तपाईंको तस्बिरको सङ्ग्रह परिमार्जन गर्न दिन्छ।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"आफ्नो मिडियाको सङ्ग्रहका स्थानहरू पढ्नुहोस्‌"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"यसले एपलाई तपाईंको मिडिया सङ्ग्रहका स्थानहरू पढ्न दिन्छ।"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"बायोमेट्रिक्स प्रयोग गर्नुहोस्"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"बायोमेट्रिक्स वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"यो व्यक्ति तपाईं नै हो भन्ने प्रमाणित गर्नुहोस्"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"जारी राख्न आफ्नो बायोमेट्रिक प्रयोग गर्नुहोस्"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"बायोमेट्रिक हार्डवेयर उपलब्ध छैन"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"प्रमाणीकरण रद्द गरियो"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"पहिचान भएन"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"प्रमाणीकरण रद्द गरियो"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"कुनै पनि PIN, ढाँचा वा पासवर्ड सेट गरिएको छैन"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"प्रमाणित गर्ने क्रममा त्रुटि भयो"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"स्क्रिन लक प्रयोग गर्नुहोस्"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"जारी राख्न आफ्नो यन्त्रको PIN, प्याटर्न वा पासवर्ड हाल्नुहोस्"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"आंशिक फिंगरप्रिन्ट पत्ता लाग्यो। कृपया फेरि प्रयास गर्नुहोस्।"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फिंगरप्रिन्ट प्रशोधन गर्न सकिएन। कृपया फेरि प्रयास गर्नुहोस्।"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"फिंगरप्रिन्ट सेन्सर फोहोर छ। कृपया सफा गरेर फेरि प्रयास गर्नुहोस्।"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो यन्त्रमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"फिंगरप्रिन्ट वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"जारी राख्न आफ्नो फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"यस यन्त्रमा फेस अनलक सुविधा प्रयोग गर्न मिल्दैन।"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"केही समयका लागि सेन्सर असक्षम पारियो।"</string>
<string name="face_name_template" msgid="3877037340223318119">"अनुहार <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"फेस अनलक प्रयोग गर्नुहोस्"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"फेस अनलक वा स्क्रिन लक प्रयोग गर्नुहोस्"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"जारी राख्न फेस अनलक प्रयोग गर्नुहोस्"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"अनुहारको आइकन"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"समाचार तथा पत्रिकाहरू"</string>
<string name="app_category_maps" msgid="6395725487922533156">"नक्सा तथा नेभिगेसन"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"उत्पादकत्व"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"सर्वसुलभता"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"यन्त्रको भण्डारण"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB डिबग प्रक्रिया"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"घन्टा"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 1f2680e2b101..46880ea78016 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Hiermee sta je de app toe je fotocollectie aan te passen."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"locaties van je mediacollecties bekijken"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Hiermee sta je de app toe locaties van je mediacollectie te bekijken."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrische gegevens gebruiken"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrische gegevens of schermvergrendeling gebruiken"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Je identiteit verifiëren"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gebruik je biometrische gegevens om door te gaan"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrische hardware niet beschikbaar"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Verificatie geannuleerd"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Niet herkend"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Verificatie geannuleerd"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Geen pincode, patroon of wachtwoord ingesteld"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Fout bij verificatie"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Schermvergrendeling gebruiken"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Geef de inloggegevens van je apparaat op om door te gaan"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Gedeeltelijke vingerafdruk gedetecteerd. Probeer het opnieuw."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kan vingerafdruk niet verwerken. Probeer het opnieuw."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"De vingerafdruksensor moet worden schoongemaakt. Probeer het daarna opnieuw."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dit apparaat heeft geen vingerafdruksensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor tijdelijk uitgeschakeld."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Vingerafdruk gebruiken"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Vingerafdruk of schermvergrendeling gebruiken"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gebruik je vingerafdruk om door te gaan."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Ontgrendelen via gezichtsherkenning wordt niet ondersteund op dit apparaat."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor tijdelijk uitgeschakeld."</string>
<string name="face_name_template" msgid="3877037340223318119">"Gezicht <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Ontgrendelen via gezichtsherkenning gebruiken"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gezicht of schermgrendeling gebruiken"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gebruik ontgrendelen via gezichtsherkenning om door te gaan"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Gezichtspictogram"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Nieuws en tijdschriften"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps en navigatie"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productiviteit"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Toegankelijkheid"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Apparaatopslag"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-foutopsporing"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"uur"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index e3c3c09214c8..7d65cde300bd 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ଆପଣଙ୍କ ଫଟୋ ସଂଗ୍ରହ ପରିବର୍ତ୍ତନ କରିବାକୁ ଆପ୍‍ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ଆପଣଙ୍କ ମିଡିଆ ସଂଗ୍ରହ ଠାରୁ ଲୋକେସନ୍‍ଗୁଡିକୁ ପଢନ୍ତୁ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ଆପଣଙ୍କ ମିଡିଆ ସଂଗ୍ରହ ଠାରୁ ଅବସ୍ଥାନଗୁଡିକୁ ପଢିବାକୁ ଆପ୍‍ ଅନୁମତି ଦେଇଥାଏ।"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ବାୟୋମେଟ୍ରିକ୍ସ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ବାୟୋମେଟ୍ରିକ୍ସ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ଏହା ଆପଣ ବୋଲି ଯାଞ୍ଚ କରନ୍ତୁ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ବାୟୋମେଟ୍ରିକ୍ସ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ବାୟୋମେଟ୍ରିକ୍‌ ହାର୍ଡୱେର୍‌ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ପ୍ରାମାଣିକତାକୁ ବାତିଲ୍ କରାଯାଇଛି"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"ଚିହ୍ନଟ ହେଲାନାହିଁ"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ପ୍ରାମାଣିକତାକୁ ବାତିଲ୍ କରାଯାଇଛି"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"କୌଣସି ପିନ୍, ପେଟେର୍ନ ବା ପାସ୍‍ୱର୍ଡ ସେଟ୍ ନାହିଁ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"ପ୍ରାମାଣିକରଣ କରିବା ସମୟରେ ତ୍ରୁଟି"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଡିଭାଇସର କ୍ରେଡେନ୍ସିଆଲ୍ ଲେଖନ୍ତୁ"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ଆଂଶିକ ଟିପଚିହ୍ନ ଚିହ୍ନଟ ହେଲା। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ଟିପଚିହ୍ନ ପ୍ରୋସେସ୍‍ କରାଯାଇପାରିଲା ନାହିଁ। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"ଟିପଚିହ୍ନ ସେନ୍ସର୍‍ ମଇଳା ହୋଇଯାଇଛି। ଦୟାକରି ସଫା କରନ୍ତୁ ଓ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍‌ରେ ଟିପଚିହ୍ନ ସେନ୍‍ସର୍ ନାହିଁ।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ଟିପଚିହ୍ନ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"ଏହି ଡିଭାଇସ୍‌ରେ ଫେସ୍ ଅନ୍‌ଲକ୍ ସମର୍ଥିତ ନୁହେଁ।"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
<string name="face_name_template" msgid="3877037340223318119">"<xliff:g id="FACEID">%d</xliff:g>ଙ୍କ ଫେସ୍‍"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ଫେସ୍ ଅନଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ଫେସ୍ ବା ସ୍କ୍ରିନ୍ ଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ଜାରି ରଖିବାକୁ ଫେସ୍ ଅନଲକ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ଫେସ୍ ଆଇକନ୍"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ଖବର ଓ ମ୍ୟାଗାଜିନ୍‍"</string>
<string name="app_category_maps" msgid="6395725487922533156">"ମାନଚିତ୍ର ଓ ନେଭିଗେଶନ୍‍"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ଉତ୍ପାଦକତା"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"ଆକ୍ସେସିବିଲିଟୀ"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"ଡିଭାଇସ୍‌ ଷ୍ଟୋରେଜ୍‌"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB ଡିବଗିଂ"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ଘଣ୍ଟା"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 01bf27679dc2..4b183205b14c 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Zezwala aplikacji na modyfikowanie kolekcji zdjęć."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"odczytywanie lokalizacji z kolekcji multimediów"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Zezwala aplikacji na odczytywanie lokalizacji z kolekcji multimediów."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Używaj biometrii"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Używaj biometrii lub blokady ekranu"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Potwierdź swoją tożsamość"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Użyj biometrii, by kontynuować"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Sprzęt biometryczny niedostępny"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Anulowano uwierzytelnianie"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nie rozpoznano"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Anulowano uwierzytelnianie"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nie ustawiono kodu PIN, wzoru ani hasła"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Podczas uwierzytelniania wystąpił błąd"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Używaj blokady ekranu"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Podaj dane logowania do urządzenia, aby kontynuować"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Odcisk palca został odczytany tylko częściowo. Spróbuj ponownie."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nie udało się przetworzyć odcisku palca. Spróbuj ponownie."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Czytnik linii papilarnych jest zabrudzony. Wyczyść go i spróbuj ponownie."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"To urządzenie nie jest wyposażone w czytnik linii papilarnych."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Czujnik jest tymczasowo wyłączony."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Używaj odcisku palca"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Używaj odcisku palca lub blokady ekranu"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Użyj odcisku palca, by kontynuować"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"To urządzenie nie obsługuje rozpoznawania twarzy."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Czujnik jest tymczasowo wyłączony."</string>
<string name="face_name_template" msgid="3877037340223318119">"Twarz <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Używaj rozpoznawania twarzy"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Używaj rozpoznawania twarzy lub blokady ekranu"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Użyj rozpoznawania twarzy, aby kontynuować"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona twarzy"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Wiadomości i czasopisma"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapy i nawigacja"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktywność"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Ułatwienia dostępu"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Pamięć urządzenia"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Debugowanie USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"godz."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index aa693582f0fa..7d028f91b23f 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que o app modifique sua coleção de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler locais na sua coleção de mídias"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que o app leia os locais na sua coleção de mídias."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar biometria"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometria ou bloqueio de tela"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme que é você"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use seus dados biométricos para continuar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico indisponível"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticação cancelada"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Não reconhecido"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autenticação cancelada"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nenhum PIN, padrão ou senha configurado"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Erro na autenticação"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueio de tela"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Insira as credenciais do dispositivo para continuar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Impressão digital parcial detectada. Tente novamente."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"O sensor de impressão digital está sujo. Limpe-o e tente novamente."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use sua impressão digital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"O desbloqueio facial não é compatível com este dispositivo."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor desativado temporariamente."</string>
<string name="face_name_template" msgid="3877037340223318119">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueio facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar reconhecimento facial ou bloqueio de tela"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use o desbloqueio facial para continuar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ícone facial"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Notícias e revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas e navegação"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produtividade"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Acessibilidade"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Armazenamento do dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuração USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 232a17219eb4..a01db5e3fca6 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que a app modifique a sua coleção de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler as localizações a partir da sua coleção de multimédia"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que a app leia as localizações a partir da sua coleção de multimédia."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utilizar a biometria"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utilizar a biometria ou o bloqueio de ecrã"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme a sua identidade"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Utilize a biometria para continuar."</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico indisponível."</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticação cancelada"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Não reconhecido."</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autenticação cancelada"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nenhum PIN, padrão ou palavra-passe definidos."</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Erro ao autenticar."</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utilizar o bloqueio de ecrã"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Introduza a credencial do dispositivo para continuar."</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Impressão digital parcial detetada. Tente novamente."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"O sensor de impressões digitais está sujo. Limpe-o e tente novamente."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem sensor de impressões digitais."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporariamente desativado."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Utilizar a impressão digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Utilizar o bloqueio de ecrã ou a impressão digital"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilize a sua impressão digital para continuar."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Desbloqueio facial não suportado neste dispositivo."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor temporariamente desativado."</string>
<string name="face_name_template" msgid="3877037340223318119">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Utilizar o desbloqueio facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Utilizar o bloqueio através do rosto ou de ecrã"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Utilize o desbloqueio facial para continuar."</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ícone de rosto"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Notícias e revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas e navegação"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produtividade"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Acessibilidade"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Armazenamento do dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuração USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index aa693582f0fa..7d028f91b23f 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite que o app modifique sua coleção de fotos."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"ler locais na sua coleção de mídias"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que o app leia os locais na sua coleção de mídias."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Usar biometria"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Usar biometria ou bloqueio de tela"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirme que é você"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Use seus dados biométricos para continuar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biométrico indisponível"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autenticação cancelada"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Não reconhecido"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autenticação cancelada"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nenhum PIN, padrão ou senha configurado"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Erro na autenticação"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueio de tela"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Insira as credenciais do dispositivo para continuar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Impressão digital parcial detectada. Tente novamente."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"O sensor de impressão digital está sujo. Limpe-o e tente novamente."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usar impressão digital"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar impressão digital ou bloqueio de tela"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use sua impressão digital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"O desbloqueio facial não é compatível com este dispositivo."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensor desativado temporariamente."</string>
<string name="face_name_template" msgid="3877037340223318119">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Usar desbloqueio facial"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Usar reconhecimento facial ou bloqueio de tela"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Use o desbloqueio facial para continuar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ícone facial"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Notícias e revistas"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapas e navegação"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produtividade"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Acessibilidade"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Armazenamento do dispositivo"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Depuração USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hora"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 01daa557ca99..e8c553908c29 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Permite aplicației să vă modifice colecția de fotografii."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"citiți locațiile din colecția media"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite aplicației să citească locațiile din colecția dvs. media."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Folosiți sistemele biometrice"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Folosiți sistemele biometrice sau blocarea ecranului"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmați-vă identitatea"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Folosiți sistemele biometrice pentru a continua"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Hardware biometric indisponibil"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentificarea a fost anulată"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nu este recunoscut"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentificarea a fost anulată"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nu este setat niciun cod PIN, model sau parolă"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Eroare la autentificare"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Folosiți blocarea ecranului"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Introduceți datele de conectare ale dispozitivului pentru a continua"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"S-a detectat parțial amprenta. Încercați din nou."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Amprenta nu a putut fi procesată. Încercați din nou."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Senzorul pentru amprente este murdar. Curățați-l și încercați din nou."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzorul este dezactivat temporar."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Folosiți amprenta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Folosiți amprenta sau blocarea ecranului"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Folosiți amprenta pentru a continua"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Deblocarea facială nu este acceptată pe dispozitiv."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzorul este dezactivat temporar."</string>
<string name="face_name_template" msgid="3877037340223318119">"Chip <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Folosiți deblocarea facială"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Folosiți blocarea ecranului sau blocarea facială"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Folosiți deblocarea facială pentru a continua"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Pictograma chip"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Știri și reviste"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Hărți și navigare"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivitate"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Accesibilitate"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Stocare pe dispozitiv"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Remedierea erorilor prin USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"oră"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 1a513e462580..48f96ef3d289 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Приложение сможет вносить изменения в вашу фотоколлекцию."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"доступ к геоданным в медиаколлекции"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Приложение получит доступ к геоданным в вашей медиаколлекции."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Использовать биометрию"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Использовать биометрию или блокировку экрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Подтвердите, что это вы"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Чтобы продолжить, используйте биометрические данные"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрическое оборудование недоступно"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аутентификация отменена"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Не распознано"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Аутентификация отменена"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Укажите PIN-код, пароль или графический ключ"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Ошибка аутентификации."</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Использовать блокировку экрана"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Чтобы продолжить, введите учетные данные устройства"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Отсканирована только часть отпечатка. Повторите попытку."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не удалось распознать отпечаток. Повторите попытку."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Очистите сканер и повторите попытку."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сканер отпечатков пальцев временно отключен."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Использовать отпечаток пальца"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Использовать отпечаток пальца или блокировку экрана"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Чтобы продолжить, используйте цифровой отпечаток"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Это устройство не поддерживает функцию \"Фейсконтроль\"."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Датчик временно отключен."</string>
<string name="face_name_template" msgid="3877037340223318119">"Лицо <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Использовать фейсконтроль"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Использовать фейсконтроль или блокировку экрана"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Чтобы продолжить, используйте фейсконтроль"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Значок лица"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Новости и журналы"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карты и навигация"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Работа"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Доступность"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Хранилище устройства"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Отладка по USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ч."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 011b042f81b3..f645fe10f3bc 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Umožňuje aplikácii upravovať zbierku fotiek."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"čítať polohy zo zbierky médií"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Umožňuje aplikácii čítať polohy zo zbierky médií."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Použiť biometrické údaje"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Použiť biometrické údaje alebo zámku obrazovky"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Overenie, že ste to vy"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Ak chcete pokračovať, použite biometrický údaj"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrický hardvér nie je k dispozícii"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Overenie bolo zrušené"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nerozpoznané"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Overenie bolo zrušené"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nie je nastavený PIN, vzor ani heslo"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Chyba overenia"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Použiť zámku obrazovky"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Ak chcete pokračovať, zadajte prihlasovacie údaje zariadenia"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Podarilo sa rozpoznať iba časť odtlačku prsta. Skúste to znova."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Odtlačok prsta sa nepodarilo spracovať. Skúste to znova."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Očistite senzor odtlačkov prstov a skúste to znova."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zariadenie nemá senzor odtlačkov prstov."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasne vypnutý."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Použiť odtlačok prsta"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Použiť odtlačok prsta alebo zámku obrazovky"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Pokračujte nasnímaním odtlačku prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Toto zariadenie nepodporuje odomknutie tvárou."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je dočasne vypnutý."</string>
<string name="face_name_template" msgid="3877037340223318119">"Tvár <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Použiť odomknutie tvárou"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Použiť tvár alebo zámku obrazovky"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Ak chcete pokračovať, použite odomknutie tvárou"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona tváre"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Noviny a časopisy"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mapy a navigácia"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Kancelárske"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Dostupnosť"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Úložisko zariadenia"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Ladenie cez USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"hodina"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 0a7f7600abfc..97de6a370883 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Aplikaciji omogoča spreminjanje zbirke fotografij."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"branje lokacij v predstavnostni zbirki"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Aplikaciji omogoča branje lokacij v predstavnostni zbirki."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Uporaba biometrike"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Uporaba biometrike ali odklepanja s poverilnico"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Preverite, da ste res vi"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Za nadaljevanje uporabite biometrični podatek."</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Strojna oprema za biometrične podatke ni na voljo"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Preverjanje pristnosti je preklicano"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Ni prepoznano"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Preverjanje pristnosti je preklicano"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nastavljena ni nobena koda PIN, vzorec ali geslo"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Napaka pri preverjanju pristnosti"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Uporaba odklepanja s poverilnico"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Za nadaljevanje vnesite poverilnico za napravo."</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Zaznan delni prstni odtis. Poskusite znova."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Prstnega odtisa ni bilo mogoče obdelati. Poskusite znova."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Tipalo prstnih odtisov je umazano. Očistite ga in poskusite znova."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ta naprava nima tipala prstnih odtisov."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tipalo je začasno onemogočeno."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Uporaba prstnega odtisa"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Uporaba prstnega odtisa ali odklepanja s poverilnico"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Uporabite prstni odtis, če želite nadaljevati."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Ta naprava ne podpira odklepanja z obrazom."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Tipalo je začasno onemogočeno."</string>
<string name="face_name_template" msgid="3877037340223318119">"Obraz <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Uporaba odklepanja z obrazom"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Uporaba odklepanja z obrazom ali s poverilnico"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Za nadaljevanje uporabite odklepanje z obrazom."</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona obraza"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Novice in revije"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Zemljevidi in navigacija"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Storilnost"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Funkc. za ljudi s poseb. potreb."</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Shramba naprave"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Odpravljanje težav prek povezave USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ura"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index ddce26d68e59..a78ff777258e 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Lejon aplikacionin të modifikojë koleksionin tënd të fotografive."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lexo vendndodhjet nga koleksioni yt i medias"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Lejon aplikacionin të lexojë vendndodhjet nga koleksioni yt i medias."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Përdor sistemet biometrike"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Përdor sistemet biometrike ose kyçjen e ekranit"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifiko që je ti"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Përdor sistemet e tua biometrike për të vazhduar"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Nuk ofrohet harduer biometrik"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Vërtetimi u anulua"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Nuk njihet"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Vërtetimi u anulua"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Nuk është vendosur kod PIN, motiv ose fjalëkalim"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Gabim gjatë vërtetimit"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Përdor kyçjen e ekranit"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Fut kredencialet e pajisjes për të vazhduar"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"U zbulua një gjurmë gishti e pjesshme. Provo përsëri."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Gjurma e gishtit nuk mund të përpunohej. Provo përsëri."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Sensori i gjurmës së gishtit nuk është i pastër. Pastroje dhe provo përsëri."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensori është çaktivizuar përkohësisht."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Përdor gjurmën e gishtit"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Përdor gjurmën e gishtit ose kyçjen e ekranit"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Përdor gjurmën e gishtit për të vazhduar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Shkyçja me fytyrë nuk mbështetet në këtë pajisje"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensori është çaktivizuar përkohësisht."</string>
<string name="face_name_template" msgid="3877037340223318119">"Fytyra <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Përdor shkyçjen me fytyrë"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Përdor kyçjen me fytyrë ose kyçjen e ekranit"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Përdor shkyçjen me fytyrë për të vazhduar"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ikona e fytyrës"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Lajme dhe revista"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Harta dhe navigim"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitet"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Qasshmëria"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Hapësira ruajtëse e pajisjes"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Korrigjimi përmes USB-së"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"orë"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 11d5e7d8c43c..04bc35f5a2d1 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -553,23 +553,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Дозвољава апликацији да мења колекцију слика."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"читање локација из медијске колекције"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Дозвољава апликацији да чита локације из медијске колекције."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Користите биометрију"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користите биометрију или закључавање екрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Потврдите свој идентитет"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Користите биометријски податак да бисте наставили"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометријски хардвер није доступан"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Потврда идентитета је отказана"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Није препознато"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Потврда идентитета је отказана"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Нисте подесили ни PIN, ни шаблон, ни лозинку"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при потврди идентитета"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користите закључавање екрана"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Унесите акредитив за уређај да бисте наставили"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Откривен је делимични отисак прста. Пробајте поново."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Није успела обрада отиска прста. Пробајте поново."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Сензор за отиске прстију је прљав. Очистите га и покушајте поново."</string>
@@ -592,10 +587,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користите отисак прста"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користите отисак прста или закључавање екрана"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Наставите помоћу отиска прста"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -641,12 +634,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Откључавање лицем није подржано на овом уређају"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Сензор је привремено онемогућен."</string>
<string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Користите откључавање лицем"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Користите закључавање лицем или закључавање екрана"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Користите откључавање лицем да бисте наставили"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Икона лица"</string>
@@ -1998,8 +1988,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Новости и часописи"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Мапе и навигација"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Продуктивност"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Приступачност"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Меморијски простор уређаја"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Отклањање грешака са USB-а"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"сат"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4f6ccff5313f..5ab243a042e1 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Tillåter att appen gör ändringar i din fotosamling."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"läsa av platser i din mediesamling"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Tillåter att appen läser av platser i din mediesamling."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Använd biometri"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Använd biometrisk data eller skärmlåset"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifiera din identitet"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Fortsätt med hjälp av din biometriska data"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrisk maskinvara är inte tillgänglig"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentiseringen avbröts"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Identifierades inte"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentiseringen avbröts"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Pinkod, grafiskt lösenord eller lösenord har inte angetts"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Ett fel uppstod vid autentiseringen"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Använd skärmlåset"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Fortsätt genom att ange enhetens autentiseringsuppgifter"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Ofullständigt fingeravtryck. Försök igen."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Det gick inte att bearbeta fingeravtrycket. Försök igen."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Fingeravtryckssensorn är smutsig. Rengör den och försök igen."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Enheten har ingen fingeravtryckssensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensorn har tillfälligt inaktiverats."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Använd ditt fingeravtryck"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Använd ditt fingeravtryck eller skärmlåset"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Fortsätt med hjälp av ditt fingeravtryck"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Ansiktslås stöds inte på den här enheten."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensorn har tillfälligt inaktiverats."</string>
<string name="face_name_template" msgid="3877037340223318119">"Ansikte <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Använd ansiktslåset"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Använd ansiktslåset eller skärmlåset"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Fortsätt med hjälp av ansiktslåset"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Ansikte"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Nyheter och tidskrifter"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Kartor och navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Produktivitet"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Tillgänglighet"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Enhetens lagringsutrymme"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB-felsökning"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"timme"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 8dd721f8890a..00477d1b1f5f 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Inaruhusu programu kubadilisha mkusanyiko wa picha zako."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"kusoma maeneo kwenye mkusanyiko wa vipengee vyako"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Inaruhusu programu kusoma maeneo kwenye mkusanyiko wa vipengee vyako."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Tumia bayometriki"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Tumia bayometriki au mbinu ya kufunga skrini"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Thibitisha kuwa ni wewe"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Tumia bayometriki yako ili uendelee"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Maunzi ya bayometriki hayapatikani"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Imeghairi uthibitishaji"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Hayatambuliki"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Imeghairi uthibitishaji"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Hujaweka pin, mchoro au nenosiri"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Hitilafu imetokea wakati wa uthibitishaji"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Tumia mbinu ya kufunga skrini"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Weka kitambulisho cha kifaa chako ili uendelee."</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Kitambua alama kimetambua sehemu ya alama. Tafadhali jaribu tena."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Imeshindwa kuchakata alama ya kidole. Tafadhali jaribu tena."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Kitambua alama ya kidole ni kichafu. Tafadhali kisafishe na ujaribu tena."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kifaa hiki hakina kitambua alama ya kidole."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Kitambuzi kimezimwa kwa muda."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Kidole cha <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Tumia alama ya kidole"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Tumia alama ya kidole au mbinu ya kufunga skrini"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Tumia alama ya kidole chako ili uendelee"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Kufungua kwa uso hakutumiki kwenye kifaa hiki."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Kitambuzi kimezimwa kwa muda."</string>
<string name="face_name_template" msgid="3877037340223318119">"Uso wa <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Tumia kipengele cha kufungua kwa uso"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Tumia uso au mbinu ya kufunga skrini"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Tumia kipengele cha kufungua kwa uso ili uendelee"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Aikoni ya uso"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Habari na Magazeti"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Ramani na Maelekezo"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Uzalishaji"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Ufikivu"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Hifadhi ya kifaa"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Utatuzi wa USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"saa"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 3760c6dc73c5..6325c191eea3 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"உங்களின் படத் தொகுப்பை மாற்ற ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"மீடியா தொகுப்பிலிருந்து இடங்களை அறிதல்"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"உங்களின் மீடியா தொகுப்பிலிருந்து இடங்களை அறிந்துகொள்ள ஆப்ஸை அனுமதிக்கும்."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"பயோமெட்ரிக்ஸைப் பயன்படுத்து"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"பயோமெட்ரிக்ஸையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"நீங்கள்தான் என உறுதிசெய்க"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"தொடர உங்கள் பயோமெட்ரிக்கைப் பயன்படுத்துங்கள்"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"பயோமெட்ரிக் வன்பொருள் இல்லை"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"அங்கீகரிப்பு ரத்தானது"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"அடையாளங்காணபடவில்லை"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"அங்கீகரிப்பு ரத்தானது"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"பின்னோ, பேட்டர்னோ, கடவுச்சொல்லோ அமைக்கப்படவில்லை"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"அங்கீகரிப்பதில் பிழை"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"திரைப் பூட்டைப் பயன்படுத்து"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"தொடர, சாதன அனுமதிச் சான்றை உள்ளிடுங்கள்"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"கைரேகையை ஓரளவுதான் கண்டறிய முடிந்தது. மீண்டும் முயலவும்."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"கைரேகையைச் செயலாக்க முடியவில்லை. மீண்டும் முயலவும்."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"கைரேகை சென்சாரில் தூசி உள்ளது. சுத்தம் செய்து, முயலவும்."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"கைரேகையைப் பயன்படுத்து"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"கைரேகையையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"தொடர்வதற்கு கைரேகையைப் பயன்படுத்துங்கள்"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"இந்த சாதனத்தில் ’முகம் காட்டித் திறத்தல்’ ஆதரிக்கப்படவில்லை."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
<string name="face_name_template" msgid="3877037340223318119">"முகம் <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"முகம் காட்டித் திறத்தலை உபயோகி"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"முகத்தையோ திரைப் பூட்டையோ பயன்படுத்து"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"தொடர, \'முகம் காட்டித் திறத்தல்\' அம்சத்தை உபயோகியுங்கள்"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"முக ஐகான்"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"செய்திகளும் பத்திரிகைகளும்"</string>
<string name="app_category_maps" msgid="6395725487922533156">"வரைபடங்களும் வழிசெலுத்தலும்"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"உற்பத்தித்திறன்"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"அணுகல்தன்மை"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"சாதனச் சேமிப்பகம்"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB பிழைதிருத்தம்"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"மணி"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 63ee3a0374af..c2a5d42b6a25 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"మీ ఫోటో సేకరణను సవరించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"మీ మీడియా సేకరణ నుండి స్థానాలను చదవండి"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"మీ మీడియా సేకరణ నుండి స్థానాలను చదవడానికి యాప్‌ను అనుమతిస్తుంది."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"బయోమెట్రిక్స్‌ను ఉపయోగించండి"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"బయోమెట్రిక్స్‌ను లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ఇది మీరేనని వెరిఫై చేసుకోండి"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"కొనసాగించడానికి, మీ బయోమెట్రిక్‌ను ఉపయోగించండి"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"బయోమెట్రిక్ హార్డ్‌వేర్‌ అందుబాటులో లేదు"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ప్రమాణీకరణ రద్దు చేయబడింది"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"గుర్తించలేదు"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ప్రమాణీకరణ రద్దు చేయబడింది"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"పిన్, ఆకృతి లేదా పాస్‌వర్డ్‌ సెట్ చేయబడలేదు"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"ప్రామాణీకరిస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"కొనసాగడానికి, మీ పరికర ఆధారాలను ఎంటర్ చేయండి"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"పాక్షిక వేలిముద్ర గుర్తించబడింది. దయచేసి మళ్లీ ప్రయత్నించండి."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"వేలిముద్రను ప్రాసెస్ చేయడం సాధ్యపడలేదు. దయచేసి మళ్లీ ప్రయత్నించండి."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"వేలిముద్ర సెన్సార్ మురికిగా ఉంది. దయచేసి శుభ్రపరిచి, మళ్లీ ప్రయత్నించండి."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ ఎంపిక లేదు."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"వేలిముద్రను ఉపయోగించండి"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"వేలిముద్ర లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"కొనసాగించడానికి మీ వేలిముద్రను ఉపయోగించండి"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"ఈ పరికరంలో ముఖంతో అన్‌లాక్‌ను ఉపయోగించడానికి మద్దతు లేదు."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string>
<string name="face_name_template" msgid="3877037340223318119">"ముఖ <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ఫేస్ అన్‌లాక్‌ను ఉపయోగించండి"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ముఖం లేదా స్క్రీన్ లాక్‌ను ఉపయోగించండి"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"కొనసాగించడానికి, మీ ఫేస్ అన్‌లాక్‌ను ఉపయోగించండి"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ముఖ చిహ్నం"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"వార్తలు &amp; వార్తాపత్రికలు"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Maps &amp; నావిగేషన్"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ఉత్పాదకత"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"యాక్సెసిబిలిటీ"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"పరికర నిల్వ"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB డీబగ్గింగ్"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"గంట"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 3c985b999162..a5cfe4028a39 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"อนุญาตให้แอปแก้ไขคอลเล็กชันรูปภาพของคุณ"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"อ่านตำแหน่งจากคอลเล็กชันสื่อของคุณ"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"อนุญาตให้แอปอ่านตำแหน่งจากคอลเล็กชันสื่อของคุณ"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"ใช้ข้อมูลไบโอเมตริก"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"ใช้ข้อมูลไบโอเมตริกหรือการล็อกหน้าจอ"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"ยืนยันว่าเป็นตัวคุณ"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"ใช้ข้อมูลไบโอเมตริกเพื่อดำเนินการต่อ"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"ฮาร์ดแวร์ไบโอเมตริกไม่พร้อมใช้งาน"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"ยกเลิกการตรวจสอบสิทธิ์แล้ว"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"ไม่รู้จัก"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"ยกเลิกการตรวจสอบสิทธิ์แล้ว"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"ไม่ได้ตั้ง PIN, รูปแบบ หรือรหัสผ่าน"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"การตรวจสอบข้อผิดพลาด"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ใช้การล็อกหน้าจอ"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"ป้อนข้อมูลเข้าสู่ระบบอุปกรณ์เพื่อดำเนินการต่อ"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"ตรวจพบลายนิ้วมือเพียงบางส่วน โปรดลองอีกครั้ง"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ประมวลผลลายนิ้วมือไม่ได้ โปรดลองอีกครั้ง"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"เซ็นเซอร์ลายนิ้วมือไม่สะอาด โปรดทำความสะอาดและลองอีกครั้ง"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ใช้ลายนิ้วมือ"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ใช้ลายนิ้วมือหรือการล็อกหน้าจอ"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ใช้ลายนิ้วมือของคุณเพื่อดำเนินการต่อ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"อุปกรณ์นี้ไม่รองรับการปลดล็อกด้วยใบหน้า"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
<string name="face_name_template" msgid="3877037340223318119">"ใบหน้า <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"ใช้การปลดล็อกด้วยใบหน้า"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"ใช้การล็อกด้วยใบหน้าหรือการล็อกหน้าจอ"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"ใช้การปลดล็อกด้วยใบหน้าเพื่อดำเนินการต่อ"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ไอคอนใบหน้า"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"ข่าวสารและนิตยสาร"</string>
<string name="app_category_maps" msgid="6395725487922533156">"แผนที่และการนำทาง"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"ประสิทธิภาพการทำงาน"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"การช่วยเหลือพิเศษ"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"พื้นที่เก็บข้อมูลของอุปกรณ์"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"การแก้ไขข้อบกพร่อง USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ชั่วโมง"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 7402195a0de8..4829cefe1940 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Pinapayagan ang app na baguhin ang iyong koleksyon ng larawan."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"basahin ang mga lokasyon mula sa iyong koleksyon ng media"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Pinapayagan ang app na basahin ang mga lokasyon mula sa iyong koleksyon ng media."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Gumamit ng biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gumamit ng biometrics o lock ng screen"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"I-verify na ikaw ito"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Gamitin ang iyong biometric para magpatuloy"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Walang biometric hardware"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Nakansela ang pag-authenticate"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Hindi nakilala"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Nakansela ang pag-authenticate"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Walang itinakdang pin, pattern, o password"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Nagkaroon ng error sa pag-authenticate"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gumamit ng lock ng screen"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Ilagay ang kredensyal ng device para magpatuloy"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Hindi buo ang natukoy na fingerprint. Pakisubukan ulit."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Hindi maproseso ang fingerprint. Pakisubukan ulit."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Marumi ang sensor ng fingerprint. Pakilinis at subukang muli."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Walang sensor ng fingerprint ang device na ito."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Pansamantalang na-disable ang sensor."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Gumamit ng fingerprint"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Gumamit ng fingerprint o lock ng screen"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gamitin ang iyong fingerprint para magpatuloy"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Hindi sinusuportahan ang face unlock sa device na ito."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Pansamantalang na-disable ang sensor."</string>
<string name="face_name_template" msgid="3877037340223318119">"Mukha <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Gumamit ng face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Gumamit ng mukha o lock ng screen"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Gumamit ng face unlock para magpatuloy"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Face icon"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Balita at Mga Magazine"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Mga Mapa at Navigation"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Productivity"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Pagiging Accessible"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Storage ng device"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Pag-debug ng USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"oras"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 147553fbfa0a..186ffa7c8206 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Uygulamanın fotoğraf koleksiyonunuzu değiştirmesine izin verir."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"medya koleksiyonunuzdaki konumları okuma"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Uygulamanın medya koleksiyonunuzdaki konumları okumasına izin verir."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Biyometri kullan"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biyometri veya ekran kilidi kullan"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Siz olduğunuzu doğrulayın"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Devam etmek için biyometri kullanın"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biyometrik donanım kullanılamıyor"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Kimlik doğrulama iptal edildi"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Tanınmadı"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Kimlik doğrulama iptal edildi"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"PIN, desen veya şifre seti yok"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Kimlik doğrulama sırasında hata oluştu"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Ekran kilidi kullan"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Devam etmek için cihaz kimlik bilginizi girin"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Parmak izinin tümü algılanamadı. Lütfen tekrar deneyin."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Parmak izi işlenemedi. Lütfen tekrar deneyin."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Parmak izi sensörü kirli. Lütfen temizleyin ve tekrar deneyin."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda parmak izi sensörü yok."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensör geçici olarak devre dışı bırakıldı."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Parmak izi kullan"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Parmak izi veya ekran kilidi kullan"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Devam etmek için parmak izinizi kullanın"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Bu cihazda yüz tanıma kilidi desteklenmiyor"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Sensör geçici olarak devre dışı bırakıldı."</string>
<string name="face_name_template" msgid="3877037340223318119">"Yüz <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Yüz tanıma kilidi kullan"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Yüz tanıma veya ekran kilidi kullan"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Devam etmek için yüz tanıma kilidini kullanın"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Yüz simgesi"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Haberler ve Dergiler"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Haritalar ve Navigasyon"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Verimlilik"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Erişilebilirlik"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Cihazdaki depolama alanı"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB üzerinden hata ayıklama"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"saat"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 77e664afcbfe..7049a2e11110 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -556,23 +556,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Додаток зможе змінювати вашу колекцію фотографій."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"розпізнавати геодані з колекції медіа-вмісту"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Додаток зможе розпізнавати геодані з вашої колекції медіа-вмісту."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Використовувати біометрію"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Використовувати біометрію або блокування екрана"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Підтвердьте, що це ви"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Щоб продовжити, скористайтеся біометрією"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Біометричне апаратне забезпечення недоступне"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Автентифікацію скасовано"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Не розпізнано"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Автентифікацію скасовано"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Не вказано PIN-код, ключ або пароль"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Помилка автентифікації"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Використовувати блокування екрана"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Щоб продовжити, введіть облікові дані пристрою"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Відбиток пальця розпізнано частково. Повторіть спробу."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не вдалось обробити відбиток пальця. Повторіть спробу."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Датчик відбитків пальців забруднився. Очистьте його та повторіть спробу."</string>
@@ -595,10 +590,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Використовувати відбиток пальця"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Використовувати відбиток пальця або блокування екрана"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Щоб продовжити, скористайтеся своїм відбитком пальця"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -644,12 +637,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"На цьому пристрої не підтримується Фейсконтроль."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Датчик тимчасово вимкнено."</string>
<string name="face_name_template" msgid="3877037340223318119">"Обличчя <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Використовувати фейсконтроль"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Використовувати фейсконтроль або блокування екрана"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Щоб продовжити, скористайтеся фейсконтролем"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Значок обличчя"</string>
@@ -2030,8 +2020,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Новини та журнали"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Карти й навігація"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Продуктивність"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Спеціальні можливості"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Пам’ять пристрою"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Налагодження USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"години"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 10f787b70fd1..615e2fa4a831 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"ایپ کو آپ کی تصویر کے مجموعے میں ترمیم کی اجازت دیتا ہے۔"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"اپنی میڈيا کے مجموعے سے مقامات پڑھیں"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"ایپ کو آپ کی میڈيا کے مجموعے سے مقامات پڑھنے کی اجازت دیتا ہے۔"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"بایو میٹرکس استعمال کریں"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"بایو میٹرکس یا اسکرین لاک استعمال کریں"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"توثیق کریں کہ یہ آپ ہیں"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"جاری رکھنے کیلئے اپنا بایو میٹرک استعمال کریں"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"بایومیٹرک ہارڈ ویئر دستیاب نہیں ہے"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"تصدیق کا عمل منسوخ ہو گیا"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"تسلیم شدہ نہیں ہے"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"تصدیق کا عمل منسوخ ہو گیا"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"کوئی پن، پیٹرن، یا پاس ورڈ سیٹ نہیں ہے"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"خرابی کی توثیق ہو رہی ہے"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"اسکرین لاک استعمال کریں"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"جاری رکھنے کیلئے اپنے آلے کی سند درج کریں"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"جزوی فنگر پرنٹ کی شناخت ہوئی۔ براہ کرم دوبارہ کوشش کریں۔"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"فنگر پرنٹ پر کارروائی نہیں کی جا سکی۔ براہ کرم دوبارہ کوشش کریں۔"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"فنگر پرنٹ سینسر گندا ہے۔ براہ کرم صاف کریں اور دوبارہ کوشش کریں۔"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"فنگر پرنٹ استعمال کریں"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"فنگر پرنٹ یا اسکرین لاک استعمال کریں"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"جاری رکھنے کیلئے اپنا فنگر پرنٹ استعمال کریں"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"اس آلہ پر چہرے کے ذریعے غیر مقفل کرنا تعاون یافتہ نہیں ہے۔"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"سینسر عارضی طور غیر فعال ہے۔"</string>
<string name="face_name_template" msgid="3877037340223318119">"چہرہ <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"چہرے کے ذریعے غیر مقفل کرنا استعمال کریں"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"چہرہ یا اسکرین لاک استعمال کریں"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"جاری رکھنے کیلئے چہرے کے ذریعے غیر مقفل کرنا استعمال کریں"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"چہرے کا آئیکن"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"خبریں اور میگزین"</string>
<string name="app_category_maps" msgid="6395725487922533156">"نقشے اور نیویگیشن"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"پروڈکٹیوٹی"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"ایکسیسبیلٹی"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"آلہ کی اسٹوریج"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"‏USB ڈیبگ کرنا"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"گھنٹہ"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index f2c5589f392b..0bcba068ffa3 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -553,7 +553,7 @@
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Biometrik tasdiqlash"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Biometrika yoki ekran qulfi"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Oʻzingizni taniting"</string>
- <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Davob etish uchun biometrik tasdiqlang"</string>
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Davom etish uchun biometrik tasdiqlang"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrik sensor ishlamayapti"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentifikatsiya bekor qilindi"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Aniqlanmadi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4d7091c68696..11644d6dba9a 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Cho phép ứng dụng này sửa đổi bộ sưu tập ảnh của bạn."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"đọc vị trí từ bộ sưu tập phương tiện"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Cho phép ứng dụng này đọc vị trí từ bộ sưu tập phương tiện của bạn."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Dùng dữ liệu sinh trắc học"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Dùng dữ liệu sinh trắc học hoặc phương thức khóa màn hình"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Xác minh danh tính của bạn"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Dùng dữ liệu sinh trắc học của bạn để tiếp tục"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Không có phần cứng sinh trắc học"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Đã hủy xác thực"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Không nhận dạng được"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Đã hủy xác thực"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Chưa đặt mã PIN, hình mở khóa hoặc mật khẩu"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Lỗi khi xác thực"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Dùng phương thức khóa màn hình"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Nhập thông tin xác thực thiết bị của bạn để tiếp tục"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Đã phát hiện được một phần vân tay. Vui lòng thử lại."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Không thể xử lý vân tay. Vui lòng thử lại."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Cảm biến vân tay bị bẩn. Hãy làm sạch và thử lại."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Thiết bị này không có cảm biến vân tay."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Đã tạm thời tắt cảm biến."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Dùng vân tay"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Dùng vân tay hoặc phương thức khóa màn hình"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Sử dụng dấu vân tay của bạn để tiếp tục"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"Thiết bị này không hỗ trợ tính năng mở khóa bằng khuôn mặt."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Đã tạm thời tắt cảm biến."</string>
<string name="face_name_template" msgid="3877037340223318119">"Khuôn mặt <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Dùng tính năng mở khóa bằng khuôn mặt"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Dùng khuôn mặt hoặc phương thức khóa màn hình"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Dùng tính năng mở khóa bằng khuôn mặt để tiếp tục"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Biểu tượng khuôn mặt"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Tin tức và tạp chí"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Bản đồ và dẫn đường"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Sản xuất"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Hỗ trợ tiếp cận"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Bộ nhớ của thiết bị"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Gỡ lỗi qua USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"giờ"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1f8f1766b376..ec455bc07ab0 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"允许该应用修改您的照片收藏。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"从您的媒体收藏中读取位置信息"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"允许该应用从您的媒体收藏中读取位置信息。"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"使用生物识别"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物识别或屏幕锁定凭据"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"验证是您本人在操作"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"使用生物识别验证身份才能继续"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"生物识别硬件无法使用"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"身份验证已取消"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"无法识别"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"身份验证已取消"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未设置任何 PIN 码、图案和密码"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"进行身份验证时出错"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用屏幕锁定凭据"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"输入您的设备凭据才能继续"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"仅检测到部分指纹,请重试。"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"无法处理指纹,请重试。"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"指纹传感器有脏污。请擦拭干净,然后重试。"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指纹"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指纹或屏幕锁定凭据"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"使用指纹完成验证才能继续"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"此设备不支持人脸解锁。"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"传感器已暂时停用。"</string>
<string name="face_name_template" msgid="3877037340223318119">"面孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"使用人脸解锁"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"使用人脸解锁或屏幕锁定凭据"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"使用人脸解锁验证身份才能继续"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"面孔图标"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"新闻和杂志"</string>
<string name="app_category_maps" msgid="6395725487922533156">"地图和导航"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"办公"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"无障碍"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"设备存储空间"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB 调试"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"点"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index ebc02c502b8a..16b9b0fe31e4 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"允許應用程式修改您的相片集。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"讀取媒體集的位置"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"允許應用程式讀取媒體集的位置。"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"使用生物識別"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物識別或螢幕鎖定"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"驗證是你本人"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"如要繼續操作,請使用使用生物識別驗證身分"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"無法使用生物識別硬件"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"已取消驗證"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"未能識別"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"已取消驗證"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未設定 PIN、圖案或密碼"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"驗證時發生錯誤"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"如要繼續操作,請輸入裝置憑證"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"只偵測到部分指紋。請再試一次。"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"無法處理指紋。請再試一次。"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"指紋感應器不乾淨。請清潔後再試一次。"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋鎖定"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"請使用您的指紋繼續"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"此裝置不支援「臉孔解鎖」。"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"感應器已暫時停用。"</string>
<string name="face_name_template" msgid="3877037340223318119">"臉孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"使用臉孔解鎖"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"使用臉孔或螢幕鎖定"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"如要繼續操作,請使用臉孔解鎖驗證身分"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"臉孔圖示"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"新聞和雜誌"</string>
<string name="app_category_maps" msgid="6395725487922533156">"地圖和導航"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"生產力應用程式"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"無障礙功能"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"裝置儲存空間"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB 偵錯"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"時"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 10d05c1fa14d..90fe15d144c4 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"允許應用程式修改你的相片收藏。"</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"讀取你的媒體收藏的位置資訊"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"允許應用程式讀取你的媒體收藏的位置資訊。"</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"使用生物特徵辨識功能"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"使用生物特徵辨識或螢幕鎖定功能"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"驗證你的身分"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"如要繼續操作,請使用生物特徵辨識功能驗證身分"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"無法使用生物特徵辨識硬體"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"已取消驗證"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"無法辨識"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"已取消驗證"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"未設定 PIN 碼、解鎖圖案或密碼"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"驗證時發生錯誤"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"使用螢幕鎖定功能"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"如要繼續操作,請輸入裝置憑證"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"僅偵測到部分指紋,請再試一次。"</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"無法處理指紋,請再試一次。"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"指紋感應器有髒汙。請清潔感應器,然後再試一次。"</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"使用指紋"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"使用指紋或螢幕鎖定功能"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"使用指紋完成驗證才能繼續操作"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"這個裝置不支援人臉解鎖功能。"</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"感應器已暫時停用。"</string>
<string name="face_name_template" msgid="3877037340223318119">"臉孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"使用人臉解鎖功能"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"使用人臉解鎖或螢幕鎖定功能"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"如要繼續操作,請使用人臉解鎖功能驗證身分"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"臉孔圖示"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"新聞和雜誌"</string>
<string name="app_category_maps" msgid="6395725487922533156">"地圖和導航"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"工作效率"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"無障礙工具"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"裝置儲存空間"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB 偵錯"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"點"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 976b97a2b8ed..1089f1e4b1c5 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -550,23 +550,18 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Ivumela uhlelo lwakho lokusebenza ukuthi lilungise iqoqo lakho lesithombe."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"funda izindawo kusukela kuqoqo lakho lemidiya"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Ivumela uhlelo lokusebenza ukuthi lifunde izindawo kusukela kuqoqo lakho lemidiya."</string>
- <!-- no translation found for biometric_app_setting_name (3339209978734534457) -->
- <skip />
- <!-- no translation found for biometric_or_screen_lock_app_setting_name (5348462421758257752) -->
- <skip />
+ <string name="biometric_app_setting_name" msgid="3339209978734534457">"Sebenzisa i-biometrics"</string>
+ <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Sebenzisa i-biometrics noma ukukhiya isikrini"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Qinisekisa ukuthi nguwe"</string>
- <!-- no translation found for biometric_dialog_default_subtitle (8457232339298571992) -->
- <skip />
+ <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Sebenzisa i-biometric yakho ukuze uqhubeke"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"I-Biometric hardware ayitholakali"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Ukufakazela ubuqiniso kukhanseliwe"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Akwaziwa"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Ukufakazela ubuqiniso kukhanseliwe"</string>
<string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Ayikho iphinikhodi, iphethini, noma iphasiwedi esethiwe"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Iphutha lokufakazela ubuqiniso"</string>
- <!-- no translation found for screen_lock_app_setting_name (6054944352976789228) -->
- <skip />
- <!-- no translation found for screen_lock_dialog_default_subtitle (8638638125397857315) -->
- <skip />
+ <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Sebenzisa isikhiya sesikrini"</string>
+ <string name="screen_lock_dialog_default_subtitle" msgid="8638638125397857315">"Faka izifakazelo zedivayisi yakho ukuze uqhubeke"</string>
<string name="fingerprint_acquired_partial" msgid="8532380671091299342">"Izigxivizo zeminwe ezincane zitholiwe. Sicela uzame futhi."</string>
<string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ayikwazanga ukucubungula izigxivizo zeminwe. Sicela uzame futhi."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="4694800187151533990">"Inzwa yezigxivizo zeminwe ingcolile. Sicela uyihlanze uphinde uzame futhi."</string>
@@ -589,10 +584,8 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Le divayisi ayinayo inzwa yezigxivizo zeminwe."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Inzwa ikhutshazwe okwesikhashana."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string>
- <!-- no translation found for fingerprint_app_setting_name (4253767877095495844) -->
- <skip />
- <!-- no translation found for fingerprint_or_screen_lock_app_setting_name (3501743523487644907) -->
- <skip />
+ <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Sebenzisa izigxivizo zeminwe"</string>
+ <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Sebenzisa izigxivizo zeminwe noma ukukhiya isikrini"</string>
<string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Sebenzisa izigxivizo zakho zeminwe ukuze uqhubeke"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -638,12 +631,9 @@
<string name="face_error_hw_not_present" msgid="1070600921591729944">"I-face unlock ayisekelwe kule divayisi."</string>
<string name="face_error_security_update_required" msgid="5076017208528750161">"Inzwa ikhutshazwe okwesikhashana."</string>
<string name="face_name_template" msgid="3877037340223318119">"Ubuso be-<xliff:g id="FACEID">%d</xliff:g>"</string>
- <!-- no translation found for face_app_setting_name (8130135875458467243) -->
- <skip />
- <!-- no translation found for face_or_screen_lock_app_setting_name (1603149075605709106) -->
- <skip />
- <!-- no translation found for face_dialog_default_subtitle (4979205739418564856) -->
- <skip />
+ <string name="face_app_setting_name" msgid="8130135875458467243">"Sebenzisa i-face unlock"</string>
+ <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Sebenzisa i-face lock noma ukukhiya isikrini"</string>
+ <string name="face_dialog_default_subtitle" msgid="4979205739418564856">"Sebenzisa i-face unlock ukuze uqhubeke"</string>
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"Isithonjana sobuso"</string>
@@ -1966,8 +1956,7 @@
<string name="app_category_news" msgid="1172762719574964544">"Izindaba nomagazini"</string>
<string name="app_category_maps" msgid="6395725487922533156">"Amamephu nokuzula"</string>
<string name="app_category_productivity" msgid="1844422703029557883">"Ukukhiqiza"</string>
- <!-- no translation found for app_category_accessibility (6643521607848547683) -->
- <skip />
+ <string name="app_category_accessibility" msgid="6643521607848547683">"Ukufinyeleleka"</string>
<string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Isitoreji sedivayisi"</string>
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Ukulungisa iphutha le-USB"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ihora"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 05d29c2685f4..7c446a90b06f 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3564,6 +3564,16 @@
<attr name="__removed2" format="boolean" />
<!-- Specifies whether the IME supports showing inline suggestions. -->
<attr name="supportsInlineSuggestions" format="boolean" />
+ <!-- Specify one or more configuration changes that the IME will handle itself. If not
+ specified, the IME will be restarted if any of these configuration changes happen in
+ the system. Otherwise, the IME will remain running and its
+ {@link android.inputmethodservice.InputMethodService#onConfigurationChanged}
+ method is called with the new configuration.
+ <p>Note that all of these configuration changes can impact the
+ resource values seen by the application, so you will generally need
+ to re-retrieve all resources (including view layouts, drawables, etc)
+ to correctly handle any configuration change.-->
+ <attr name="configChanges" />
</declare-styleable>
<!-- This is the subtype of InputMethod. Subtype can describe locales (for example, en_US and
@@ -3853,6 +3863,15 @@
<!-- Attribute whether the accessibility service wants to be able to take screenshot. -->
<attr name="canTakeScreenshot" format="boolean" />
+ <!-- Attribute indicating whether the accessibility service is used to assist users with
+ disabilities. This criteria might be defined by the installer. The default is false.
+ <p>
+ Note: If this flag is false, system will show a notification after a duration to
+ inform the user about the privacy implications of the service.
+ </p>
+ -->
+ <attr name="isAccessibilityTool" format="boolean" />
+
<!-- Animated image of the accessibility service purpose or behavior, to help users
understand how the service can help them.-->
<attr name="animatedImageDrawable" format="reference"/>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8bc3a52fa17b..397c6467f020 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1961,6 +1961,8 @@
<string name="config_systemWifiCoexManager" translateable="false"></string>
<!-- The name of the package that will hold the wellbeing role. -->
<string name="config_systemWellbeing" translatable="false"></string>
+ <!-- The name of the package that will hold the television notification handler role -->
+ <string name="config_systemTelevisionNotificationHandler" translatable="false"></string>
<!-- The name of the package that will be allowed to change its components' label/icon. -->
<string name="config_overrideComponentUiPackage" translatable="false"></string>
@@ -2270,6 +2272,9 @@
<bool name="config_dozeWakeLockScreenSensorAvailable">false</bool>
<integer name="config_dozeWakeLockScreenDebounce">300</integer>
+ <!-- Type of the quick pickup sensor. Empty if quick pickup is not supported. -->
+ <string name="config_quickPickupSensorType" translatable="false"></string>
+
<!-- Control whether the always on display mode is available. This should only be enabled on
devices where the display has been tuned to be power efficient in DOZE and/or DOZE_SUSPEND
states. -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 10aa7b3f4354..43dbd38d1dc4 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -746,7 +746,7 @@
<dimen name="notification_right_icon_headerless_margin">20dp</dimen>
<!-- The top margin of the right icon in the "big" notification states -->
<!-- TODO(b/181048615): Move the large icon below the expander in big states -->
- <dimen name="notification_right_icon_big_margin_top">20dp</dimen>
+ <dimen name="notification_right_icon_big_margin_top">16dp</dimen>
<!-- The size of the left icon -->
<dimen name="notification_left_icon_size">@dimen/notification_icon_circle_size</dimen>
<!-- The left padding of the left icon -->
diff --git a/core/res/res/values/policy_exempt_apps.xml b/core/res/res/values/policy_exempt_apps.xml
new file mode 100644
index 000000000000..1cead8322e55
--- /dev/null
+++ b/core/res/res/values/policy_exempt_apps.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<resources>
+ <!--
+ A collection of apps that are critical for the device and hence will never be disabled by
+ device policies or APIs.
+ -->
+ <string-array translatable="false" name="policy_exempt_apps">
+ </string-array>
+</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index b5d1e0ceec02..e0a728c233b2 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3071,7 +3071,6 @@
<public name="windowSplashScreenAnimationDuration"/>
<public name="windowSplashScreenBrandingImage"/>
<public name="splashScreenTheme" />
- <public name="rippleStyle" />
<public name="maxResizeWidth" />
<public name="maxResizeHeight" />
<public name="targetCellWidth" />
@@ -3087,6 +3086,7 @@
<public name="dataExtractionRules"/>
<public name="passwordsActivity"/>
<public name="selectableAsDefault"/>
+ <public name="isAccessibilityTool"/>
</public-group>
<public-group type="drawable" first-id="0x010800b5">
@@ -3174,6 +3174,8 @@
<public name="config_systemWifiCoexManager" />
<!-- @hide @SystemApi -->
<public name="config_systemWellbeing" />
+ <!-- @hide @SystemApi -->
+ <public name="config_systemTelevisionNotificationHandler" />
</public-group>
<public-group type="id" first-id="0x01020055">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2b1168f14f21..4af561b947cd 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1532,6 +1532,8 @@
<string name="biometric_dialog_default_title">Verify it\u2019s you</string>
<!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with a biometric (e.g. fingerprint or face). [CHAR LIMIT=70] -->
<string name="biometric_dialog_default_subtitle">Use your biometric to continue</string>
+ <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with a biometric (e.g. fingerprint or face) or their screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=90] -->
+ <string name="biometric_or_screen_lock_dialog_default_subtitle">Use your biometric or screen lock to continue</string>
<!-- Message shown when biometric hardware is not available [CHAR LIMIT=50] -->
<string name="biometric_error_hw_unavailable">Biometric hardware unavailable</string>
@@ -1604,6 +1606,8 @@
<string name="fingerprint_or_screen_lock_app_setting_name">Use fingerprint or screen lock</string>
<!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their fingerprint. [CHAR LIMIT=70] -->
<string name="fingerprint_dialog_default_subtitle">Use your fingerprint to continue</string>
+ <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their fingerprint or screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=90] -->
+ <string name="fingerprint_or_screen_lock_dialog_default_subtitle">Use your fingerprint or screen lock to continue</string>
<!-- Array containing custom error messages from vendor. Vendor is expected to add and translate these strings -->
<string-array name="fingerprint_error_vendor">
@@ -1704,6 +1708,8 @@
<string name="face_or_screen_lock_app_setting_name">Use face or screen lock</string>
<!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their face. [CHAR LIMIT=70] -->
<string name="face_dialog_default_subtitle">Use face unlock to continue</string>
+ <!-- Subtitle shown on the system-provided biometric dialog, asking the user to authenticate with their face or screen lock credential (i.e. PIN, pattern, or password). [CHAR LIMIT=90] -->
+ <string name="face_or_screen_lock_dialog_default_subtitle">Use your face or screen lock to continue</string>
<!-- Array containing custom error messages from vendor. Vendor is expected to add and translate these strings -->
<string-array name="face_error_vendor">
@@ -2778,6 +2784,12 @@
<!-- Displayed to the user to confirm that they have copied text/images to the clipboard [CHAR LIMIT=NONE] -->
<string name="copied">Copied</string>
+ <!-- Displayed to the user to inform them that an app has accessed clipboard data (pasted as in "copy and paste") that was copied from another app [CHAR LIMIT=50] -->
+ <string name="pasted_from_app"><xliff:g id="pasting_app_name" example="Gmail">%1$s</xliff:g> pasted from <xliff:g id="source_app_name" example="Chrome">%2$s</xliff:g></string>
+
+ <!-- Displayed to the user to inform them that an app has accessed clipboard data (pasted as in "copy and paste") [CHAR LIMIT=50] -->
+ <string name="pasted_from_clipboard"><xliff:g id="pasting_app_name" example="Gmail">%1$s</xliff:g> pasted from clipboard</string>
+
<!-- Menu item displayed at the end of a menu to allow users to see another page worth of menu items. This is shown on any app's menu as long as the app has too many items in the menu.-->
<string name="more_item_label">More</string>
<!-- Prepended to the shortcut for a menu item to indicate that the user should hold the MENU button together with the shortcut to invoke the item. For example, if the shortcut to open a new tab in browser is MENU and B together, then this would be prepended to the letter "B" -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 00cc81639608..5f4063b0d30b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -558,6 +558,8 @@
<java-symbol type="string" name="prepend_shortcut_label" />
<java-symbol type="string" name="private_dns_broken_detailed" />
<java-symbol type="string" name="paste_as_plain_text" />
+ <java-symbol type="string" name="pasted_from_app" />
+ <java-symbol type="string" name="pasted_from_clipboard" />
<java-symbol type="string" name="replace" />
<java-symbol type="string" name="undo" />
<java-symbol type="string" name="redo" />
@@ -1264,6 +1266,8 @@
<java-symbol type="array" name="vendor_disallowed_apps_managed_device" />
<java-symbol type="array" name="cross_profile_apps" />
<java-symbol type="array" name="vendor_cross_profile_apps" />
+ <java-symbol type="array" name="policy_exempt_apps" />
+ <java-symbol type="array" name="vendor_policy_exempt_apps" />
<java-symbol type="drawable" name="default_wallpaper" />
<java-symbol type="drawable" name="default_lock_wallpaper" />
@@ -2471,6 +2475,7 @@
<java-symbol type="string" name="biometric_or_screen_lock_app_setting_name" />
<java-symbol type="string" name="biometric_dialog_default_title" />
<java-symbol type="string" name="biometric_dialog_default_subtitle" />
+ <java-symbol type="string" name="biometric_or_screen_lock_dialog_default_subtitle" />
<java-symbol type="string" name="biometric_error_hw_unavailable" />
<java-symbol type="string" name="biometric_error_user_canceled" />
<java-symbol type="string" name="biometric_not_recognized" />
@@ -2502,6 +2507,7 @@
<java-symbol type="string" name="fingerprint_app_setting_name" />
<java-symbol type="string" name="fingerprint_or_screen_lock_app_setting_name" />
<java-symbol type="string" name="fingerprint_dialog_default_subtitle" />
+ <java-symbol type="string" name="fingerprint_or_screen_lock_dialog_default_subtitle" />
<java-symbol type="string" name="fingerprint_authenticated" />
<java-symbol type="string" name="fingerprint_error_no_fingerprints" />
<java-symbol type="string" name="fingerprint_error_hw_not_present" />
@@ -2551,6 +2557,7 @@
<java-symbol type="string" name="face_app_setting_name" />
<java-symbol type="string" name="face_or_screen_lock_app_setting_name" />
<java-symbol type="string" name="face_dialog_default_subtitle" />
+ <java-symbol type="string" name="face_or_screen_lock_dialog_default_subtitle" />
<java-symbol type="string" name="face_authenticated_no_confirmation_required" />
<java-symbol type="string" name="face_authenticated_confirmation_required" />
<java-symbol type="string" name="face_error_security_update_required" />
@@ -3590,6 +3597,7 @@
<java-symbol type="string" name="config_dozeUdfpsLongPressSensorType" />
<java-symbol type="bool" name="config_dozeWakeLockScreenSensorAvailable" />
<java-symbol type="integer" name="config_dozeWakeLockScreenDebounce" />
+ <java-symbol type="string" name="config_quickPickupSensorType" />
<java-symbol type="array" name="config_allowedGlobalInstantAppSettings" />
<java-symbol type="array" name="config_allowedSystemInstantAppSettings" />
diff --git a/core/res/res/values/vendor_policy_exempt_apps.xml b/core/res/res/values/vendor_policy_exempt_apps.xml
new file mode 100644
index 000000000000..eb4c760b6724
--- /dev/null
+++ b/core/res/res/values/vendor_policy_exempt_apps.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<resources>
+ <!--
+ A collection of apps that are critical for the device and hence will never be disabled by
+ device policies or APIs.
+ -->
+ <string-array translatable="false" name="vendor_policy_exempt_apps">
+ </string-array>
+</resources>
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 57c0be5007b8..5d75d9b3f70b 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -2923,7 +2923,7 @@ public class PackageManagerTests extends AndroidTestCase {
assertFalse("BaseCodePath should not be registered", callback.mSuccess);
}
- // Verify thatmodules which are not own by the calling package are not registered.
+ // Verify that modules which are not own by the calling package are not registered.
public void testRegisterDexModuleNotOwningModule() throws Exception {
TestDexModuleRegisterCallback callback = new TestDexModuleRegisterCallback();
String moduleBelongingToOtherPackage = "/data/user/0/com.google.android.gms/module.apk";
@@ -2978,6 +2978,13 @@ public class PackageManagerTests extends AndroidTestCase {
assertFalse("DexModule registration should fail", callback.mSuccess);
}
+ // If the module does not exist on disk we should get a failure.
+ public void testRegisterDexModuleNotExistsNoCallback() throws Exception {
+ ApplicationInfo info = getContext().getApplicationInfo();
+ String nonExistentApk = Paths.get(info.dataDir, "non-existent.apk").toString();
+ getPm().registerDexModule(nonExistentApk, null);
+ }
+
// Copied from com.android.server.pm.InstructionSets because we don't have access to it here.
private static String[] getAppDexInstructionSets(ApplicationInfo info) {
if (info.primaryCpuAbi != null) {
diff --git a/core/tests/coretests/src/android/inputmethodservice/InputMethodServiceTest.java b/core/tests/coretests/src/android/inputmethodservice/InputMethodServiceTest.java
new file mode 100644
index 000000000000..4863cfe588ba
--- /dev/null
+++ b/core/tests/coretests/src/android/inputmethodservice/InputMethodServiceTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.inputmethodservice;
+
+import static android.content.res.Configuration.KEYBOARD_12KEY;
+import static android.content.res.Configuration.NAVIGATION_NONAV;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+
+import static junit.framework.Assert.assertFalse;
+
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.rule.ServiceTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.TimeoutException;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class InputMethodServiceTest {
+ private InputMethodService mService;
+ private Context mContext;
+ @Rule
+ public final ServiceTestRule serviceRule = new ServiceTestRule();
+
+ @Before
+ public void setUp() throws TimeoutException {
+ mContext = getInstrumentation().getContext();
+ mService = new InputMethodService();
+ }
+
+ @Test
+ public void testShouldImeRestartForConfig() throws Exception {
+ // Make sure we preserve Pre-S behavior i.e. Service restarts.
+ mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.R;
+ Configuration config = mContext.getResources().getConfiguration();
+ mService.setLastKnownConfig(config);
+ assertTrue("IME should restart for Pre-S",
+ mService.shouldImeRestartForConfig(config));
+
+ // IME shouldn't restart on targetSdk S+ (with no config changes).
+ mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.S;
+ assertFalse("IME shouldn't restart for S+",
+ mService.shouldImeRestartForConfig(config));
+
+ // Screen density changed but IME doesn't handle congfigChanges
+ config.densityDpi = 99;
+ assertTrue("IME should restart for unhandled configChanges",
+ mService.shouldImeRestartForConfig(config));
+
+ // opt-in IME to handle config changes.
+ mService.setHandledConfigChanges(ActivityInfo.CONFIG_DENSITY);
+ assertFalse("IME shouldn't restart for S+ since it handles configChanges",
+ mService.shouldImeRestartForConfig(config));
+ }
+}
diff --git a/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java b/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java
index 1e0e1235161c..f5fcb03bb816 100644
--- a/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java
@@ -125,7 +125,7 @@ public class InputMethodSubtypeTest {
assertEquals("he", clonedSubtypeHe.getLocale());
}
- private static final InputMethodSubtype cloneViaParcel(final InputMethodSubtype original) {
+ private static InputMethodSubtype cloneViaParcel(final InputMethodSubtype original) {
Parcel parcel = null;
try {
parcel = Parcel.obtain();
@@ -157,4 +157,4 @@ public class InputMethodSubtypeTest {
.setIsAsciiCapable(true)
.build();
}
-} \ No newline at end of file
+}
diff --git a/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java b/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java
index 453ad72b64dc..f264cc630dc5 100644
--- a/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java
@@ -62,20 +62,20 @@ public class SparseRectFArrayTest {
@Test
public void testBuilder() throws Exception {
- final RectF TEMP_RECT = new RectF(10.0f, 20.0f, 30.0f, 40.0f);
- final int TEMP_FLAGS = 0x1234;
+ final RectF testRect = new RectF(10.0f, 20.0f, 30.0f, 40.0f);
+ final int testFlags = 0x1234;
final SparseRectFArrayBuilder builder = new SparseRectFArrayBuilder();
- builder.append(100, TEMP_RECT.left, TEMP_RECT.top, TEMP_RECT.right, TEMP_RECT.bottom,
- TEMP_FLAGS);
+ builder.append(100, testRect.left, testRect.top, testRect.right, testRect.bottom,
+ testFlags);
assertNull(builder.build().get(-1));
assertNull(builder.build().get(0));
assertNull(builder.build().get(99));
assertEquals(0, builder.build().getFlags(99, 0 /* valueIfKeyNotFound */));
assertEquals(1, builder.build().getFlags(99, 1 /* valueIfKeyNotFound */));
- assertEquals(TEMP_RECT, builder.build().get(100));
- assertEquals(TEMP_FLAGS, builder.build().getFlags(100, 0 /* valueIfKeyNotFound */));
- assertEquals(TEMP_FLAGS, builder.build().getFlags(100, 1 /* valueIfKeyNotFound */));
+ assertEquals(testRect, builder.build().get(100));
+ assertEquals(testFlags, builder.build().getFlags(100, 0 /* valueIfKeyNotFound */));
+ assertEquals(testFlags, builder.build().getFlags(100, 1 /* valueIfKeyNotFound */));
assertNull(builder.build().get(101));
assertEquals(0, builder.build().getFlags(101, 0 /* valueIfKeyNotFound */));
assertEquals(1, builder.build().getFlags(101, 1 /* valueIfKeyNotFound */));
diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
index 9cb7876b3e5a..64bcc1c379ba 100644
--- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
@@ -98,9 +98,10 @@ public class FrameTrackerTest {
mListenerCapture = ArgumentCaptor.forClass(OnJankDataListener.class);
doNothing().when(mSurfaceControlWrapper).addJankStatsListener(
mListenerCapture.capture(), any());
+ doNothing().when(mSurfaceControlWrapper).removeJankStatsListener(
+ mListenerCapture.capture());
mChoreographer = mock(ChoreographerWrapper.class);
-
Session session = new Session(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
mTracker = Mockito.spy(
new FrameTracker(session, handler, mRenderer, mViewRootWrapper,
@@ -127,11 +128,12 @@ public class FrameTrackerTest {
sendFirstWindowFrame(5, JANK_NONE, 101L);
// end the trace session, the last janky frame is after the end() so is discarded.
- when(mChoreographer.getVsyncId()).thenReturn(101L);
+ when(mChoreographer.getVsyncId()).thenReturn(102L);
mTracker.end();
- sendFrame(500, JANK_APP_DEADLINE_MISSED, 102L);
+ sendFrame(5, JANK_NONE, 102L);
+ sendFrame(500, JANK_APP_DEADLINE_MISSED, 103L);
- verify(mRenderer).removeObserver(any());
+ verify(mTracker).removeObservers();
verify(mTracker, never()).triggerPerfetto();
}
@@ -148,11 +150,11 @@ public class FrameTrackerTest {
sendFrame(40, JANK_SURFACEFLINGER_DEADLINE_MISSED, 101L);
// end the trace session
- when(mChoreographer.getVsyncId()).thenReturn(101L);
+ when(mChoreographer.getVsyncId()).thenReturn(102L);
mTracker.end();
sendFrame(4, JANK_NONE, 102L);
- verify(mRenderer).removeObserver(any());
+ verify(mTracker).removeObservers();
// We detected a janky frame - trigger Perfetto
verify(mTracker).triggerPerfetto();
@@ -171,11 +173,11 @@ public class FrameTrackerTest {
sendFrame(4, JANK_NONE, 101L);
// end the trace session
- when(mChoreographer.getVsyncId()).thenReturn(101L);
+ when(mChoreographer.getVsyncId()).thenReturn(102L);
mTracker.end();
sendFrame(4, JANK_NONE, 102L);
- verify(mRenderer).removeObserver(any());
+ verify(mTracker).removeObservers();
// We detected a janky frame - trigger Perfetto
verify(mTracker, never()).triggerPerfetto();
@@ -194,11 +196,11 @@ public class FrameTrackerTest {
sendFrame(40, JANK_APP_DEADLINE_MISSED, 101L);
// end the trace session
- when(mChoreographer.getVsyncId()).thenReturn(101L);
+ when(mChoreographer.getVsyncId()).thenReturn(102L);
mTracker.end();
sendFrame(4, JANK_NONE, 102L);
- verify(mRenderer).removeObserver(any());
+ verify(mTracker).removeObservers();
// We detected a janky frame - trigger Perfetto
verify(mTracker).triggerPerfetto();
@@ -224,7 +226,7 @@ public class FrameTrackerTest {
// One more callback with VSYNC after the end() vsync id.
sendFrame(4, JANK_NONE, 103L);
- verify(mRenderer).removeObserver(any());
+ verify(mTracker).removeObservers();
// We detected a janky frame - trigger Perfetto
verify(mTracker).triggerPerfetto();
@@ -246,11 +248,50 @@ public class FrameTrackerTest {
sendFrame(50, JANK_APP_DEADLINE_MISSED, 102L);
mTracker.cancel();
- verify(mRenderer).removeObserver(any());
+ verify(mTracker).removeObservers();
// Since the tracker has been cancelled, shouldn't trigger perfetto.
verify(mTracker, never()).triggerPerfetto();
}
+ @Test
+ public void testRemoveObserversWhenCancelledInEnd() {
+ when(mChoreographer.getVsyncId()).thenReturn(100L);
+ mTracker.begin();
+ verify(mRenderer, only()).addObserver(any());
+
+ // send first frame - not janky
+ sendFrame(4, JANK_NONE, 100L);
+
+ // send another frame - should be considered janky
+ sendFrame(40, JANK_APP_DEADLINE_MISSED, 101L);
+
+ // end the trace session
+ when(mChoreographer.getVsyncId()).thenReturn(101L);
+ mTracker.end();
+ sendFrame(4, JANK_NONE, 102L);
+
+ // Since the begin vsync id (101) equals to the end vsync id (101), will be treat as cancel.
+ verify(mTracker).cancel();
+
+ // Observers should be removed in this case, or FrameTracker object will be leaked.
+ verify(mTracker).removeObservers();
+
+ // Should never trigger Perfetto since it is a cancel.
+ verify(mTracker, never()).triggerPerfetto();
+ }
+
+ @Test
+ public void testCancelWhenSessionNeverBegun() {
+ mTracker.cancel();
+ verify(mTracker).removeObservers();
+ }
+
+ @Test
+ public void testEndWhenSessionNeverBegun() {
+ mTracker.end();
+ verify(mTracker).removeObservers();
+ }
+
private void sendFirstWindowFrame(long durationMillis,
@JankType int jankType, long vsyncId) {
sendFrame(durationMillis, jankType, vsyncId, true /* firstWindowFrame */);
diff --git a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
index d50bb05c3588..b89e8bce5fc9 100644
--- a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
@@ -232,7 +232,7 @@ public final class LooperStatsTest {
assertThat(entry3.handlerClassName).isEqualTo(
"com.android.internal.os.LooperStatsTest$TestHandlerSecond");
assertThat(entry3.messageName).startsWith(
- "com.android.internal.os.LooperStatsTest-$$ExternalSyntheticLambda");
+ "com.android.internal.os.LooperStatsTest$$ExternalSyntheticLambda4");
assertThat(entry3.messageCount).isEqualTo(1);
assertThat(entry3.recordedMessageCount).isEqualTo(1);
assertThat(entry3.exceptionCount).isEqualTo(0);
diff --git a/core/tests/mockingcoretests/src/android/view/DisplayTests.java b/core/tests/mockingcoretests/src/android/view/DisplayTests.java
new file mode 100644
index 000000000000..678f21fe1211
--- /dev/null
+++ b/core/tests/mockingcoretests/src/android/view/DisplayTests.java
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_90;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManagerGlobal;
+import android.platform.test.annotations.Presubmit;
+import android.util.DisplayMetrics;
+import android.view.DisplayAdjustments.FixedRotationAdjustments;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.quality.Strictness;
+
+import java.util.function.Consumer;
+
+/**
+ * Tests for {@link Display}.
+ *
+ * <p>Build/Install/Run:
+ *
+ * atest FrameworksMockingCoreTests:android.view.DisplayTests
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class DisplayTests {
+
+ private static final int APP_WIDTH = 272;
+ private static final int APP_HEIGHT = 700;
+ // Tablet size device, ROTATION_0 corresponds to portrait.
+ private static final int LOGICAL_WIDTH = 700;
+ private static final int LOGICAL_HEIGHT = 1800;
+
+ // Bounds of the app when the device is in portrait mode.
+ private static Rect sAppBoundsPortrait = buildAppBounds(LOGICAL_WIDTH, LOGICAL_HEIGHT);
+ private static Rect sAppBoundsLandscape = buildAppBounds(LOGICAL_HEIGHT, LOGICAL_WIDTH);
+
+ private StaticMockitoSession mMockitoSession;
+
+ private DisplayManagerGlobal mDisplayManagerGlobal;
+ private Context mApplicationContext;
+ private DisplayInfo mDisplayInfo = new DisplayInfo();
+
+ @Before
+ public void setupTests() {
+ mMockitoSession = mockitoSession()
+ .mockStatic(DisplayManagerGlobal.class)
+ .strictness(Strictness.LENIENT)
+ .startMocking();
+
+ // Ensure no adjustments are set before each test.
+ mApplicationContext = ApplicationProvider.getApplicationContext();
+ DisplayAdjustments displayAdjustments =
+ mApplicationContext.getResources().getDisplayAdjustments();
+ displayAdjustments.setFixedRotationAdjustments(null);
+ mApplicationContext.getResources().overrideDisplayAdjustments(null);
+ mApplicationContext.getResources().getConfiguration().windowConfiguration.setAppBounds(
+ null);
+ mApplicationContext.getResources().getConfiguration().windowConfiguration.setMaxBounds(
+ null);
+ mDisplayInfo.rotation = ROTATION_0;
+
+ mDisplayManagerGlobal = mock(DisplayManagerGlobal.class);
+ doReturn(mDisplayInfo).when(mDisplayManagerGlobal).getDisplayInfo(anyInt());
+ }
+
+ @After
+ public void teardownTests() {
+ if (mMockitoSession != null) {
+ mMockitoSession.finishMocking();
+ }
+ Mockito.framework().clearInlineMocks();
+ }
+
+ @Test
+ public void testConstructor_defaultDisplayAdjustments_matchesDisplayInfo() {
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ assertThat(display.getDisplayAdjustments()).isEqualTo(
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ DisplayInfo actualDisplayInfo = new DisplayInfo();
+ display.getDisplayInfo(actualDisplayInfo);
+ verifyDisplayInfo(actualDisplayInfo, mDisplayInfo);
+ }
+
+ @Test
+ public void testConstructor_defaultResources_matchesDisplayInfo() {
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ assertThat(display.getDisplayAdjustments()).isEqualTo(
+ mApplicationContext.getResources().getDisplayAdjustments());
+ DisplayInfo actualDisplayInfo = new DisplayInfo();
+ display.getDisplayInfo(actualDisplayInfo);
+ verifyDisplayInfo(actualDisplayInfo, mDisplayInfo);
+ }
+
+ @Test
+ public void testGetRotation_defaultDisplayAdjustments_rotationNotAdjusted() {
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ assertThat(display.getRotation()).isEqualTo(ROTATION_0);
+ }
+
+ @Test
+ public void testGetRotation_displayAdjustmentsWithoutOverride_rotationNotAdjusted() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated, but no override is set.
+ DisplayAdjustments displayAdjustments = DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
+ final FixedRotationAdjustments fixedRotationAdjustments =
+ new FixedRotationAdjustments(ROTATION_90, APP_WIDTH, APP_HEIGHT,
+ DisplayCutout.NO_CUTOUT);
+ displayAdjustments.setFixedRotationAdjustments(fixedRotationAdjustments);
+ // GIVEN display is constructed with display adjustments.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ displayAdjustments);
+ // THEN rotation is not adjusted since no override was set.
+ assertThat(display.getRotation()).isEqualTo(ROTATION_0);
+ }
+
+ @Test
+ public void testGetRotation_resourcesWithoutOverride_rotationNotAdjusted() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated, but no override is set.
+ setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN rotation is not adjusted since no override is set.
+ assertThat(display.getRotation()).isEqualTo(ROTATION_0);
+ }
+
+ @Test
+ public void testGetRotation_resourcesWithOverrideDisplayAdjustments_rotationAdjusted() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated, and an override is set.
+ setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN rotation is adjusted since an override is set.
+ assertThat(display.getRotation()).isEqualTo(ROTATION_90);
+ }
+
+ @Test
+ public void testGetRealSize_defaultResourcesPortrait_matchesLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches display orientation.
+ verifyRealSizeIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealSize_defaultResourcesLandscape_matchesRotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches display orientation.
+ verifyRealSizeIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealSize_defaultDisplayAdjustmentsPortrait_matchesLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ // THEN real size matches display orientation.
+ verifyRealSizeIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealSize_defaultDisplayAdjustmentsLandscape_matchesLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ // THEN real size matches display orientation.
+ verifyRealSizeIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesPortraitWithFixedRotation_notRotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated.
+ setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches display orientation.
+ verifyRealSizeIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesWithLandscapeFixedRotation_notRotatedLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated.
+ setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches display orientation.
+ verifyRealSizeIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesWithPortraitOverrideRotation_rotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated, and an override is set.
+ setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches app orientation.
+ verifyRealSizeIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated, and an override is set.
+ setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches app orientation.
+ verifyRealSizeIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesPortraitSandboxed_matchesSandboxBounds() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN app is letterboxed.
+ setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
+ sAppBoundsPortrait);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches app bounds.
+ verifyRealSizeMatchesApp(display, sAppBoundsPortrait);
+ }
+
+ @Test
+ public void testGetRealSize_resourcesLandscapeSandboxed_matchesSandboxBounds() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN app is letterboxed.
+ setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
+ sAppBoundsLandscape);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real size matches app bounds.
+ verifyRealSizeMatchesApp(display, sAppBoundsLandscape);
+ }
+
+ @Test
+ public void testGetRealMetrics_defaultResourcesPortrait_matchesLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_defaultResourcesLandscape_matchesRotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_defaultDisplayAdjustmentsPortrait_matchesLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_defaultDisplayAdjustmentsLandscape_matchesLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesPortraitWithFixedRotation_notRotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated.
+ setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesWithLandscapeFixedRotation_notRotatedLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated.
+ setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches display orientation.
+ verifyRealMetricsIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesWithPortraitOverrideRotation_rotatedLogicalSize() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated with an override.
+ setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches app orientation.
+ verifyRealMetricsIsPortrait(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN fixed rotation adjustments are rotated.
+ setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90);
+ // GIVEN display is constructed with default resources.
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches app orientation.
+ verifyRealMetricsIsLandscape(display);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesPortraitSandboxed_matchesSandboxBounds() {
+ // GIVEN display is not rotated.
+ setDisplayInfoPortrait(mDisplayInfo);
+ // GIVEN app is letterboxed.
+ setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
+ sAppBoundsPortrait);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches app bounds.
+ verifyRealMetricsMatchesApp(display, sAppBoundsPortrait);
+ }
+
+ @Test
+ public void testGetRealMetrics_resourcesLandscapeSandboxed_matchesSandboxBounds() {
+ // GIVEN display is rotated.
+ setDisplayInfoLandscape(mDisplayInfo);
+ // GIVEN app is letterboxed.
+ setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
+ sAppBoundsLandscape);
+ final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
+ mApplicationContext.getResources());
+ // THEN real metrics matches app bounds.
+ verifyRealMetricsMatchesApp(display, sAppBoundsLandscape);
+ }
+
+ // Given rotated display dimensions, calculate the letterboxed app bounds.
+ private static Rect buildAppBounds(int displayWidth, int displayHeight) {
+ final int midWidth = displayWidth / 2;
+ final int left = midWidth - (APP_WIDTH / 2);
+ final int right = midWidth + (APP_WIDTH / 2);
+ final int midHeight = displayHeight / 2;
+ // Coordinate system starts at top left.
+ final int top = midHeight - (APP_HEIGHT / 2);
+ final int bottom = midHeight + (APP_HEIGHT / 2);
+ return new Rect(left, top, right, bottom);
+ }
+
+ private static void setDisplayInfoLandscape(DisplayInfo displayInfo) {
+ displayInfo.rotation = ROTATION_90;
+ // Flip width & height assignment since the device is rotated.
+ displayInfo.logicalWidth = LOGICAL_HEIGHT;
+ displayInfo.logicalHeight = LOGICAL_WIDTH;
+ }
+
+ private static void setDisplayInfoPortrait(DisplayInfo displayInfo) {
+ displayInfo.rotation = ROTATION_0;
+ displayInfo.logicalWidth = LOGICAL_WIDTH;
+ displayInfo.logicalHeight = LOGICAL_HEIGHT;
+ }
+
+ /**
+ * Set max bounds to be sandboxed to the app bounds, indicating the app is in
+ * size compat mode or letterbox.
+ */
+ private static void setMaxBoundsSandboxedToMatchAppBounds(Resources resources, Rect appBounds) {
+ resources.getConfiguration().windowConfiguration.setMaxBounds(appBounds);
+ }
+
+ /**
+ * Do not compare entire display info, since it is updated to match display the test is run on.
+ */
+ private static void verifyDisplayInfo(DisplayInfo actual, DisplayInfo expected) {
+ assertThat(actual.displayId).isEqualTo(expected.displayId);
+ assertThat(actual.rotation).isEqualTo(expected.rotation);
+ assertThat(actual.logicalWidth).isEqualTo(LOGICAL_WIDTH);
+ assertThat(actual.logicalHeight).isEqualTo(LOGICAL_HEIGHT);
+ }
+
+ private static void verifyRealSizeIsLandscape(Display display) {
+ Point size = new Point();
+ display.getRealSize(size);
+ // Flip the width and height check since the device is rotated.
+ assertThat(size).isEqualTo(new Point(LOGICAL_HEIGHT, LOGICAL_WIDTH));
+ }
+
+ private static void verifyRealMetricsIsLandscape(Display display) {
+ DisplayMetrics metrics = new DisplayMetrics();
+ display.getRealMetrics(metrics);
+ // Flip the width and height check since the device is rotated.
+ assertThat(metrics.widthPixels).isEqualTo(LOGICAL_HEIGHT);
+ assertThat(metrics.heightPixels).isEqualTo(LOGICAL_WIDTH);
+ }
+
+ private static void verifyRealSizeIsPortrait(Display display) {
+ Point size = new Point();
+ display.getRealSize(size);
+ assertThat(size).isEqualTo(new Point(LOGICAL_WIDTH, LOGICAL_HEIGHT));
+ }
+
+ private static void verifyRealMetricsIsPortrait(Display display) {
+ DisplayMetrics metrics = new DisplayMetrics();
+ display.getRealMetrics(metrics);
+ assertThat(metrics.widthPixels).isEqualTo(LOGICAL_WIDTH);
+ assertThat(metrics.heightPixels).isEqualTo(LOGICAL_HEIGHT);
+ }
+
+ private static void verifyRealSizeMatchesApp(Display display, Rect appBounds) {
+ Point size = new Point();
+ display.getRealSize(size);
+ assertThat(size).isEqualTo(new Point(appBounds.width(), appBounds.height()));
+ }
+
+ private static void verifyRealMetricsMatchesApp(Display display, Rect appBounds) {
+ DisplayMetrics metrics = new DisplayMetrics();
+ display.getRealMetrics(metrics);
+ assertThat(metrics.widthPixels).isEqualTo(appBounds.width());
+ assertThat(metrics.heightPixels).isEqualTo(appBounds.height());
+ }
+
+ private static FixedRotationAdjustments setOverrideFixedRotationAdjustments(
+ Resources resources, @Surface.Rotation int rotation) {
+ FixedRotationAdjustments fixedRotationAdjustments =
+ setFixedRotationAdjustments(resources, rotation);
+ resources.overrideDisplayAdjustments(
+ buildOverrideRotationAdjustments(fixedRotationAdjustments));
+ return fixedRotationAdjustments;
+ }
+
+ private static FixedRotationAdjustments setFixedRotationAdjustments(Resources resources,
+ @Surface.Rotation int rotation) {
+ final FixedRotationAdjustments fixedRotationAdjustments =
+ new FixedRotationAdjustments(rotation, APP_WIDTH, APP_HEIGHT,
+ DisplayCutout.NO_CUTOUT);
+ resources.getDisplayAdjustments().setFixedRotationAdjustments(fixedRotationAdjustments);
+ return fixedRotationAdjustments;
+ }
+
+ private static Consumer<DisplayAdjustments> buildOverrideRotationAdjustments(
+ FixedRotationAdjustments fixedRotationAdjustments) {
+ return consumedDisplayAdjustments
+ -> consumedDisplayAdjustments.setFixedRotationAdjustments(fixedRotationAdjustments);
+ }
+}
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index b7bf8ab75799..4a3bd99b8f7c 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -307,6 +307,12 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "-1777196134": {
+ "message": "goodToGo(): No apps to animate, mPendingAnimations=%d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
"-1770075711": {
"message": "Adding window client %s that is dead, aborting.",
"level": "WARN",
@@ -1219,6 +1225,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DragState.java"
},
+ "-681380736": {
+ "message": "Sandbox max bounds for uid %s to bounds %s due to letterboxing from mismatch with parent bounds? %s size compat mode %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_CONFIGURATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-677449371": {
"message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b",
"level": "DEBUG",
@@ -1981,12 +1993,6 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "194124419": {
- "message": "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d",
- "level": "DEBUG",
- "group": "WM_DEBUG_REMOTE_ANIMATIONS",
- "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
- },
"200829729": {
"message": "ScreenRotationAnimation onAnimationEnd",
"level": "DEBUG",
@@ -2083,6 +2089,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DragState.java"
},
+ "269976641": {
+ "message": "goodToGo(): Animation canceled already",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
"274773837": {
"message": "applyAnimation: anim=%s nextAppTransition=ANIM_CLIP_REVEAL transit=%s Callers=%s",
"level": "VERBOSE",
diff --git a/data/keyboards/Vendor_0957_Product_0001.idc b/data/keyboards/Vendor_0957_Product_0001.idc
index e1f4346369f3..39479ce725e1 100644
--- a/data/keyboards/Vendor_0957_Product_0001.idc
+++ b/data/keyboards/Vendor_0957_Product_0001.idc
@@ -19,5 +19,4 @@
# Basic Parameters
keyboard.layout = Vendor_0957_Product_0001
-keyboard.characterMap = Vendor_0957_Product_0001
audio.mic = 1 \ No newline at end of file
diff --git a/data/keyboards/Vendor_248a_Product_8266.idc b/data/keyboards/Vendor_248a_Product_8266.idc
new file mode 100644
index 000000000000..3021655c286e
--- /dev/null
+++ b/data/keyboards/Vendor_248a_Product_8266.idc
@@ -0,0 +1,24 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Input Device Configuration file for Google Reference RCU Remote.
+#
+#
+
+# Basic Parameters
+# Due to a memory error on early prototypes of the reference remote control
+# the VID/PID is mapped to 248a/8266 instead of 0957/0001
+keyboard.layout = Vendor_0957_Product_0001
+audio.mic = 1 \ No newline at end of file
diff --git a/graphics/java/android/graphics/drawable/RippleAnimationSession.java b/graphics/java/android/graphics/drawable/RippleAnimationSession.java
index 80f65f919fa6..f3bf63bb3660 100644
--- a/graphics/java/android/graphics/drawable/RippleAnimationSession.java
+++ b/graphics/java/android/graphics/drawable/RippleAnimationSession.java
@@ -27,8 +27,9 @@ import android.graphics.Paint;
import android.graphics.RecordingCanvas;
import android.graphics.animation.RenderNodeAnimator;
import android.util.ArraySet;
-import android.view.animation.DecelerateInterpolator;
+import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
+import android.view.animation.PathInterpolator;
import java.util.function.Consumer;
@@ -36,32 +37,41 @@ import java.util.function.Consumer;
* @hide
*/
public final class RippleAnimationSession {
- private static final int ENTER_ANIM_DURATION = 350;
- private static final int EXIT_ANIM_OFFSET = ENTER_ANIM_DURATION;
- private static final int EXIT_ANIM_DURATION = 350;
+ private static final String TAG = "RippleAnimationSession";
+ private static final int ENTER_ANIM_DURATION = 300;
+ private static final int SLIDE_ANIM_DURATION = 450;
+ private static final int EXIT_ANIM_DURATION = 300;
private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
- // Matches R.interpolator.fast_out_slow_in but as we have no context we can't just import that
- private static final TimeInterpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator();
-
+ private static final TimeInterpolator PATH_INTERPOLATOR =
+ new PathInterpolator(.2f, 0, 0, 1f);
private Consumer<RippleAnimationSession> mOnSessionEnd;
- private AnimationProperties<Float, Paint> mProperties;
+ private final AnimationProperties<Float, Paint> mProperties;
private AnimationProperties<CanvasProperty<Float>, CanvasProperty<Paint>> mCanvasProperties;
private Runnable mOnUpdate;
private long mStartTime;
private boolean mForceSoftware;
- private ArraySet<Animator> mActiveAnimations = new ArraySet(3);
+ private final float mWidth, mHeight;
+ private final ValueAnimator mSparkle = ValueAnimator.ofFloat(0, 1);
+ private final ArraySet<Animator> mActiveAnimations = new ArraySet<>(3);
RippleAnimationSession(@NonNull AnimationProperties<Float, Paint> properties,
- boolean forceSoftware) {
+ boolean forceSoftware, float width, float height) {
mProperties = properties;
mForceSoftware = forceSoftware;
- }
-
- void end() {
- for (Animator anim: mActiveAnimations) {
- if (anim != null) anim.end();
- }
- mActiveAnimations.clear();
+ mWidth = width;
+ mHeight = height;
+
+ mSparkle.addUpdateListener(anim -> {
+ final long now = AnimationUtils.currentAnimationTimeMillis();
+ final long elapsed = now - mStartTime - ENTER_ANIM_DURATION;
+ final float phase = (float) elapsed / 1000f;
+ mProperties.getShader().setSecondsOffset(phase);
+ notifyUpdate();
+ });
+ mSparkle.setDuration(ENTER_ANIM_DURATION);
+ mSparkle.setStartDelay(ENTER_ANIM_DURATION);
+ mSparkle.setInterpolator(LINEAR_INTERPOLATOR);
+ mSparkle.setRepeatCount(ValueAnimator.INFINITE);
}
@NonNull RippleAnimationSession enter(Canvas canvas) {
@@ -70,17 +80,19 @@ public final class RippleAnimationSession {
} else {
enterSoftware();
}
- mStartTime = System.nanoTime();
+ mStartTime = AnimationUtils.currentAnimationTimeMillis();
return this;
}
@NonNull RippleAnimationSession exit(Canvas canvas) {
+ mSparkle.end();
if (isHwAccelerated(canvas)) exitHardware((RecordingCanvas) canvas);
else exitSoftware();
return this;
}
private void onAnimationEnd(Animator anim) {
+ notifyUpdate();
mActiveAnimations.remove(anim);
}
@@ -92,7 +104,6 @@ public final class RippleAnimationSession {
RippleAnimationSession setOnAnimationUpdated(@Nullable Runnable run) {
mOnUpdate = run;
- mProperties.setOnChange(mOnUpdate);
return this;
}
@@ -122,14 +133,12 @@ public final class RippleAnimationSession {
}
private long computeDelay() {
- long currentTime = System.nanoTime();
- long timePassed = (currentTime - mStartTime) / 1_000_000;
- long difference = EXIT_ANIM_OFFSET;
- return Math.max(difference - timePassed, 0);
+ final long timePassed = AnimationUtils.currentAnimationTimeMillis() - mStartTime;
+ return Math.max((long) SLIDE_ANIM_DURATION - timePassed, 0);
}
+
private void notifyUpdate() {
- Runnable onUpdate = mOnUpdate;
- if (onUpdate != null) onUpdate.run();
+ if (mOnUpdate != null) mOnUpdate.run();
}
RippleAnimationSession setForceSoftwareAnimation(boolean forceSw) {
@@ -153,7 +162,7 @@ public final class RippleAnimationSession {
}
});
exit.setTarget(canvas);
- exit.setInterpolator(DECELERATE_INTERPOLATOR);
+ exit.setInterpolator(LINEAR_INTERPOLATOR);
long delay = computeDelay();
exit.setStartDelay(delay);
@@ -161,36 +170,67 @@ public final class RippleAnimationSession {
mActiveAnimations.add(exit);
}
- private void enterHardware(RecordingCanvas can) {
+ private void enterHardware(RecordingCanvas canvas) {
AnimationProperties<CanvasProperty<Float>, CanvasProperty<Paint>>
props = getCanvasProperties();
RenderNodeAnimator expand =
new RenderNodeAnimator(props.getProgress(), .5f);
- expand.setTarget(can);
- expand.setDuration(ENTER_ANIM_DURATION);
- expand.addListener(new AnimatorListener(this));
+ RenderNodeAnimator slideX =
+ new RenderNodeAnimator(props.getX(), mWidth / 2);
+ RenderNodeAnimator slideY =
+ new RenderNodeAnimator(props.getY(), mHeight / 2);
+ expand.setTarget(canvas);
+ slideX.setTarget(canvas);
+ slideY.setTarget(canvas);
+ startAnimation(expand, slideX, slideY);
+ }
+
+ private void startAnimation(Animator expand,
+ Animator slideX, Animator slideY) {
+ expand.setDuration(SLIDE_ANIM_DURATION);
+ slideX.setDuration(SLIDE_ANIM_DURATION);
+ slideY.setDuration(SLIDE_ANIM_DURATION);
+ slideX.addListener(new AnimatorListener(this));
expand.setInterpolator(LINEAR_INTERPOLATOR);
+ slideX.setInterpolator(PATH_INTERPOLATOR);
+ slideY.setInterpolator(PATH_INTERPOLATOR);
expand.start();
+ slideX.start();
+ slideY.start();
+ if (!mSparkle.isRunning()) {
+ mSparkle.start();
+ mActiveAnimations.add(mSparkle);
+ }
mActiveAnimations.add(expand);
+ mActiveAnimations.add(slideX);
+ mActiveAnimations.add(slideY);
}
private void enterSoftware() {
ValueAnimator expand = ValueAnimator.ofFloat(0f, 0.5f);
+ ValueAnimator slideX = ValueAnimator.ofFloat(
+ mProperties.getX(), mWidth / 2);
+ ValueAnimator slideY = ValueAnimator.ofFloat(
+ mProperties.getY(), mHeight / 2);
expand.addUpdateListener(updatedAnimation -> {
notifyUpdate();
mProperties.getShader().setProgress((Float) expand.getAnimatedValue());
});
- expand.addListener(new AnimatorListener(this));
- expand.setInterpolator(LINEAR_INTERPOLATOR);
- expand.start();
- mActiveAnimations.add(expand);
+ slideX.addUpdateListener(anim -> {
+ float x = (float) slideX.getAnimatedValue();
+ float y = (float) slideY.getAnimatedValue();
+ mProperties.setOrigin(x, y);
+ mProperties.getShader().setOrigin(x, y);
+ });
+ startAnimation(expand, slideX, slideY);
}
@NonNull AnimationProperties<Float, Paint> getProperties() {
return mProperties;
}
- @NonNull AnimationProperties getCanvasProperties() {
+ @NonNull
+ AnimationProperties<CanvasProperty<Float>, CanvasProperty<Paint>> getCanvasProperties() {
if (mCanvasProperties == null) {
mCanvasProperties = new AnimationProperties<>(
CanvasProperty.createFloat(mProperties.getX()),
@@ -209,6 +249,7 @@ public final class RippleAnimationSession {
AnimatorListener(RippleAnimationSession session) {
mSession = session;
}
+
@Override
public void onAnimationStart(Animator animation) {
@@ -231,21 +272,12 @@ public final class RippleAnimationSession {
}
static class AnimationProperties<FloatType, PaintType> {
- private final FloatType mY;
- private FloatType mProgress;
- private FloatType mMaxRadius;
+ private final FloatType mProgress;
+ private final FloatType mMaxRadius;
private final PaintType mPaint;
- private final FloatType mX;
private final RippleShader mShader;
- private Runnable mOnChange;
-
- private void onChange() {
- if (mOnChange != null) mOnChange.run();
- }
-
- private void setOnChange(Runnable onChange) {
- mOnChange = onChange;
- }
+ private FloatType mX;
+ private FloatType mY;
AnimationProperties(FloatType x, FloatType y, FloatType maxRadius,
PaintType paint, FloatType progress, RippleShader shader) {
@@ -261,6 +293,11 @@ public final class RippleAnimationSession {
return mProgress;
}
+ void setOrigin(FloatType x, FloatType y) {
+ mX = x;
+ mY = y;
+ }
+
FloatType getX() {
return mX;
}
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 5024875aab3c..d6bbee90d73b 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -48,6 +48,7 @@ import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.Shader;
import android.os.Build;
+import android.os.SystemProperties;
import android.util.AttributeSet;
import android.view.animation.LinearInterpolator;
@@ -109,17 +110,6 @@ import java.util.Arrays;
* </pre>
*
* @attr ref android.R.styleable#RippleDrawable_color
- *
- * To change the ripple style, assign the value of "solid" or "patterned" to the android:rippleStyle
- * attribute.
- *
- * <pre>
- * <code>&lt;!-- A red ripple masked against an opaque rectangle. --/>
- * &lt;ripple android:rippleStyle="patterned">
- * &lt;/ripple></code>
- * </pre>
- *
- * @attr ref android.R.styleable#RippleDrawable_rippleStyle
*/
public class RippleDrawable extends LayerDrawable {
/**
@@ -131,12 +121,14 @@ public class RippleDrawable extends LayerDrawable {
/**
* Ripple style where a solid circle is drawn. This is also the default style
* @see #setRippleStyle(int)
+ * @hide
*/
public static final int STYLE_SOLID = 0;
/**
* Ripple style where a circle shape with a patterned,
* noisy interior expands from the hotspot to the bounds".
* @see #setRippleStyle(int)
+ * @hide
*/
public static final int STYLE_PATTERNED = 1;
@@ -159,6 +151,9 @@ public class RippleDrawable extends LayerDrawable {
/** The maximum number of ripples supported. */
private static final int MAX_RIPPLES = 10;
private static final LinearInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
+ /** Temporary flag for teamfood. **/
+ private static final boolean FORCE_PATTERNED_STYLE =
+ SystemProperties.getBoolean("persist.material.patternedripple", false);
private final Rect mTempRect = new Rect();
@@ -361,7 +356,9 @@ public class RippleDrawable extends LayerDrawable {
}
} else {
if (focused || hovered) {
- enterPatternedBackgroundAnimation(focused, hovered);
+ if (!pressed) {
+ enterPatternedBackgroundAnimation(focused, hovered);
+ }
} else {
exitPatternedBackgroundAnimation();
}
@@ -571,7 +568,10 @@ public class RippleDrawable extends LayerDrawable {
mState.mMaxRadius = a.getDimensionPixelSize(
R.styleable.RippleDrawable_radius, mState.mMaxRadius);
- mState.mRippleStyle = a.getInteger(R.styleable.RippleDrawable_rippleStyle, STYLE_SOLID);
+ if (!FORCE_PATTERNED_STYLE) {
+ mState.mRippleStyle = a.getInteger(R.styleable.RippleDrawable_rippleStyle,
+ mState.mRippleStyle);
+ }
}
private void verifyRequiredAttributes(@NonNull TypedArray a) throws XmlPullParserException {
@@ -812,21 +812,25 @@ public class RippleDrawable extends LayerDrawable {
}
private void drawPatterned(@NonNull Canvas canvas) {
- final Rect bounds = getBounds();
+ final Rect bounds = getDirtyBounds();
final int saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
boolean useCanvasProps = shouldUseCanvasProps(canvas);
boolean changedHotspotBounds = !bounds.equals(mHotspotBounds);
if (isBounded()) {
- canvas.clipRect(mHotspotBounds);
+ canvas.clipRect(bounds);
}
- float x, y;
+ float x, y, w, h;
if (changedHotspotBounds) {
x = mHotspotBounds.exactCenterX();
y = mHotspotBounds.exactCenterY();
+ w = mHotspotBounds.width();
+ h = mHotspotBounds.height();
useCanvasProps = false;
} else {
x = mPendingX;
y = mPendingY;
+ w = bounds.width();
+ h = bounds.height();
}
boolean shouldAnimate = mRippleActive;
boolean shouldExit = mExitingAnimation;
@@ -837,9 +841,9 @@ public class RippleDrawable extends LayerDrawable {
drawPatternedBackground(canvas);
if (shouldAnimate && mRunningAnimations.size() <= MAX_RIPPLES) {
RippleAnimationSession.AnimationProperties<Float, Paint> properties =
- createAnimationProperties(x, y);
- mRunningAnimations.add(new RippleAnimationSession(properties, !useCanvasProps)
- .setOnAnimationUpdated(useCanvasProps ? null : () -> invalidateSelf(false))
+ createAnimationProperties(x, y, w, h);
+ mRunningAnimations.add(new RippleAnimationSession(properties, !useCanvasProps, w, h)
+ .setOnAnimationUpdated(() -> invalidateSelf(false))
.setOnSessionEnd(session -> {
mRunningAnimations.remove(session);
})
@@ -864,20 +868,8 @@ public class RippleDrawable extends LayerDrawable {
} else {
RippleAnimationSession.AnimationProperties<Float, Paint> p =
s.getProperties();
- float posX, posY;
- if (changedHotspotBounds) {
- posX = x;
- posY = y;
- if (p.getPaint().getShader() instanceof RippleShader) {
- RippleShader shader = (RippleShader) p.getPaint().getShader();
- shader.setOrigin(posX, posY);
- }
- } else {
- posX = p.getX();
- posY = p.getY();
- }
float radius = p.getMaxRadius();
- canvas.drawCircle(posX, posY, radius, p.getPaint());
+ canvas.drawCircle(p.getX(), p.getY(), radius, p.getPaint());
}
}
canvas.restoreToCount(saveCount);
@@ -905,14 +897,13 @@ public class RippleDrawable extends LayerDrawable {
private float computeRadius() {
Rect b = getDirtyBounds();
- float gap = 0;
- float radius = (float) Math.sqrt(b.width() * b.width() + b.height() * b.height()) / 2 + gap;
+ float radius = (float) Math.sqrt(b.width() * b.width() + b.height() * b.height()) / 2;
return radius;
}
@NonNull
private RippleAnimationSession.AnimationProperties<Float, Paint> createAnimationProperties(
- float x, float y) {
+ float x, float y, float w, float h) {
Paint p = new Paint(mRipplePaint);
float radius = mState.mMaxRadius;
RippleAnimationSession.AnimationProperties<Float, Paint> properties;
@@ -920,19 +911,19 @@ public class RippleDrawable extends LayerDrawable {
int color = mMaskColorFilter == null
? mState.mColor.getColorForState(getState(), Color.BLACK)
: mMaskColorFilter.getColor();
- color = color | 0xFF000000;
shader.setColor(color);
shader.setOrigin(x, y);
+ shader.setResolution(w, h);
+ shader.setSecondsOffset(0);
shader.setRadius(radius);
shader.setProgress(.0f);
properties = new RippleAnimationSession.AnimationProperties<>(
x, y, radius, p, 0f,
shader);
if (mMaskShader == null) {
- shader.setHasMask(false);
+ shader.setShader(null);
} else {
shader.setShader(mMaskShader);
- shader.setHasMask(true);
}
p.setShader(shader);
p.setColorFilter(null);
@@ -1160,7 +1151,7 @@ public class RippleDrawable extends LayerDrawable {
// The ripple timing depends on the paint's alpha value, so we need
// to push just the alpha channel into the paint and let the filter
// handle the full-alpha color.
- int maskColor = color | 0xFF000000;
+ int maskColor = mState.mRippleStyle == STYLE_PATTERNED ? color : color | 0xFF000000;
if (mMaskColorFilter.getColor() != maskColor) {
mMaskColorFilter = new PorterDuffColorFilter(maskColor, mMaskColorFilter.getMode());
}
@@ -1248,6 +1239,7 @@ public class RippleDrawable extends LayerDrawable {
* @see #STYLE_PATTERNED
*
* @param style The style of the ripple
+ * @hide
*/
public void setRippleStyle(@RippleStyle int style) throws IllegalArgumentException {
if (style == STYLE_SOLID || style == STYLE_PATTERNED) {
@@ -1260,6 +1252,7 @@ public class RippleDrawable extends LayerDrawable {
/**
* Get the current ripple style
* @return Ripple style
+ * @hide
*/
public @RippleStyle int getRippleStyle() {
return mState.mRippleStyle;
@@ -1276,7 +1269,7 @@ public class RippleDrawable extends LayerDrawable {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
ColorStateList mColor = ColorStateList.valueOf(Color.MAGENTA);
int mMaxRadius = RADIUS_AUTO;
- int mRippleStyle = STYLE_SOLID;
+ int mRippleStyle = FORCE_PATTERNED_STYLE ? STYLE_PATTERNED : STYLE_SOLID;
public RippleState(LayerState orig, RippleDrawable owner, Resources res) {
super(orig, owner, res);
diff --git a/graphics/java/android/graphics/drawable/RippleShader.java b/graphics/java/android/graphics/drawable/RippleShader.java
index 500efdd84854..25492779e6e9 100644
--- a/graphics/java/android/graphics/drawable/RippleShader.java
+++ b/graphics/java/android/graphics/drawable/RippleShader.java
@@ -17,58 +17,153 @@
package android.graphics.drawable;
import android.annotation.ColorInt;
-import android.annotation.NonNull;
import android.graphics.Color;
import android.graphics.RuntimeShader;
import android.graphics.Shader;
final class RippleShader extends RuntimeShader {
- private static final String SHADER = "uniform float2 in_origin;\n"
- + "uniform float in_maxRadius;\n"
+ private static final String SHADER_UNIFORMS = "uniform vec2 in_origin;\n"
+ "uniform float in_progress;\n"
+ + "uniform float in_maxRadius;\n"
+ + "uniform vec2 in_resolution;\n"
+ "uniform float in_hasMask;\n"
- + "uniform float4 in_color;\n"
- + "uniform shader in_shader;\n"
- + "float dist2(float2 p0, float2 pf) { return sqrt((pf.x - p0.x) * (pf.x - p0.x) + "
- + "(pf.y - p0.y) * (pf.y - p0.y)); }\n"
- + "float mod2(float a, float b) { return a - (b * floor(a / b)); }\n"
- + "float rand(float2 src) { return fract(sin(dot(src.xy, float2(12.9898, 78.233))) * "
- + "43758.5453123); }\n"
- + "float4 main(float2 p)\n"
- + "{\n"
- + " float fraction = in_progress;\n"
- + " float2 fragCoord = p;//sk_FragCoord.xy;\n"
- + " float maxDist = in_maxRadius;\n"
- + " float fragDist = dist2(in_origin, fragCoord.xy);\n"
- + " float circleRadius = maxDist * fraction;\n"
- + " float colorVal = (fragDist - circleRadius) / maxDist;\n"
- + " float d = fragDist < circleRadius \n"
- + " ? 1. - abs(colorVal * 3. * smoothstep(0., 1., fraction)) \n"
- + " : 1. - abs(colorVal * 5.);\n"
- + " d = smoothstep(0., 1., d);\n"
- + " float divider = 2.;\n"
- + " float x = floor(fragCoord.x / divider);\n"
- + " float y = floor(fragCoord.y / divider);\n"
- + " float density = .95;\n"
- + " d = rand(float2(x, y)) > density ? d : d * .2;\n"
- + " d = d * rand(float2(fraction, x * y));\n"
- + " float alpha = 1. - pow(fraction, 2.);\n"
- + " if (in_hasMask != 0.) {return sample(in_shader).a * in_color * d * alpha;}\n"
- + " return in_color * d * alpha;\n"
+ + "uniform float in_secondsOffset;\n"
+ + "uniform vec4 in_color;\n"
+ + "uniform shader in_shader;\n";
+ private static final String SHADER_LIB =
+ "float triangleNoise(vec2 n) {\n"
+ + " n = fract(n * vec2(5.3987, 5.4421));\n"
+ + " n += dot(n.yx, n.xy + vec2(21.5351, 14.3137));\n"
+ + " float xy = n.x * n.y;\n"
+ + " return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;\n"
+ + "}"
+ + "const float PI = 3.1415926535897932384626;\n"
+ + "\n"
+ + "float threshold(float v, float l, float h) {\n"
+ + " return step(l, v) * (1.0 - step(h, v));\n"
+ + "}\n"
+ + "\n"
+ + "float sparkles(vec2 uv, float t) {\n"
+ + " float n = triangleNoise(uv);\n"
+ + " float s = 0.0;\n"
+ + " for (float i = 0; i < 4; i += 1) {\n"
+ + " float l = i * 0.25;\n"
+ + " float h = l + 0.025;\n"
+ + " float o = abs(sin(0.1 * PI * (t + i)));\n"
+ + " s += threshold(n + o, l, h);\n"
+ + " }\n"
+ + " return saturate(s);\n"
+ + "}\n"
+ + "\n"
+ + "float softCircle(vec2 uv, vec2 xy, float radius, float blur) {\n"
+ + " float blurHalf = blur * 0.5;\n"
+ + " float d = distance(uv, xy);\n"
+ + " return 1. - smoothstep(1. - blurHalf, 1. + blurHalf, d / radius);\n"
+ + "}\n"
+ + "\n"
+ + "float softRing(vec2 uv, vec2 xy, float radius, float blur) {\n"
+ + " float thickness = 0.4;\n"
+ + " float circle_outer = softCircle(uv, xy, radius + thickness * 0.5, blur);\n"
+ + " float circle_inner = softCircle(uv, xy, radius - thickness * 0.5, blur);\n"
+ + " return circle_outer - circle_inner;\n"
+ + "}\n"
+ + "\n"
+ + "struct Viewport {\n"
+ + " float aspect;\n"
+ + " vec2 uv;\n"
+ + " vec2 resolution_pixels;\n"
+ + "};\n"
+ + "\n"
+ + "Viewport getViewport(vec2 frag_coord, vec2 resolution_pixels) {\n"
+ + " Viewport v;\n"
+ + " v.aspect = resolution_pixels.y / resolution_pixels.x;\n"
+ + " v.uv = frag_coord / resolution_pixels;\n"
+ + " v.uv.y = (1.0 - v.uv.y) * v.aspect;\n"
+ + " v.resolution_pixels = resolution_pixels;\n"
+ + " return v;\n"
+ + "}\n"
+ + "\n"
+ + "vec2 getTouch(vec2 touch_position_pixels, Viewport viewport) {\n"
+ + " vec2 touch = touch_position_pixels / viewport.resolution_pixels;\n"
+ + " touch.y *= viewport.aspect;\n"
+ + " return touch;\n"
+ + "}\n"
+ + "\n"
+ + "struct Wave {\n"
+ + " float ring;\n"
+ + " float circle;\n"
+ + "};\n"
+ + "\n"
+ + "Wave getWave(Viewport viewport, vec2 touch, float progress) {\n"
+ + " float fade = pow((clamp(progress, 0.8, 1.0)), 8.);\n"
+ + " Wave w;\n"
+ + " w.ring = max(softRing(viewport.uv, touch, progress, 0.45) - fade, 0.);\n"
+ + " w.circle = softCircle(viewport.uv, touch, 2.0 * progress, 0.2) - progress;\n"
+ + " return w;\n"
+ + "}\n"
+ + "\n"
+ + "vec4 getRipple(vec4 color, float loudness, float sparkle, Wave wave) {\n"
+ + " float alpha = wave.ring * sparkle * loudness\n"
+ + " + wave.circle * color.a;\n"
+ + " return vec4(color.rgb, saturate(alpha));\n"
+ + "}\n"
+ + "\n"
+ + "float getRingMask(vec2 frag, vec2 center, float r, float progress) {\n"
+ + " float dist = distance(frag, center);\n"
+ + " float expansion = r * .6;\n"
+ + " r = r * min(1.,progress);\n"
+ + " float minD = max(r - expansion, 0.);\n"
+ + " float maxD = r + expansion;\n"
+ + " if (dist > maxD || dist < minD) return .0;\n"
+ + " return min(maxD - dist, dist - minD) / expansion; \n"
+ + "}\n"
+ + "\n"
+ + "float subProgress(float start, float end, float progress) {\n"
+ + " float sub = clamp(progress, start, end);\n"
+ + " return (sub - start) / (end - start); \n"
+ "}\n";
+ private static final String SHADER_MAIN = "vec4 main(vec2 p) {\n"
+ + " float fadeIn = subProgress(0., 0.175, in_progress);\n"
+ + " float fadeOutNoise = subProgress(0.375, 1., in_progress);\n"
+ + " float fadeOutRipple = subProgress(0.375, 0.75, in_progress);\n"
+ + " Viewport vp = getViewport(p, in_resolution);\n"
+ + " vec2 touch = getTouch(in_origin, vp);\n"
+ + " Wave w = getWave(vp, touch, in_progress * 0.25);\n"
+ + " float ring = getRingMask(p, in_origin, in_maxRadius, fadeIn);\n"
+ + " float alpha = min(fadeIn, 1. - fadeOutNoise);\n"
+ + " float sparkle = sparkles(p, in_progress * 0.25 + in_secondsOffset)\n"
+ + " * ring * alpha;\n"
+ + " vec4 r = getRipple(in_color, 1., sparkle, w);\n"
+ + " float fade = min(fadeIn, 1.-fadeOutRipple);\n"
+ + " vec4 circle = vec4(in_color.rgb, softCircle(p, in_origin, in_maxRadius "
+ + " * fadeIn, 0.2) * fade * in_color.a);\n"
+ + " float mask = in_hasMask == 1. ? sample(in_shader).a > 0. ? 1. : 0. : 1.;\n"
+ + " return mix(circle, vec4(1.), sparkle * mask);\n"
+ + "}";
+ private static final String SHADER = SHADER_UNIFORMS + SHADER_LIB + SHADER_MAIN;
RippleShader() {
super(SHADER, false);
}
- public void setShader(@NonNull Shader s) {
- setInputShader("in_shader", s);
+ public void setShader(Shader shader) {
+ if (shader != null) {
+ setInputShader("in_shader", shader);
+ }
+ setUniform("in_hasMask", shader == null ? 0 : 1);
}
public void setRadius(float radius) {
setUniform("in_maxRadius", radius);
}
+ /**
+ * Continuous offset used as noise phase.
+ */
+ public void setSecondsOffset(float t) {
+ setUniform("in_secondsOffset", t);
+ }
+
public void setOrigin(float x, float y) {
setUniform("in_origin", new float[] {x, y});
}
@@ -77,13 +172,16 @@ final class RippleShader extends RuntimeShader {
setUniform("in_progress", progress);
}
- public void setHasMask(boolean hasMask) {
- setUniform("in_hasMask", hasMask ? 1 : 0);
- }
-
+ /**
+ * Color of the circle that's under the sparkles. Sparkles will always be white.
+ */
public void setColor(@ColorInt int colorIn) {
Color color = Color.valueOf(colorIn);
this.setUniform("in_color", new float[] {color.red(),
color.green(), color.blue(), color.alpha()});
}
+
+ public void setResolution(float w, float h) {
+ setUniform("in_resolution", w, h);
+ }
}
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index ed789f03f9ba..55015696ff47 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -20,7 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
-import android.security.usermanager.IKeystoreUserManager;
+import android.security.maintenance.IKeystoreMaintenance;
import android.system.keystore2.Domain;
import android.system.keystore2.ResponseCode;
import android.util.Log;
@@ -34,9 +34,9 @@ public class AndroidKeyStoreMaintenance {
public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR;
- private static IKeystoreUserManager getService() {
- return IKeystoreUserManager.Stub.asInterface(
- ServiceManager.checkService("android.security.usermanager"));
+ private static IKeystoreMaintenance getService() {
+ return IKeystoreMaintenance.Stub.asInterface(
+ ServiceManager.checkService("android.security.maintenance"));
}
/**
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index f48da74eb397..cd77d9c2723f 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -22,7 +22,6 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
import android.os.Build;
-import android.security.KeyStore;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterCertificateChain;
import android.security.keymaster.KeymasterDefs;
@@ -32,9 +31,14 @@ import android.util.ArraySet;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.security.spec.ECGenParameterSpec;
import java.util.Collection;
+import java.util.Random;
import java.util.Set;
/**
@@ -223,22 +227,47 @@ public abstract class AttestationUtils {
@NonNull public static X509Certificate[] attestDeviceIds(Context context,
@NonNull int[] idTypes, @NonNull byte[] attestationChallenge) throws
DeviceIdAttestationException {
- final KeymasterArguments attestArgs = prepareAttestationArgumentsForDeviceId(
- context, idTypes, attestationChallenge);
-
- // Perform attestation.
- final KeymasterCertificateChain outChain = new KeymasterCertificateChain();
- final int errorCode = KeyStore.getInstance().attestDeviceIds(attestArgs, outChain);
- if (errorCode != KeyStore.NO_ERROR) {
- throw new DeviceIdAttestationException("Unable to perform attestation",
- KeyStore.getKeyStoreException(errorCode));
+ String keystoreAlias = generateRandomAlias();
+ KeyGenParameterSpec.Builder builder =
+ new KeyGenParameterSpec.Builder(keystoreAlias, KeyProperties.PURPOSE_SIGN)
+ .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
+ .setDigests(KeyProperties.DIGEST_SHA256)
+ .setAttestationChallenge(attestationChallenge);
+
+ if (idTypes != null) {
+ builder.setAttestationIds(idTypes);
+ builder.setDevicePropertiesAttestationIncluded(true);
}
try {
- return parseCertificateChain(outChain);
- } catch (KeyAttestationException e) {
- throw new DeviceIdAttestationException(e.getMessage(), e);
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
+ KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
+ keyPairGenerator.initialize(builder.build());
+ keyPairGenerator.generateKeyPair();
+
+ KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ keyStore.load(null);
+
+ X509Certificate[] certificateChain =
+ (X509Certificate[]) keyStore.getCertificateChain(keystoreAlias);
+
+ keyStore.deleteEntry(keystoreAlias);
+
+ return certificateChain;
+ } catch (Exception e) {
+ throw new DeviceIdAttestationException("Unable to perform attestation", e);
+ }
+ }
+
+ private static String generateRandomAlias() {
+ Random random = new SecureRandom();
+ StringBuilder builder = new StringBuilder();
+ // Pick random uppercase letters, A-Z. 20 of them gives us ~94 bits of entropy, which
+ // should prevent any conflicts with app-selected aliases, even for very unlucky users.
+ for (int i = 0; i < 20; ++i) {
+ builder.append(random.nextInt(26) + 'A');
}
+ return builder.toString();
}
/**
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 72735a787b7f..5cb2c3b41517 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -467,8 +467,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
*
* @return The numeric namespace as configured in the keystore2_key_contexts files of Android's
* SEPolicy.
- * TODO b/171806779 link to public Keystore 2.0 documentation.
- * See bug for more details for now.
+ * See <a href="https://source.android.com/security/keystore#access-control">
+ * Keystore 2.0 access control</a>
* @hide
*/
@SystemApi
@@ -1042,9 +1042,9 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
* keys between system and vendor components, e.g., WIFI settings and WPA supplicant.
*
* @param namespace Numeric SELinux namespace as configured in keystore2_key_contexts
- * of Android's SEPolicy.
- * TODO b/171806779 link to public Keystore 2.0 documentation.
- * See bug for more details for now.
+ * of Android's SEPolicy.
+ * See <a href="https://source.android.com/security/keystore#access-control">
+ * Keystore 2.0 access control</a>
* @return this Builder object.
*
* @hide
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index d36695b9b410..fa852e33a1d8 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -340,11 +340,11 @@ public class AndroidKeyStoreProvider extends Provider {
* @param keyStore The keystore2 backend.
* @param alias The alias of the key in the Keystore database.
* @param namespace The a Keystore namespace. This is used by system api only to request
- * Android system specific keystore namespace, which can be configured
- * in the device's SEPolicy. Third party apps and most system components
- * set this parameter to -1 to indicate their application specific namespace.
- * TODO b/171806779 link to public Keystore 2.0 documentation.
- * See bug for more details for now.
+ * Android system specific keystore namespace, which can be configured
+ * in the device's SEPolicy. Third party apps and most system components
+ * set this parameter to -1 to indicate their application specific namespace.
+ * See <a href="https://source.android.com/security/keystore#access-control">
+ * Keystore 2.0 access control</a>
* @hide
**/
@NonNull
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index 725f87d93e4e..580861cf4974 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -121,6 +121,19 @@ public class PhonePipMenuController implements PipMenuController {
}
};
+ private final float[] mTmpValues = new float[9];
+ private final Runnable mUpdateEmbeddedMatrix = () -> {
+ if (mPipMenuView == null || mPipMenuView.getViewRootImpl() == null) {
+ return;
+ }
+ mMoveTransform.getValues(mTmpValues);
+ try {
+ mPipMenuView.getViewRootImpl().getAccessibilityEmbeddedConnection()
+ .setScreenMatrix(mTmpValues);
+ } catch (RemoteException e) {
+ }
+ };
+
public PhonePipMenuController(Context context, PipMediaController mediaController,
SystemWindows systemWindows, ShellExecutor mainExecutor,
Handler mainHandler) {
@@ -306,6 +319,11 @@ public class PhonePipMenuController implements PipMenuController {
} else {
mApplier.scheduleApply(params);
}
+
+ if (mPipMenuView.getViewRootImpl() != null) {
+ mPipMenuView.getHandler().removeCallbacks(mUpdateEmbeddedMatrix);
+ mPipMenuView.getHandler().post(mUpdateEmbeddedMatrix);
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 0d64407f649f..8ab405bca7db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -32,7 +32,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
-import android.annotation.Nullable;
import android.app.PendingIntent.CanceledException;
import android.app.RemoteAction;
import android.content.ComponentName;
@@ -52,10 +51,8 @@ import android.util.Size;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
-import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewRootImpl;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
@@ -198,6 +195,11 @@ public class PipMenuView extends FrameLayout {
}
@Override
+ public boolean shouldDelayChildPressedState() {
+ return true;
+ }
+
+ @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (!mAllowTouches) {
return false;
@@ -287,18 +289,6 @@ public class PipMenuView extends FrameLayout {
}
}
- @Nullable SurfaceControl getWindowSurfaceControl() {
- final ViewRootImpl root = getViewRootImpl();
- if (root == null) {
- return null;
- }
- final SurfaceControl out = root.getSurfaceControl();
- if (out != null && out.isValid()) {
- return out;
- }
- return null;
- }
-
/**
* Different from {@link #hideMenu()}, this function does not try to finish this menu activity
* and instead, it fades out the controls by setting the alpha to 0 directly without menu
@@ -398,8 +388,20 @@ public class PipMenuView extends FrameLayout {
return true;
});
+ // Update the expand button only if it should show with the menu
+ expandContainer.setVisibility(mMenuState == MENU_STATE_FULL
+ ? View.VISIBLE
+ : View.INVISIBLE);
+
+ FrameLayout.LayoutParams expandedLp =
+ (FrameLayout.LayoutParams) expandContainer.getLayoutParams();
if (mActions.isEmpty() || mMenuState == MENU_STATE_CLOSE || mMenuState == MENU_STATE_NONE) {
actionsContainer.setVisibility(View.INVISIBLE);
+
+ // Update the expand container margin to adjust the center of the expand button to
+ // account for the existence of the action container
+ expandedLp.topMargin = 0;
+ expandedLp.bottomMargin = 0;
} else {
actionsContainer.setVisibility(View.VISIBLE);
if (mActionsGroup != null) {
@@ -455,14 +457,12 @@ public class PipMenuView extends FrameLayout {
// Update the expand container margin to adjust the center of the expand button to
// account for the existence of the action container
- FrameLayout.LayoutParams expandedLp =
- (FrameLayout.LayoutParams) expandContainer.getLayoutParams();
expandedLp.topMargin = getResources().getDimensionPixelSize(
R.dimen.pip_action_padding);
expandedLp.bottomMargin = getResources().getDimensionPixelSize(
R.dimen.pip_expand_container_edge_margin);
- expandContainer.requestLayout();
}
+ expandContainer.requestLayout();
}
private void notifyMenuStateChange(int menuState, boolean resize, Runnable callback) {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
index ecc066be734f..5a96a7c8cbd9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
@@ -17,7 +17,6 @@
package com.android.wm.shell.flicker.helpers
import android.app.Instrumentation
-import android.graphics.Point
import android.media.session.MediaController
import android.media.session.MediaSessionManager
import android.os.SystemClock
@@ -135,11 +134,8 @@ class PipAppHelper(instrumentation: Instrumentation) : BaseAppHelper(
expandPipWindow(wmHelper)
val exitPipObject = uiDevice.findObject(By.res(SYSTEMUI_PACKAGE, "dismiss"))
requireNotNull(exitPipObject) { "PIP window dismiss button not found" }
- val coordinatesInWindow = exitPipObject.visibleBounds
- val windowOffset = wmHelper.getWindowRegion(component).bounds
- val newCoordinates = Point(windowOffset.left + coordinatesInWindow.centerX(),
- windowOffset.top + coordinatesInWindow.centerY())
- uiDevice.click(newCoordinates.x, newCoordinates.y)
+ val dismissButtonBounds = exitPipObject.visibleBounds
+ uiDevice.click(dismissButtonBounds.centerX(), dismissButtonBounds.centerY())
}
// Wait for animation to complete.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index 83dca53b1542..2f08db1b7d0a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -107,7 +107,7 @@ class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) {
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
+ .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
repetitions = 5)
}
}
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index aba0f1b47673..63b831de5da1 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -97,8 +97,8 @@ cc_library {
"libincfs",
"libutils",
"libz",
- "libziparchive",
],
+ static_libs: ["libziparchive_for_incfs"],
static: {
enabled: false,
},
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index d663c52b2c08..607ef72df96a 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -388,11 +388,10 @@ cc_defaults {
"liblog",
"libminikin",
"libz",
- "libziparchive",
"libjpeg",
],
- static_libs: ["libnativehelper_lazy"],
+ static_libs: ["libnativehelper_lazy", "libziparchive_for_incfs"],
target: {
android: {
diff --git a/libs/hwui/utils/PaintUtils.h b/libs/hwui/utils/PaintUtils.h
index 09c6a4fdf50d..a8f2d9a28d67 100644
--- a/libs/hwui/utils/PaintUtils.h
+++ b/libs/hwui/utils/PaintUtils.h
@@ -52,18 +52,10 @@ public:
return mode == SkBlendMode::kSrcOver || mode == SkBlendMode::kSrc;
}
- static bool isBlendedShader(const SkShader* shader) {
- if (shader == nullptr) {
- return false;
- }
- return !shader->isOpaque();
- }
+ static bool isBlendedShader(const SkShader* shader) { return shader && !shader->isOpaque(); }
static bool isBlendedColorFilter(const SkColorFilter* filter) {
- if (filter == nullptr) {
- return false;
- }
- return (filter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) == 0;
+ return filter && !filter->isAlphaUnchanged();
}
static inline SkBlendMode getBlendModeDirect(const SkPaint* paint) {
diff --git a/media/Android.bp b/media/Android.bp
index 9268b22a929a..a66236e6f4ea 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -27,6 +27,9 @@ aidl_interface {
aidl_interface {
name: "media_permission-aidl",
unstable: true,
+ host_supported: true,
+ vendor_available: true,
+ double_loadable: true,
local_include_dir: "aidl",
srcs: [
"aidl/android/media/permission/Identity.aidl",
diff --git a/media/aidl/android/media/permission/Identity.aidl b/media/aidl/android/media/permission/Identity.aidl
index 361497d59ea9..36389047cee8 100644
--- a/media/aidl/android/media/permission/Identity.aidl
+++ b/media/aidl/android/media/permission/Identity.aidl
@@ -22,11 +22,11 @@ package android.media.permission;
*/
parcelable Identity {
/** Linux user ID. */
- int uid;
+ int uid = -1;
/** Linux process ID. */
- int pid;
+ int pid = -1;
/** Package name. If null, the first package owned by the given uid will be assumed. */
- @nullable String packageName;
+ @nullable @utf8InCpp String packageName;
/** Attribution tag. Mostly used for diagnostic purposes. */
- @nullable String attributionTag;
+ @nullable @utf8InCpp String attributionTag;
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 1cef0922a48e..e8e263147c6e 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -6729,7 +6729,7 @@ public class AudioManager {
*/
public Map<Integer, Boolean> getSurroundFormats() {
Map<Integer, Boolean> surroundFormats = new HashMap<>();
- int status = AudioSystem.getSurroundFormats(surroundFormats, false);
+ int status = AudioSystem.getSurroundFormats(surroundFormats);
if (status != AudioManager.SUCCESS) {
// fail and bail!
Log.e(TAG, "getSurroundFormats failed:" + status);
@@ -6762,20 +6762,17 @@ public class AudioManager {
/**
* @hide
* Returns all surround formats that are reported by the connected HDMI device.
- * The keys are not affected by calling setSurroundFormatEnabled(), and the values
- * are not affected by calling setSurroundFormatEnabled() when in AUTO mode.
- * This information can used to show the AUTO setting for SurroundSound.
+ * The return values are not affected by calling setSurroundFormatEnabled.
*
- * @return a map where the key is a surround format and
- * the value indicates the surround format is enabled or not
+ * @return a list of surround formats
*/
- public Map<Integer, Boolean> getReportedSurroundFormats() {
- Map<Integer, Boolean> reportedSurroundFormats = new HashMap<>();
- int status = AudioSystem.getSurroundFormats(reportedSurroundFormats, true);
+ public ArrayList<Integer> getReportedSurroundFormats() {
+ ArrayList<Integer> reportedSurroundFormats = new ArrayList<>();
+ int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats);
if (status != AudioManager.SUCCESS) {
// fail and bail!
Log.e(TAG, "getReportedSurroundFormats failed:" + status);
- return new HashMap<Integer, Boolean>(); // Always return a map.
+ return new ArrayList<Integer>(); // Always return a list.
}
return reportedSurroundFormats;
}
@@ -7087,26 +7084,22 @@ public class AudioManager {
* <pre class="prettyprint">
* // Get an AudioManager instance
* AudioManager audioManager = Context.getSystemService(AudioManager.class);
- * try {
- * AudioDeviceInfo speakerDevice = null;
- * List<AudioDeviceInfo> devices = audioManager.getAvailableCommunicationDevices();
- * for (AudioDeviceInfo device : devices) {
- * if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
- * speakerDevice = device;
- * break;
- * }
+ * AudioDeviceInfo speakerDevice = null;
+ * List<AudioDeviceInfo> devices = audioManager.getAvailableCommunicationDevices();
+ * for (AudioDeviceInfo device : devices) {
+ * if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
+ * speakerDevice = device;
+ * break;
* }
- * if (speakerDevice != null) {
- * // Turn speakerphone ON.
- * boolean result = audioManager.setCommunicationDevice(speakerDevice);
- * if (!result) {
- * // Handle error.
- * }
- * // Turn speakerphone OFF.
- * audioManager.clearCommunicationDevice();
+ * }
+ * if (speakerDevice != null) {
+ * // Turn speakerphone ON.
+ * boolean result = audioManager.setCommunicationDevice(speakerDevice);
+ * if (!result) {
+ * // Handle error.
* }
- * } catch (IllegalArgumentException e) {
- * // Handle exception.
+ * // Turn speakerphone OFF.
+ * audioManager.clearCommunicationDevice();
* }
* </pre>
* @param device the requested audio device.
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index bf04b660425b..d7112d6dfa63 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -16,6 +16,8 @@
package android.media;
+import static android.media.permission.PermissionUtil.myIdentity;
+
import android.annotation.CallbackExecutor;
import android.annotation.FloatRange;
import android.annotation.IntDef;
@@ -26,9 +28,11 @@ import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
import android.media.MediaRecorder.Source;
import android.media.audiopolicy.AudioMix;
import android.media.audiopolicy.AudioPolicy;
+import android.media.permission.Identity;
import android.media.projection.MediaProjection;
import android.os.Binder;
import android.os.Build;
@@ -54,6 +58,7 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -352,6 +357,32 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
@RequiresPermission(android.Manifest.permission.RECORD_AUDIO)
public AudioRecord(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
int sessionId) throws IllegalArgumentException {
+ this(attributes, format, bufferSizeInBytes, sessionId, ActivityThread.currentApplication());
+ }
+
+ /**
+ * @hide
+ * Class constructor with {@link AudioAttributes} and {@link AudioFormat}.
+ * @param attributes a non-null {@link AudioAttributes} instance. Use
+ * {@link AudioAttributes.Builder#setCapturePreset(int)} for configuring the audio
+ * source for this instance.
+ * @param format a non-null {@link AudioFormat} instance describing the format of the data
+ * that will be recorded through this AudioRecord. See {@link AudioFormat.Builder} for
+ * configuring the audio format parameters such as encoding, channel mask and sample rate.
+ * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is written
+ * to during the recording. New audio data can be read from this buffer in smaller chunks
+ * than this size. See {@link #getMinBufferSize(int, int, int)} to determine the minimum
+ * required buffer size for the successful creation of an AudioRecord instance. Using values
+ * smaller than getMinBufferSize() will result in an initialization failure.
+ * @param sessionId ID of audio session the AudioRecord must be attached to, or
+ * {@link AudioManager#AUDIO_SESSION_ID_GENERATE} if the session isn't known at construction
+ * time. See also {@link AudioManager#generateAudioSessionId()} to obtain a session ID before
+ * construction.
+ * @param context An optional context to pull an attribution tag from.
+ * @throws IllegalArgumentException
+ */
+ private AudioRecord(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
+ int sessionId, @Nullable Context context) throws IllegalArgumentException {
mRecordingState = RECORDSTATE_STOPPED;
if (attributes == null) {
@@ -414,15 +445,21 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
audioBuffSizeCheck(bufferSizeInBytes);
+ Identity identity = myIdentity(context);
+ if (identity.packageName == null) {
+ // Command line utility
+ identity.packageName = "uid:" + Binder.getCallingUid();
+ }
+
int[] sampleRate = new int[] {mSampleRate};
int[] session = new int[1];
session[0] = sessionId;
//TODO: update native initialization when information about hardware init failure
// due to capture device already open is available.
- int initResult = native_setup( new WeakReference<AudioRecord>(this),
+ int initResult = native_setup(new WeakReference<AudioRecord>(this),
mAudioAttributes, sampleRate, mChannelMask, mChannelIndexMask,
mAudioFormat, mNativeBufferSizeInBytes,
- session, getCurrentOpPackageName(), 0 /*nativeRecordInJavaObj*/);
+ session, identity, 0 /*nativeRecordInJavaObj*/);
if (initResult != SUCCESS) {
loge("Error code "+initResult+" when initializing native AudioRecord object.");
return; // with mState == STATE_UNINITIALIZED
@@ -434,15 +471,6 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
mState = STATE_INITIALIZED;
}
- private String getCurrentOpPackageName() {
- String opPackageName = ActivityThread.currentOpPackageName();
- if (opPackageName != null) {
- return opPackageName;
- }
- // Command line utility
- return "uid:" + Binder.getCallingUid();
- }
-
/**
* A constructor which explicitly connects a Native (C++) AudioRecord. For use by
* the AudioRecordRoutingProxy subclass.
@@ -492,7 +520,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
0 /*mAudioFormat*/,
0 /*mNativeBufferSizeInBytes*/,
session,
- ActivityThread.currentOpPackageName(),
+ myIdentity(null),
nativeRecordInJavaObj);
if (initResult != SUCCESS) {
loge("Error code "+initResult+" when initializing native AudioRecord object.");
@@ -548,6 +576,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
private AudioPlaybackCaptureConfiguration mAudioPlaybackCaptureConfiguration;
private AudioAttributes mAttributes;
private AudioFormat mFormat;
+ private Context mContext;
private int mBufferSizeInBytes;
private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
private int mPrivacySensitive = PRIVACY_SENSITIVE_DEFAULT;
@@ -583,6 +612,18 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
}
/**
+ * Sets the context the record belongs to.
+ * @param context a non-null {@link Context} instance
+ * @return the same Builder instance.
+ */
+ public @NonNull Builder setContext(@NonNull Context context) {
+ Objects.requireNonNull(context);
+ // keep reference, we only copy the data when building
+ mContext = context;
+ return this;
+ }
+
+ /**
* @hide
* To be only used by system components. Allows specifying non-public capture presets
* @param attributes a non-null {@link AudioAttributes} instance that contains the capture
@@ -793,7 +834,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
* mFormat.getBytesPerSample(mFormat.getEncoding());
}
final AudioRecord record = new AudioRecord(
- mAttributes, mFormat, mBufferSizeInBytes, mSessionId);
+ mAttributes, mFormat, mBufferSizeInBytes, mSessionId, mContext);
if (record.getState() == STATE_UNINITIALIZED) {
// release is not necessary
throw new UnsupportedOperationException("Cannot create AudioRecord");
@@ -2035,15 +2076,32 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
// Native methods called from the Java side
//--------------------
- @UnsupportedAppUsage
- private native final int native_setup(Object audiorecord_this,
+ /**
+ * @deprecated Use native_setup that takes an Identity object
+ * @return
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
+ publicAlternatives = "{@code AudioRecord.Builder}")
+ @Deprecated
+ private int native_setup(Object audiorecordThis,
Object /*AudioAttributes*/ attributes,
int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
int buffSizeInBytes, int[] sessionId, String opPackageName,
- long nativeRecordInJavaObj);
+ long nativeRecordInJavaObj) {
+ Identity identity = myIdentity(null);
+ identity.packageName = opPackageName;
+
+ return native_setup(audiorecordThis, attributes, sampleRate, channelMask, channelIndexMask,
+ audioFormat, buffSizeInBytes, sessionId, identity, nativeRecordInJavaObj);
+ }
+
+ private native int native_setup(Object audiorecordThis,
+ Object /*AudioAttributes*/ attributes,
+ int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
+ int buffSizeInBytes, int[] sessionId, Identity identity, long nativeRecordInJavaObj);
// TODO remove: implementation calls directly into implementation of native_release()
- private native final void native_finalize();
+ private native void native_finalize();
/**
* @hide
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index f1f6cb1f42be..8134d6f8352d 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -1699,8 +1699,10 @@ public class AudioSystem
public static native int getMicrophones(ArrayList<MicrophoneInfo> microphonesInfo);
/** @hide */
- public static native int getSurroundFormats(Map<Integer, Boolean> surroundFormats,
- boolean reported);
+ public static native int getSurroundFormats(Map<Integer, Boolean> surroundFormats);
+
+ /** @hide */
+ public static native int getReportedSurroundFormats(ArrayList<Integer> surroundFormats);
/**
* @hide
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 9176dae8609f..3de78bb9ef9f 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -18,6 +18,7 @@ package android.media;
import static android.Manifest.permission.BIND_IMS_SERVICE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.media.permission.PermissionUtil.myIdentity;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
@@ -34,6 +35,7 @@ import android.content.res.AssetFileDescriptor;
import android.graphics.SurfaceTexture;
import android.media.SubtitleController.Anchor;
import android.media.SubtitleTrack.RenderingWidget;
+import android.media.permission.Identity;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -53,6 +55,7 @@ import android.provider.Settings;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
@@ -684,11 +687,14 @@ public class MediaPlayer extends PlayerBase
mTimeProvider = new TimeProvider(this);
mOpenSubtitleSources = new Vector<InputStream>();
+ Identity identity = myIdentity(null);
+ // set the package name to empty if it was null
+ identity.packageName = TextUtils.emptyIfNull(identity.packageName);
+
/* Native setup requires a weak reference to our object.
* It's easier to create it here than in C++.
*/
- native_setup(new WeakReference<MediaPlayer>(this),
- getCurrentOpPackageName());
+ native_setup(new WeakReference<MediaPlayer>(this), identity);
baseRegisterPlayer(sessionId);
}
@@ -2471,7 +2477,7 @@ public class MediaPlayer extends PlayerBase
private native final int native_setMetadataFilter(Parcel request);
private static native final void native_init();
- private native void native_setup(Object mediaplayerThis, @NonNull String opPackageName);
+ private native void native_setup(Object mediaplayerThis, @NonNull Identity identity);
private native final void native_finalize();
/**
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 49a4cc6239bb..87e1e5bdb9ce 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -16,6 +16,8 @@
package android.media;
+import static android.media.permission.PermissionUtil.myIdentity;
+
import android.annotation.CallbackExecutor;
import android.annotation.FloatRange;
import android.annotation.IntDef;
@@ -25,7 +27,9 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
import android.hardware.Camera;
+import android.media.permission.Identity;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -48,6 +52,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -127,9 +132,21 @@ public class MediaRecorder implements AudioRouting,
/**
* Default constructor.
+ *
+ * @deprecated Use {@link #MediaRecorder(Context)} instead
*/
+ @Deprecated
public MediaRecorder() {
+ this(ActivityThread.currentApplication());
+ }
+ /**
+ * Default constructor.
+ *
+ * @param context Context the recorder belongs to
+ */
+ public MediaRecorder(@NonNull Context context) {
+ Objects.requireNonNull(context);
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
@@ -140,12 +157,11 @@ public class MediaRecorder implements AudioRouting,
}
mChannelCount = 1;
- String packageName = ActivityThread.currentPackageName();
/* Native setup requires a weak reference to our object.
* It's easier to create it here than in C++.
*/
- native_setup(new WeakReference<MediaRecorder>(this), packageName,
- ActivityThread.currentOpPackageName());
+ native_setup(new WeakReference<MediaRecorder>(this),
+ ActivityThread.currentPackageName(), myIdentity(context));
}
/**
@@ -1740,12 +1756,22 @@ public class MediaRecorder implements AudioRouting,
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private static native final void native_init();
- @UnsupportedAppUsage
- private native final void native_setup(Object mediarecorder_this,
- String clientName, String opPackageName) throws IllegalStateException;
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
+ publicAlternatives = "{@link MediaRecorder}")
+ private void native_setup(Object mediarecorderThis,
+ String clientName, String opPackageName) throws IllegalStateException {
+ Identity identity = myIdentity(null);
+ identity.packageName = opPackageName;
+
+ native_setup(mediarecorderThis, clientName, identity);
+ }
+
+ private native void native_setup(Object mediarecorderThis,
+ String clientName, Identity identity)
+ throws IllegalStateException;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private native final void native_finalize();
+ private native void native_finalize();
@UnsupportedAppUsage
private native void setParameter(String nameValuePair);
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index dc9c58ebf18c..b4db3055e58c 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -60,6 +60,7 @@ import java.util.stream.Collectors;
public final class MediaRouter2 {
private static final String TAG = "MR2";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final Object sSystemRouterLock = new Object();
private static final Object sRouterLock = new Object();
// The maximum time for the old routing controller available after transfer.
@@ -67,8 +68,8 @@ public final class MediaRouter2 {
// The manager request ID representing that no manager is involved.
private static final long MANAGER_REQUEST_ID_NONE = MediaRoute2ProviderService.REQUEST_ID_NONE;
- @GuardedBy("sRouterLock")
- private static Map<String, MediaRouter2> sMediaRouter2Map = new ArrayMap<>();
+ @GuardedBy("sSystemRouterLock")
+ private static Map<String, MediaRouter2> sSystemMediaRouter2Map = new ArrayMap<>();
private static MediaRouter2Manager sManager;
@GuardedBy("sRouterLock")
@@ -76,6 +77,7 @@ public final class MediaRouter2 {
private final Context mContext;
private final IMediaRouterService mMediaRouterService;
+ private final Object mLock = new Object();
private final CopyOnWriteArrayList<RouteCallbackRecord> mRouteCallbackRecords =
new CopyOnWriteArrayList<>();
@@ -88,27 +90,29 @@ public final class MediaRouter2 {
new CopyOnWriteArrayList<>();
private final String mClientPackageName;
+ private final ManagerCallback mManagerCallback;
+
private final String mPackageName;
- @GuardedBy("sRouterLock")
+ @GuardedBy("mLock")
final Map<String, MediaRoute2Info> mRoutes = new ArrayMap<>();
final RoutingController mSystemController;
- @GuardedBy("sRouterLock")
+ @GuardedBy("mLock")
private RouteDiscoveryPreference mDiscoveryPreference = RouteDiscoveryPreference.EMPTY;
// TODO: Make MediaRouter2 is always connected to the MediaRouterService.
- @GuardedBy("sRouterLock")
+ @GuardedBy("mLock")
MediaRouter2Stub mStub;
- @GuardedBy("sRouterLock")
+ @GuardedBy("mLock")
private final Map<String, RoutingController> mNonSystemRoutingControllers = new ArrayMap<>();
private final AtomicInteger mNextRequestId = new AtomicInteger(1);
final Handler mHandler;
- @GuardedBy("sRouterLock")
+ @GuardedBy("mLock")
private boolean mShouldUpdateRoutes = true;
private volatile List<MediaRoute2Info> mFilteredRoutes = Collections.emptyList();
private volatile OnGetControllerHintsListener mOnGetControllerHintsListener;
@@ -130,6 +134,11 @@ public final class MediaRouter2 {
/**
* Gets an instance of the media router which controls the app's media routing.
* Returns {@code null} if the given package name is invalid.
+ * <p>
+ * Note: For media routers created with this method, the discovery preference passed to
+ * {@link #registerRouteCallback} will have no effect. The callback will be called accordingly
+ * with the client app's discovery preference. Therefore, it is recommended to pass
+ * {@link RouteDiscoveryPreference#EMPTY} there.
*
* @param clientPackageName the package name of the app to control
* @hide
@@ -149,15 +158,17 @@ public final class MediaRouter2 {
return null;
}
- synchronized (sRouterLock) {
- MediaRouter2 instance = sMediaRouter2Map.get(clientPackageName);
+ synchronized (sSystemRouterLock) {
+ MediaRouter2 instance = sSystemMediaRouter2Map.get(clientPackageName);
if (instance == null) {
// TODO: Add permission check here using MODIFY_AUDIO_ROUTING.
if (sManager == null) {
sManager = MediaRouter2Manager.getInstance(context.getApplicationContext());
}
instance = new MediaRouter2(context, clientPackageName);
- sMediaRouter2Map.put(clientPackageName, instance);
+ sSystemMediaRouter2Map.put(clientPackageName, instance);
+ // TODO: Remove router instance once it is not needed.
+ instance.registerManagerCallback();
}
return instance;
}
@@ -192,11 +203,14 @@ public final class MediaRouter2 {
}
mSystemController = new SystemRoutingController(currentSystemSessionInfo);
+ // Only used by system MediaRouter2.
mClientPackageName = null;
+ mManagerCallback = null;
}
private MediaRouter2(Context context, String clientPackageName) {
mClientPackageName = clientPackageName;
+ mManagerCallback = new ManagerCallback();
mContext = context;
mMediaRouterService = null;
mPackageName = null;
@@ -220,8 +234,8 @@ public final class MediaRouter2 {
}
/**
- * Gets the target package name of the app which this media router controls.
- * This is only non-null when the router instance is created with the target package name.
+ * Gets the client package name of the app which this media router controls.
+ * This is only non-null when the router instance is created with the client package name.
*
* @see #getInstance(Context, String)
* @hide
@@ -245,6 +259,9 @@ public final class MediaRouter2 {
Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(routeCallback, "callback must not be null");
Objects.requireNonNull(preference, "preference must not be null");
+ if (isSystemRouter()) {
+ preference = RouteDiscoveryPreference.EMPTY;
+ }
RouteCallbackRecord record = new RouteCallbackRecord(executor, routeCallback, preference);
@@ -253,7 +270,11 @@ public final class MediaRouter2 {
// is happening but it's okay because either this or the other registration should be done.
mRouteCallbackRecords.addIfAbsent(record);
- synchronized (sRouterLock) {
+ if (isSystemRouter()) {
+ return;
+ }
+
+ synchronized (mLock) {
if (mStub == null) {
MediaRouter2Stub stub = new MediaRouter2Stub();
try {
@@ -289,7 +310,11 @@ public final class MediaRouter2 {
return;
}
- synchronized (sRouterLock) {
+ if (isSystemRouter()) {
+ return;
+ }
+
+ synchronized (mLock) {
if (mStub == null) {
return;
}
@@ -326,22 +351,37 @@ public final class MediaRouter2 {
}
/**
+ * Gets the list of all discovered routes.
+ * This list includes the routes that are not related to the client app.
+ * <p>
+ * This will return an empty list for non-system media routers.
+ *
+ * @hide
+ */
+ //@SystemApi
+ public List<MediaRoute2Info> getAllRoutes() {
+ if (isSystemRouter()) {
+ return sManager.getAllRoutes();
+ }
+ return Collections.emptyList();
+ }
+
+ /**
* Gets the unmodifiable list of {@link MediaRoute2Info routes} currently
* known to the media router.
* <p>
* Please note that the list can be changed before callbacks are invoked.
* </p>
- *
* @return the list of routes that contains at least one of the route features in discovery
* preferences registered by the application
*/
@NonNull
public List<MediaRoute2Info> getRoutes() {
- if (mClientPackageName != null) {
+ if (isSystemRouter()) {
return sManager.getAvailableRoutes(mClientPackageName);
}
- synchronized (sRouterLock) {
+ synchronized (mLock) {
if (mShouldUpdateRoutes) {
mShouldUpdateRoutes = false;
@@ -449,7 +489,7 @@ public final class MediaRouter2 {
* @see TransferCallback#onTransferFailure
*/
public void transferTo(@NonNull MediaRoute2Info route) {
- if (mClientPackageName != null) {
+ if (isSystemRouter()) {
sManager.selectRoute(mClientPackageName, route);
return;
}
@@ -464,7 +504,7 @@ public final class MediaRouter2 {
* controls the media routing, this method is a no-op.
*/
public void stop() {
- if (mClientPackageName != null) {
+ if (isSystemRouter()) {
List<RoutingSessionInfo> sessionInfos = sManager.getRoutingSessions(mClientPackageName);
RoutingSessionInfo sessionToRelease = sessionInfos.get(sessionInfos.size() - 1);
sManager.releaseSession(sessionToRelease);
@@ -481,7 +521,7 @@ public final class MediaRouter2 {
*/
//@SystemApi
public void transfer(@NonNull RoutingController controller, @NonNull MediaRoute2Info route) {
- if (mClientPackageName != null) {
+ if (isSystemRouter()) {
sManager.transfer(controller.getRoutingSessionInfo(), route);
return;
}
@@ -490,7 +530,7 @@ public final class MediaRouter2 {
Objects.requireNonNull(route, "route must not be null");
boolean routeFound;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
// TODO: Check thread-safety
routeFound = mRoutes.containsKey(route.getId());
}
@@ -526,7 +566,7 @@ public final class MediaRouter2 {
}
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -576,7 +616,7 @@ public final class MediaRouter2 {
public List<RoutingController> getControllers() {
// TODO: Do not create the controller instances every time,
// Instead, update the list using the sessions' ID and session related callbacks.
- if (mClientPackageName != null) {
+ if (isSystemRouter()) {
return sManager.getRoutingSessions(mClientPackageName).stream()
.map(info -> new RoutingController(info))
.collect(Collectors.toList());
@@ -584,7 +624,7 @@ public final class MediaRouter2 {
List<RoutingController> result = new ArrayList<>();
result.add(0, mSystemController);
- synchronized (sRouterLock) {
+ synchronized (mLock) {
result.addAll(mNonSystemRoutingControllers.values());
}
return result;
@@ -603,7 +643,7 @@ public final class MediaRouter2 {
Objects.requireNonNull(route, "route must not be null");
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -627,7 +667,7 @@ public final class MediaRouter2 {
List<MediaRoute2Info> removedRoutes = new ArrayList<>();
List<MediaRoute2Info> changedRoutes = new ArrayList<>();
- synchronized (sRouterLock) {
+ synchronized (mLock) {
List<String> currentRoutesIds = currentRoutes.stream().map(MediaRoute2Info::getId)
.collect(Collectors.toList());
@@ -685,7 +725,7 @@ public final class MediaRouter2 {
void addRoutesOnHandler(List<MediaRoute2Info> routes) {
List<MediaRoute2Info> addedRoutes = new ArrayList<>();
- synchronized (sRouterLock) {
+ synchronized (mLock) {
for (MediaRoute2Info route : routes) {
mRoutes.put(route.getId(), route);
if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
@@ -701,7 +741,7 @@ public final class MediaRouter2 {
void removeRoutesOnHandler(List<MediaRoute2Info> routes) {
List<MediaRoute2Info> removedRoutes = new ArrayList<>();
- synchronized (sRouterLock) {
+ synchronized (mLock) {
for (MediaRoute2Info route : routes) {
mRoutes.remove(route.getId());
if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
@@ -717,7 +757,7 @@ public final class MediaRouter2 {
void changeRoutesOnHandler(List<MediaRoute2Info> routes) {
List<MediaRoute2Info> changedRoutes = new ArrayList<>();
- synchronized (sRouterLock) {
+ synchronized (mLock) {
for (MediaRoute2Info route : routes) {
mRoutes.put(route.getId(), route);
if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
@@ -789,7 +829,7 @@ public final class MediaRouter2 {
newController.setRoutingSessionInfo(sessionInfo);
} else {
newController = new RoutingController(sessionInfo);
- synchronized (sRouterLock) {
+ synchronized (mLock) {
mNonSystemRoutingControllers.put(newController.getId(), newController);
}
}
@@ -812,7 +852,7 @@ public final class MediaRouter2 {
}
RoutingController matchingController;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
matchingController = mNonSystemRoutingControllers.get(sessionInfo.getId());
}
@@ -840,7 +880,7 @@ public final class MediaRouter2 {
}
RoutingController matchingController;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
matchingController = mNonSystemRoutingControllers.get(sessionInfo.getId());
}
@@ -868,7 +908,7 @@ public final class MediaRouter2 {
if (oldSession.isSystemSession()) {
controller = getSystemController();
} else {
- synchronized (sRouterLock) {
+ synchronized (mLock) {
controller = mNonSystemRoutingControllers.get(oldSession.getId());
}
}
@@ -878,6 +918,22 @@ public final class MediaRouter2 {
requestCreateController(controller, route, managerRequestId);
}
+ /**
+ * Returns whether this router is created with {@link #getInstance(Context, String)}.
+ * This kind of router can control the target app's media routing.
+ */
+ private boolean isSystemRouter() {
+ return mClientPackageName != null;
+ }
+
+ /**
+ * Registers {@link MediaRouter2Manager.Callback} for getting events.
+ */
+ private void registerManagerCallback() {
+ // Using direct executor here, since MediaRouter2Manager also posts to the main handler.
+ sManager.registerCallback(Runnable::run, mManagerCallback);
+ }
+
private List<MediaRoute2Info> filterRoutes(List<MediaRoute2Info> routes,
RouteDiscoveryPreference discoveryRequest) {
return routes.stream()
@@ -1236,7 +1292,7 @@ public final class MediaRouter2 {
}
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -1283,7 +1339,7 @@ public final class MediaRouter2 {
}
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -1318,7 +1374,7 @@ public final class MediaRouter2 {
}
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -1352,7 +1408,7 @@ public final class MediaRouter2 {
return;
}
MediaRouter2Stub stub;
- synchronized (sRouterLock) {
+ synchronized (mLock) {
stub = mStub;
}
if (stub != null) {
@@ -1386,7 +1442,7 @@ public final class MediaRouter2 {
mState = CONTROLLER_STATE_RELEASING;
}
- synchronized (sRouterLock) {
+ synchronized (mLock) {
// It could happen if the controller is released by the another thread
// in between two locks
if (!mNonSystemRoutingControllers.remove(getId(), this)) {
@@ -1415,7 +1471,7 @@ public final class MediaRouter2 {
mState = CONTROLLER_STATE_RELEASED;
}
- synchronized (sRouterLock) {
+ synchronized (mLock) {
mNonSystemRoutingControllers.remove(getId(), this);
if (shouldReleaseSession && mStub != null) {
@@ -1483,7 +1539,7 @@ public final class MediaRouter2 {
}
private List<MediaRoute2Info> getRoutesWithIds(List<String> routeIds) {
- synchronized (sRouterLock) {
+ synchronized (mLock) {
return routeIds.stream().map(mRoutes::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
@@ -1665,4 +1721,79 @@ public final class MediaRouter2 {
MediaRouter2.this, oldSession, route, managerRequestId));
}
}
+
+ class ManagerCallback implements MediaRouter2Manager.Callback {
+
+ @Override
+ public void onRoutesAdded(@NonNull List<MediaRoute2Info> routes) {
+ List<MediaRoute2Info> filteredRoutes =
+ sManager.filterRoutesForPackage(routes, mClientPackageName);
+ if (filteredRoutes.isEmpty()) {
+ return;
+ }
+ for (RouteCallbackRecord record: mRouteCallbackRecords) {
+ record.mExecutor.execute(
+ () -> record.mRouteCallback.onRoutesAdded(filteredRoutes));
+ }
+ }
+
+ @Override
+ public void onRoutesRemoved(@NonNull List<MediaRoute2Info> routes) {
+ List<MediaRoute2Info> filteredRoutes =
+ sManager.filterRoutesForPackage(routes, mClientPackageName);
+ if (filteredRoutes.isEmpty()) {
+ return;
+ }
+ for (RouteCallbackRecord record: mRouteCallbackRecords) {
+ record.mExecutor.execute(
+ () -> record.mRouteCallback.onRoutesRemoved(filteredRoutes));
+ }
+ }
+
+ @Override
+ public void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {
+ List<MediaRoute2Info> filteredRoutes =
+ sManager.filterRoutesForPackage(routes, mClientPackageName);
+ if (filteredRoutes.isEmpty()) {
+ return;
+ }
+ for (RouteCallbackRecord record: mRouteCallbackRecords) {
+ record.mExecutor.execute(
+ () -> record.mRouteCallback.onRoutesChanged(filteredRoutes));
+ }
+ }
+
+ @Override
+ public void onSessionUpdated(@NonNull RoutingSessionInfo session) {
+ // TODO: Call ControllerCallback.onControllerUpdated
+ }
+
+ @Override
+ public void onTransferred(@NonNull RoutingSessionInfo oldSession,
+ @Nullable RoutingSessionInfo newSession) {
+ // TODO: Call TransferCallback.onTransfer
+ }
+
+ @Override
+ public void onTransferFailed(@NonNull RoutingSessionInfo session,
+ @NonNull MediaRoute2Info route) {
+ // TODO: Call TransferCallback.onTransferFailure
+ }
+
+ @Override
+ public void onSessionReleased(@NonNull RoutingSessionInfo session) {
+ // TODO: Call TransferCallback.onStop()
+ }
+
+ @Override
+ public void onPreferredFeaturesChanged(@NonNull String packageName,
+ @NonNull List<String> preferredFeatures) {
+ // Does nothing.
+ }
+
+ @Override
+ public void onRequestFailed(int reason) {
+ // Does nothing.
+ }
+ }
}
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 5e732f9be68f..ca619d4072c3 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -237,6 +237,36 @@ public final class MediaRouter2Manager {
}
/**
+ * Returns a list of routes which are related to the given package name in the given route list.
+ */
+ @NonNull
+ public List<MediaRoute2Info> filterRoutesForPackage(@NonNull List<MediaRoute2Info> routes,
+ @NonNull String packageName) {
+ Objects.requireNonNull(routes, "routes must not be null");
+ Objects.requireNonNull(packageName, "packageName must not be null");
+
+ List<RoutingSessionInfo> sessions = getRoutingSessions(packageName);
+ RoutingSessionInfo sessionInfo = sessions.get(sessions.size() - 1);
+
+ List<MediaRoute2Info> result = new ArrayList<>();
+ List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
+ if (preferredFeatures == null) {
+ preferredFeatures = Collections.emptyList();
+ }
+
+ synchronized (mRoutesLock) {
+ for (MediaRoute2Info route : routes) {
+ if (route.hasAnyFeatures(preferredFeatures)
+ || sessionInfo.getSelectedRoutes().contains(route.getId())
+ || sessionInfo.getTransferableRoutes().contains(route.getId())) {
+ result.add(route);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
* Gets the system routing session associated with no specific application.
*/
@NonNull
diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java
index 67a4a4b1f851..fd3c4057ad21 100644
--- a/media/java/android/media/audiofx/AudioEffect.java
+++ b/media/java/android/media/audiofx/AudioEffect.java
@@ -16,6 +16,8 @@
package android.media.audiofx;
+import static android.media.permission.PermissionUtil.myIdentity;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -23,11 +25,11 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.TestApi;
-import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioSystem;
+import android.media.permission.Identity;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -515,10 +517,11 @@ public class AudioEffect {
}
// native initialization
+ // TODO b/182469354: Make consistent with AudioRecord
int initResult = native_setup(new WeakReference<AudioEffect>(this),
type.toString(), uuid.toString(), priority, audioSession,
deviceType, deviceAddress,
- id, desc, ActivityThread.currentOpPackageName(), probe);
+ id, desc, myIdentity(null), probe);
if (initResult != SUCCESS && initResult != ALREADY_EXISTS) {
Log.e(TAG, "Error code " + initResult
+ " when initializing AudioEffect.");
@@ -1385,7 +1388,7 @@ public class AudioEffect {
private native final int native_setup(Object audioeffect_this, String type,
String uuid, int priority, int audioSession,
int deviceType, String deviceAddress, int[] id, Object[] desc,
- String opPackageName, boolean probe);
+ Identity identity, boolean probe);
private native final void native_finalize();
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index a5da648cf14a..58c9e650bb90 100644
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -16,8 +16,10 @@
package android.media.audiofx;
-import android.app.ActivityThread;
+import static android.media.permission.PermissionUtil.myIdentity;
+
import android.compat.annotation.UnsupportedAppUsage;
+import android.media.permission.Identity;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
@@ -217,9 +219,11 @@ public class Visualizer {
synchronized (mStateLock) {
mState = STATE_UNINITIALIZED;
+
// native initialization
+ // TODO b/182469354: make consistent with AudioRecord
int result = native_setup(new WeakReference<Visualizer>(this), audioSession, id,
- ActivityThread.currentOpPackageName());
+ myIdentity(null));
if (result != SUCCESS && result != ALREADY_EXISTS) {
Log.e(TAG, "Error code "+result+" when initializing Visualizer.");
switch (result) {
@@ -686,7 +690,7 @@ public class Visualizer {
private native final int native_setup(Object audioeffect_this,
int audioSession,
int[] id,
- String opPackageName);
+ Identity identity);
@GuardedBy("mStateLock")
private native final void native_finalize();
diff --git a/media/java/android/media/metrics/NetworkEvent.java b/media/java/android/media/metrics/NetworkEvent.java
index 098885cc9bdd..186606825104 100644
--- a/media/java/android/media/metrics/NetworkEvent.java
+++ b/media/java/android/media/metrics/NetworkEvent.java
@@ -113,10 +113,11 @@ public final class NetworkEvent extends Event implements Parcelable {
*
* @hide
*/
- public NetworkEvent(@NetworkType int type, long timeSinceCreatedMillis, Bundle extras) {
+ public NetworkEvent(@NetworkType int type, long timeSinceCreatedMillis,
+ @Nullable Bundle extras) {
this.mNetworkType = type;
this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
- this.mExtras = extras.deepCopy();
+ this.mExtras = extras == null ? null : extras.deepCopy();
}
/**
diff --git a/media/java/android/media/metrics/PlaybackErrorEvent.java b/media/java/android/media/metrics/PlaybackErrorEvent.java
index b23b4d2728b4..ccf848b50a36 100644
--- a/media/java/android/media/metrics/PlaybackErrorEvent.java
+++ b/media/java/android/media/metrics/PlaybackErrorEvent.java
@@ -65,12 +65,12 @@ public final class PlaybackErrorEvent extends Event implements Parcelable {
int errorCode,
int subErrorCode,
long timeSinceCreatedMillis,
- Bundle extras) {
+ @Nullable Bundle extras) {
this.mExceptionStack = exceptionStack;
this.mErrorCode = errorCode;
this.mSubErrorCode = subErrorCode;
this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
- this.mExtras = extras.deepCopy();
+ this.mExtras = extras == null ? null : extras.deepCopy();
}
/** @hide */
diff --git a/media/java/android/media/metrics/PlaybackMetrics.java b/media/java/android/media/metrics/PlaybackMetrics.java
index 7e7f44a97b9c..3ffd10f4ea8c 100644
--- a/media/java/android/media/metrics/PlaybackMetrics.java
+++ b/media/java/android/media/metrics/PlaybackMetrics.java
@@ -194,7 +194,7 @@ public final class PlaybackMetrics implements Parcelable {
long localBytesRead,
long networkTransferDurationMillis,
byte[] drmSessionId,
- Bundle extras) {
+ @Nullable Bundle extras) {
this.mMediaDurationMillis = mediaDurationMillis;
this.mStreamSource = streamSource;
this.mStreamType = streamType;
@@ -212,7 +212,7 @@ public final class PlaybackMetrics implements Parcelable {
this.mLocalBytesRead = localBytesRead;
this.mNetworkTransferDurationMillis = networkTransferDurationMillis;
this.mDrmSessionId = drmSessionId;
- this.mExtras = extras.deepCopy();
+ this.mExtras = extras == null ? null : extras.deepCopy();
}
/**
diff --git a/media/java/android/media/metrics/PlaybackStateEvent.java b/media/java/android/media/metrics/PlaybackStateEvent.java
index dea8c1db71de..2bab5c9bc3dc 100644
--- a/media/java/android/media/metrics/PlaybackStateEvent.java
+++ b/media/java/android/media/metrics/PlaybackStateEvent.java
@@ -138,10 +138,10 @@ public final class PlaybackStateEvent extends Event implements Parcelable {
public PlaybackStateEvent(
int state,
long timeSinceCreatedMillis,
- Bundle extras) {
+ @Nullable Bundle extras) {
this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
this.mState = state;
- this.mExtras = extras.deepCopy();
+ this.mExtras = extras == null ? null : extras.deepCopy();
}
/**
diff --git a/media/java/android/media/metrics/TrackChangeEvent.java b/media/java/android/media/metrics/TrackChangeEvent.java
index aa519782ec80..a3eb4adfeb8d 100644
--- a/media/java/android/media/metrics/TrackChangeEvent.java
+++ b/media/java/android/media/metrics/TrackChangeEvent.java
@@ -167,7 +167,7 @@ public final class TrackChangeEvent extends Event implements Parcelable {
this.mWidth = width;
this.mHeight = height;
this.mVideoFrameRate = videoFrameRate;
- this.mExtras = extras.deepCopy();
+ this.mExtras = extras == null ? null : extras.deepCopy();
}
/**
diff --git a/media/java/android/media/permission/PermissionUtil.java b/media/java/android/media/permission/PermissionUtil.java
index 315ee4f1e998..92fe8820570c 100644
--- a/media/java/android/media/permission/PermissionUtil.java
+++ b/media/java/android/media/permission/PermissionUtil.java
@@ -17,9 +17,12 @@
package android.media.permission;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityThread;
import android.content.Context;
import android.content.PermissionChecker;
import android.os.Binder;
+import android.os.Process;
import java.util.Objects;
@@ -49,6 +52,25 @@ import java.util.Objects;
*/
public class PermissionUtil {
/**
+ * Create an identity for the current process and the passed context.
+ *
+ * @param context The process the identity is for. If {@code null}, the process's default
+ * identity is chosen.
+ * @return The identity for the current process and context
+ */
+ public static @NonNull Identity myIdentity(@Nullable Context context) {
+ Identity identity = new Identity();
+
+ identity.pid = Process.myPid();
+ identity.uid = Process.myUid();
+ identity.packageName = context != null ? context.getOpPackageName()
+ : ActivityThread.currentOpPackageName();
+ identity.attributionTag = context != null ? context.getAttributionTag() : null;
+
+ return identity;
+ }
+
+ /**
* Authenticate an originator, where the binder call is coming from a middleman.
*
* The middleman is expected to hold a special permission to act as such, or else a
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index ce4550492740..f09dcde1ee28 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -84,6 +84,7 @@ cc_library_shared {
"android.hardware.drm@1.4",
"android.hidl.memory@1.0",
"android.hidl.token@1.0-utils",
+ "media_permission-aidl-cpp",
],
header_libs: [
@@ -182,7 +183,7 @@ cc_library_shared {
"libnativehelper",
"libutils",
"tv_tuner_aidl_interface-ndk_platform",
- "tv_tuner_resource_manager_aidl_interface-ndk_platform"
+ "tv_tuner_resource_manager_aidl_interface-ndk_platform",
],
static_libs: [
@@ -212,4 +213,3 @@ cc_library_shared {
"-Wunreachable-code",
],
}
-
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 98ac5b983098..a3607597f05e 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -17,6 +17,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaPlayer-JNI"
+#include "permission_utils.h"
#include "utils/Log.h"
#include <media/mediaplayer.h>
@@ -79,6 +80,8 @@ static StateExceptionFields gStateExceptionFields;
using namespace android;
using media::VolumeShaper;
+using media::permission::Identity;
+using media::permission::convertIdentity;
// ----------------------------------------------------------------------------
@@ -946,11 +949,11 @@ android_media_MediaPlayer_native_init(JNIEnv *env)
static void
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
- jstring opPackageName)
+ jobject jIdentity)
{
ALOGV("native_setup");
- ScopedUtfChars opPackageNameStr(env, opPackageName);
- sp<MediaPlayer> mp = new MediaPlayer(opPackageNameStr.c_str());
+
+ sp<MediaPlayer> mp = new MediaPlayer(convertIdentity(env, jIdentity));
if (mp == NULL) {
jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
return;
@@ -1406,7 +1409,7 @@ static const JNINativeMethod gMethods[] = {
{"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter},
{"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata},
{"native_init", "()V", (void *)android_media_MediaPlayer_native_init},
- {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;)V",(void *)android_media_MediaPlayer_native_setup},
+ {"native_setup", "(Ljava/lang/Object;Landroid/media/permission/Identity;)V",(void *)android_media_MediaPlayer_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
{"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id},
{"native_setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id},
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index f99dc012be95..66411233216f 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -24,6 +24,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaRecorderJNI"
+#include "permission_utils.h"
#include <utils/Log.h>
#include <gui/Surface.h>
@@ -50,6 +51,8 @@
using namespace android;
+using android::media::permission::convertIdentity;
+
// ----------------------------------------------------------------------------
// helper function to extract a native Camera object from a Camera Java object
@@ -617,13 +620,12 @@ android_media_MediaRecorder_native_init(JNIEnv *env)
static void
android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
- jstring packageName, jstring opPackageName)
+ jstring packageName, jobject jIdentity)
{
ALOGV("setup");
- ScopedUtfChars opPackageNameStr(env, opPackageName);
+ sp<MediaRecorder> mr = new MediaRecorder(convertIdentity(env, jIdentity));
- sp<MediaRecorder> mr = new MediaRecorder(String16(opPackageNameStr.c_str()));
if (mr == NULL) {
jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
return;
@@ -869,7 +871,7 @@ static const JNINativeMethod gMethods[] = {
{"native_reset", "()V", (void *)android_media_MediaRecorder_native_reset},
{"release", "()V", (void *)android_media_MediaRecorder_release},
{"native_init", "()V", (void *)android_media_MediaRecorder_native_init},
- {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V",
+ {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Landroid/media/permission/Identity;)V",
(void *)android_media_MediaRecorder_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize},
{"native_setInputSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_setInputSurface },
diff --git a/media/jni/audioeffect/Android.bp b/media/jni/audioeffect/Android.bp
index c2fc91d5cfea..bfed983c8bce 100644
--- a/media/jni/audioeffect/Android.bp
+++ b/media/jni/audioeffect/Android.bp
@@ -27,6 +27,11 @@ cc_library_shared {
"libaudioclient",
"libaudioutils",
"libaudiofoundation",
+ "media_permission-aidl-cpp",
+ ],
+
+ export_shared_lib_headers: [
+ "media_permission-aidl-cpp",
],
version_script: "exports.lds",
diff --git a/media/jni/audioeffect/Visualizer.cpp b/media/jni/audioeffect/Visualizer.cpp
index a74ae5307a36..8a52456849f0 100644
--- a/media/jni/audioeffect/Visualizer.cpp
+++ b/media/jni/audioeffect/Visualizer.cpp
@@ -34,8 +34,8 @@ namespace android {
// ---------------------------------------------------------------------------
-Visualizer::Visualizer (const String16& opPackageName)
- : AudioEffect(opPackageName)
+Visualizer::Visualizer (const Identity& identity)
+ : AudioEffect(identity)
{
}
diff --git a/media/jni/audioeffect/Visualizer.h b/media/jni/audioeffect/Visualizer.h
index 8b6a62f25638..3ee91f0f8b1e 100644
--- a/media/jni/audioeffect/Visualizer.h
+++ b/media/jni/audioeffect/Visualizer.h
@@ -20,6 +20,9 @@
#include <media/AudioEffect.h>
#include <system/audio_effects/effect_visualizer.h>
#include <utils/Thread.h>
+#include "android/media/permission/Identity.h"
+
+using namespace android::media::permission;
/**
* The Visualizer class enables application to retrieve part of the currently playing audio for
@@ -65,7 +68,7 @@ public:
/* Constructor.
* See AudioEffect constructor for details on parameters.
*/
- explicit Visualizer(const String16& opPackageName);
+ explicit Visualizer(const Identity& identity);
~Visualizer();
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index 0d53ab152129..953b7e01c983 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -25,6 +25,7 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
#include "media/AudioEffect.h"
+#include "permission_utils.h"
#include <nativehelper/ScopedUtfChars.h>
@@ -34,6 +35,8 @@
using namespace android;
+using media::permission::convertIdentity;
+
#define AUDIOEFFECT_SUCCESS 0
#define AUDIOEFFECT_ERROR (-1)
#define AUDIOEFFECT_ERROR_ALREADY_EXISTS (-2)
@@ -270,7 +273,7 @@ static jint
android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jstring type, jstring uuid, jint priority, jint sessionId,
jint deviceType, jstring deviceAddress,
- jintArray jId, jobjectArray javadesc, jstring opPackageName, jboolean probe)
+ jintArray jId, jobjectArray javadesc, jobject jIdentity, jboolean probe)
{
ALOGV("android_media_AudioEffect_native_setup");
AudioEffectJniStorage* lpJniStorage = NULL;
@@ -283,8 +286,6 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t
jobject jdesc;
AudioDeviceTypeAddr device;
- ScopedUtfChars opPackageNameStr(env, opPackageName);
-
setAudioEffect(env, thiz, 0);
if (type != NULL) {
@@ -337,7 +338,7 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t
}
// create the native AudioEffect object
- lpAudioEffect = new AudioEffect(String16(opPackageNameStr.c_str()));
+ lpAudioEffect = new AudioEffect(convertIdentity(env, jIdentity));
if (lpAudioEffect == 0) {
ALOGE("Error creating AudioEffect");
goto setup_failure;
@@ -773,7 +774,7 @@ android_media_AudioEffect_native_queryPreProcessings(JNIEnv *env, jclass clazz _
// Dalvik VM type signatures
static const JNINativeMethod gMethods[] = {
{"native_init", "()V", (void *)android_media_AudioEffect_native_init},
- {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;[I[Ljava/lang/Object;Ljava/lang/String;Z)I",
+ {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;[I[Ljava/lang/Object;Landroid/media/permission/Identity;Z)I",
(void *)android_media_AudioEffect_native_setup},
{"native_finalize", "()V", (void *)android_media_AudioEffect_native_finalize},
{"native_release", "()V", (void *)android_media_AudioEffect_native_release},
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index 4c5970a30a05..439715cbb811 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -25,6 +25,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/threads.h>
#include "Visualizer.h"
+#include "permission_utils.h"
#include <nativehelper/ScopedUtfChars.h>
@@ -347,7 +348,7 @@ static void android_media_visualizer_effect_callback(int32_t event,
static jint
android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
- jint sessionId, jintArray jId, jstring opPackageName)
+ jint sessionId, jintArray jId, jobject jIdentity)
{
ALOGV("android_media_visualizer_native_setup");
VisualizerJniStorage* lpJniStorage = NULL;
@@ -355,8 +356,6 @@ android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
sp<Visualizer> lpVisualizer;
jint* nId = NULL;
- ScopedUtfChars opPackageNameStr(env, opPackageName);
-
setVisualizer(env, thiz, 0);
lpJniStorage = new VisualizerJniStorage();
@@ -382,7 +381,7 @@ android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
}
// create the native Visualizer object
- lpVisualizer = new Visualizer(String16(opPackageNameStr.c_str()));
+ lpVisualizer = new Visualizer(convertIdentity(env, jIdentity));
if (lpVisualizer == 0) {
ALOGE("Error creating Visualizer");
goto setup_failure;
@@ -679,7 +678,7 @@ android_media_setPeriodicCapture(JNIEnv *env, jobject thiz, jint rate, jboolean
// Dalvik VM type signatures
static const JNINativeMethod gMethods[] = {
{"native_init", "()V", (void *)android_media_visualizer_native_init},
- {"native_setup", "(Ljava/lang/Object;I[ILjava/lang/String;)I",
+ {"native_setup", "(Ljava/lang/Object;I[ILandroid/media/permission/Identity;)I",
(void *)android_media_visualizer_native_setup},
{"native_finalize", "()V", (void *)android_media_visualizer_native_finalize},
{"native_release", "()V", (void *)android_media_visualizer_native_release},
diff --git a/media/jni/soundpool/Android.bp b/media/jni/soundpool/Android.bp
index b3406cd89046..4227cd8cbb29 100644
--- a/media/jni/soundpool/Android.bp
+++ b/media/jni/soundpool/Android.bp
@@ -63,7 +63,7 @@ tidy_errors = [
// Remove some pedantic stylistic requirements.
"-google-readability-casting", // C++ casts not always necessary and may be verbose
- "-google-readability-todo", // do not require TODO(info)
+ "-google-readability-todo", // do not require TODO(info)
"-google-build-using-namespace", // Reenable and fix later.
"-google-explicit-constructor", // found in StreamManager.h
@@ -100,7 +100,7 @@ cc_defaults {
tidy_checks: tidy_errors,
tidy_checks_as_errors: tidy_errors,
tidy_flags: [
- "-format-style=file",
+ "-format-style=file",
],
}
@@ -135,6 +135,7 @@ cc_library_shared {
"libaudioclient",
"libmediandk",
"libbinder",
+ "media_permission-aidl-cpp",
],
cflags: [
diff --git a/media/jni/soundpool/Stream.cpp b/media/jni/soundpool/Stream.cpp
index 73e319a5902e..abb0f1208bc2 100644
--- a/media/jni/soundpool/Stream.cpp
+++ b/media/jni/soundpool/Stream.cpp
@@ -17,6 +17,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "SoundPool::Stream"
#include <utils/Log.h>
+#include<android/media/permission/Identity.h>
#include "Stream.h"
@@ -24,6 +25,8 @@
namespace android::soundpool {
+using media::permission::Identity;
+
Stream::~Stream()
{
ALOGV("%s(%p)", __func__, this);
@@ -326,15 +329,17 @@ void Stream::play_l(const std::shared_ptr<Sound>& sound, int32_t nextStreamID,
// do not create a new audio track if current track is compatible with sound parameters
+ Identity identity = Identity();
+ identity.packageName = mStreamManager->getOpPackageName();
+ // TODO b/182469354 make consistent with AudioRecord, add util for native source
newTrack = new AudioTrack(streamType, sampleRate, sound->getFormat(),
channelMask, sound->getIMemory(), AUDIO_OUTPUT_FLAG_FAST,
staticCallback, userData,
0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE,
AudioTrack::TRANSFER_DEFAULT,
- nullptr /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/,
+ nullptr /*offloadInfo*/, identity,
mStreamManager->getAttributes(),
- false /*doNotReconnect*/, 1.0f /*maxRequiredSpeed*/,
- mStreamManager->getOpPackageName());
+ false /*doNotReconnect*/, 1.0f /*maxRequiredSpeed*/);
// Set caller name so it can be logged in destructor.
// MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_SOUNDPOOL
newTrack->setCallerName("soundpool");
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index cdf4851a3e3d..ed120b53d636 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Kies \'n <xliff:g id="PROFILE_NAME">%1$s</xliff:g> om deur &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; bestuur te word"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string>
<string name="profile_name_watch" msgid="576290739483672360">"horlosie"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Stel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; om jou <xliff:g id="PROFILE_NAME">%2$s</xliff:g> te bestuur – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Jy het <xliff:g id="APP_NAME">%1$s</xliff:g> nodig om jou <xliff:g id="PROFILE_NAME">%2$s</xliff:g> te bestuur. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nee, dankie"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index a03ea0dfcd4c..76f68e7ee495 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"በ&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; የሚተዳደር <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ይምረጡ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ሰዓት"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; የእርስዎን <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; እንዲያስተዳድር ያቀናብሩት"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> የእርስዎን <xliff:g id="PROFILE_NAME">%2$s</xliff:g> ለማስተዳደር ያስፈልጋል። <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"አዎ"</string>
- <string name="consent_no" msgid="1335543792857823917">"አይ፣ አመሰግናለሁ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index 970c46bd6133..92783a529cfc 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"‏اختَر <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ليديره تطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ساعة"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"‏اضبط &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; لإدارة <xliff:g id="PROFILE_NAME">%2$s</xliff:g> على &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"يجب توفّر تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> لإدارة <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"نعم"</string>
- <string name="consent_no" msgid="1335543792857823917">"لا، شكرًا"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index 477844c2a477..34ce062e0f4a 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;এ পৰিচালনা কৰিব লগা এটা <xliff:g id="PROFILE_NAME">%1$s</xliff:g> বাছনি কৰক"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইচ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ঘড়ী"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"আপোনাৰ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> পৰিচালনা কৰিবলৈ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ছেট কৰক - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"আপোনাৰ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> পৰিচালনা কৰিবলৈ <xliff:g id="APP_NAME">%1$s</xliff:g>ৰ আৱশ্যক। <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"হয়"</string>
- <string name="consent_no" msgid="1335543792857823917">"নালাগে, ধন্যবাদ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index f10c639a0368..b07cad615d57 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; tərəfindən idarə ediləcək <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="profile_name_watch" msgid="576290739483672360">"izləyin"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> profilinizin &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tərəfindən idarə olunmasını ayarlayın - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> profilinizi idarə etmək üçün <xliff:g id="APP_NAME">%1$s</xliff:g> tələb olunur. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Bəli"</string>
- <string name="consent_no" msgid="1335543792857823917">"Xeyr, çox sağolun"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index e8542f364027..edeaa7785e36 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Podesite aplikaciju &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da upravlja profilom <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je neophodna za upravljanje profilom <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Da"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, hvala"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index 13be6f245ac0..9410d686133b 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Выберыце прыладу (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), якой будзе кіраваць праграма &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string>
<string name="profile_name_watch" msgid="576290739483672360">"гадзіннік"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; кіраваць прыладай \"<xliff:g id="PROFILE_NAME">%2$s</xliff:g>\" – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Для кіравання прыладай \"<xliff:g id="PROFILE_NAME">%2$s</xliff:g>\" патрабуецца праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\". <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Так"</string>
- <string name="consent_no" msgid="1335543792857823917">"Не, дзякуй"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 3bda5e6104c8..4457dbd2cb3a 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Изберете устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), което да се управлява от &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="profile_name_watch" msgid="576290739483672360">"часовник"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Задайте &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да управлява устройството ви (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"За управление на <xliff:g id="PROFILE_NAME">%2$s</xliff:g> се изисква <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Да"</string>
- <string name="consent_no" msgid="1335543792857823917">"Не, благодаря"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index d3bc5152af9a..4aa7e74e5432 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> বেছে নিন যেটি &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ম্যানেজ করবে"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string>
<string name="profile_name_watch" msgid="576290739483672360">"দেখুন"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"আপনার <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; ম্যানেজ করার জন্য &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; সেট করুন"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g>-কে আপনার <xliff:g id="PROFILE_NAME">%2$s</xliff:g>.ম্যানেজ করতে দিতে হবে। <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"হ্যাঁ"</string>
- <string name="consent_no" msgid="1335543792857823917">"না থাক"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index 905b3061ffc6..8ffa3272fb8c 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Odaberite uređaj <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Postavite aplikaciju &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da upravlja vašim uređajem <xliff:g id="PROFILE_NAME">%2$s</xliff:g> — &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Potrebna je aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> za upravljanje uređajem <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Da"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, hvala"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 86dc6940abe2..c9c186eba741 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Tria un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> perquè el gestioni &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string>
<string name="profile_name_watch" msgid="576290739483672360">"rellotge"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Defineix que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; gestioni el teu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;)"</string>
- <string name="profile_summary" msgid="2009764182871566255">"L\'aplicació <xliff:g id="APP_NAME">%1$s</xliff:g> és necessària per gestionar el teu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sí"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, gràcies"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index 389ccd0ccc95..b2ac32db2a99 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Vyberte zařízení <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, které chcete spravovat pomocí aplikace &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string>
<string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Nastavit aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ke správě tohoto zařízení: <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Ke správě profilu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> je potřeba aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ano"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, díky"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 5a31f9bba4b6..bc67948c3ecf 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Vælg den enhed (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), som skal administreres af &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ur"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Angiv &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; til administration af: <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> er nødvendig for at administrere: <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nej tak"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index b643eb2936ce..1c7ec74f4494 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Gerät (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) auswählen, das von &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; verwaltet werden soll"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string>
<string name="profile_name_watch" msgid="576290739483672360">"Smartwatch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; zum Verwalten deines Geräts (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) festlegen – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> ist erforderlich, um dein Gerät (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) zu verwalten. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nein danke"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 60de2ffe0572..fed516fb04eb 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Επιλέξτε ένα προφίλ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> για διαχείριση από την εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ρολόι"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Ορίστε μια εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; για διαχείριση του προφίλ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> απαιτείται για τη διαχείριση του προφίλ <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ναι"</string>
- <string name="consent_no" msgid="1335543792857823917">"Όχι, ευχαριστώ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index 2fed1ae7fec3..4fd057f3e7e4 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Set &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> is needed to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yes"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, thanks"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
index 2fed1ae7fec3..4fd057f3e7e4 100644
--- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Set &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> is needed to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yes"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, thanks"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index 2fed1ae7fec3..4fd057f3e7e4 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Set &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> is needed to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yes"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, thanks"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index 2fed1ae7fec3..4fd057f3e7e4 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Set &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> is needed to manage your <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yes"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, thanks"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
index f3c4b1dcb434..0e3902c50aea 100644
--- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎Choose a ‎‏‎‎‏‏‎<xliff:g id="PROFILE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to be managed by &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;‎‏‎‎‏‎"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎device‎‏‎‎‏‎"</string>
<string name="profile_name_watch" msgid="576290739483672360">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎watch‎‏‎‎‏‎"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎Set &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to manage your ‎‏‎‎‏‏‎<xliff:g id="PROFILE_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ - &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%3$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;‎‏‎‎‏‎"</string>
- <string name="profile_summary" msgid="2009764182871566255">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is needed to manage your ‎‏‎‎‏‏‎<xliff:g id="PROFILE_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎. ‎‏‎‎‏‏‎<xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="consent_yes" msgid="4055438216605487056">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎Yes‎‏‎‎‏‎"</string>
- <string name="consent_no" msgid="1335543792857823917">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‎No thanks‎‏‎‎‏‎"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index 4fbb57ed9440..6b903c609fe9 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para que &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; lo administre"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"reloj"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Configura &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; para administrar <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Se requiere <xliff:g id="APP_NAME">%1$s</xliff:g> para administrar tu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sí"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, gracias"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index 5ca9305ce4d6..0a2906a97a39 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para gestionarlo con &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"reloj"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Haz que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; gestione tu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Se necesita <xliff:g id="APP_NAME">%1$s</xliff:g> para gestionar tu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sí"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, gracias"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index 357f05237b85..4958a17206f7 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Valige seade <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, mida haldab rakendus &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"seade"</string>
<string name="profile_name_watch" msgid="576290739483672360">"käekell"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Määrake rakendus &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; haldama teie seadet <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> on vajalik teie seadme <xliff:g id="PROFILE_NAME">%2$s</xliff:g> haldamiseks. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Jah"</string>
- <string name="consent_no" msgid="1335543792857823917">"Tänan, ei"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 14c7154acdd3..2a61fd519511 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Aukeratu &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; aplikazioak kudeatu beharreko <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string>
<string name="profile_name_watch" msgid="576290739483672360">"erlojua"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Konfiguratu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; <xliff:g id="PROFILE_NAME">%2$s</xliff:g> (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;) kudea dezan"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> erabili behar duzu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> kudeatzeko. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Bai"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ez"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 6bb9620f09f7..8d102303d91a 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"‏انتخاب <xliff:g id="PROFILE_NAME">%1$s</xliff:g> برای مدیریت کردن با &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>‏&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ساعت"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"‏تنظیم &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; برای مدیریت کردن <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>‏&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"برای مدیریت کردن <xliff:g id="PROFILE_NAME">%2$s</xliff:g> به <xliff:g id="APP_NAME">%1$s</xliff:g> نیاز دارید. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"بله"</string>
- <string name="consent_no" msgid="1335543792857823917">"نه متشکرم"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index 5a9c1cd66aa8..cfa03af870dc 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Valitse <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, jota &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; hallinnoi"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"laite"</string>
<string name="profile_name_watch" msgid="576290739483672360">"kello"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Aseta &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; profiilin (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) hallinnoijaksi – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> tarvitaan profiilin (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) hallinnointiin. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Kyllä"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ei kiitos"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index b31babda1a00..d3cfc299c4ce 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Choisissez un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré par &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Utiliser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pour gérer votre <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"L\'application <xliff:g id="APP_NAME">%1$s</xliff:g> est requise pour gérer votre <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Oui"</string>
- <string name="consent_no" msgid="1335543792857823917">"Non merci"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index 08c93a2c31c6..d82e3905c5d1 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Sélectionner le/la <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré(e) par &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Définir &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pour la gestion de votre <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> est requis pour gérer votre <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Oui"</string>
- <string name="consent_no" msgid="1335543792857823917">"Non, merci"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index c95b90e73edc..2a85398cf3cc 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Escolle un perfil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) para que o xestione a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"reloxo"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Define a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; para a xestión do teu perfil (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>): &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Necesítase a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> para xestionar o teu perfil (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>). <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Si"</string>
- <string name="consent_no" msgid="1335543792857823917">"Non, grazas"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 7e4104208446..6f52403ed416 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; દ્વારા મેનેજ કરવા માટે કોઈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> પસંદ કરો"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ડિવાઇસ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"સ્માર્ટવૉચ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"તમારા <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;ને મેનેજ કરવા માટે &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; સેટ કરો"</string>
- <string name="profile_summary" msgid="2009764182871566255">"તમારા <xliff:g id="PROFILE_NAME">%2$s</xliff:g>ને મેનેજ કરવા માટે <xliff:g id="APP_NAME">%1$s</xliff:g> જરૂરી છે. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"હા"</string>
- <string name="consent_no" msgid="1335543792857823917">"ના, આભાર"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index ac95cc620bfa..9af99924c76a 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"कोई <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चुनें, ताकि उसे &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; की मदद से प्रबंधित किया जा सके"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string>
<string name="profile_name_watch" msgid="576290739483672360">"स्मार्टवॉच"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"अपने <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; को प्रबंधित करने के लिए, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को सेट करें"</string>
- <string name="profile_summary" msgid="2009764182871566255">"आपके <xliff:g id="PROFILE_NAME">%2$s</xliff:g> को प्रबंधित करने के लिए, <xliff:g id="APP_NAME">%1$s</xliff:g> की ज़रूरत है. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"हां"</string>
- <string name="consent_no" msgid="1335543792857823917">"नहीं, रहने दें"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index df8451f5f127..fe30ec485169 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="profile_name_watch" msgid="576290739483672360">"satom"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Postavite aplikaciju &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da upravlja vašim profilom <xliff:g id="PROFILE_NAME">%2$s</xliff:g> –- &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> potrebna je za upravljanje vašim <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Da"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, hvala"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index ff1c6c54d7ba..370d4dff6a98 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"A(z) &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; alkalmazással kezelni kívánt <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiválasztása"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string>
<string name="profile_name_watch" msgid="576290739483672360">"óra"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"A(z) &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; alkalmazás beállítása a(z) <xliff:g id="PROFILE_NAME">%2$s</xliff:g> (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;) kezelésére"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Szükség van a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazásra a(z) <xliff:g id="PROFILE_NAME">%2$s</xliff:g> kezeléséhez. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Igen"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nem"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index 194223d1d416..fee55d0c5396 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Ընտրեք <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ը, որը պետք է կառավարվի &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; հավելվածի կողմից"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ժամացույց"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Ընտրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածը որպես <xliff:g id="PROFILE_NAME">%2$s</xliff:g>ի կառավարիչ․ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Ձեր <xliff:g id="PROFILE_NAME">%2$s</xliff:g>ը կառավարելու համար անհրաժեշտ է <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը։ <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Այո"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ոչ, շնորհակալություն"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 58bf3cb4bca4..498bf2cd3351 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk dikelola oleh &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string>
<string name="profile_name_watch" msgid="576290739483672360">"smartwatch"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Tetapkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengelola <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Perlu <xliff:g id="APP_NAME">%1$s</xliff:g> untuk mengelola <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ya"</string>
- <string name="consent_no" msgid="1335543792857823917">"Tidak"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index cc5b98939b71..bd12658284ef 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Velja <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sem &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; á að stjórna"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string>
<string name="profile_name_watch" msgid="576290739483672360">"úr"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; stjórn á <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> er krafist til að stjórna <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Já"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nei, takk"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 4cbefd801187..40d43207bced 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Scegli un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> che sia gestito da &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"orologio"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Configura &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; per gestire il tuo <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"È richiesta l\'app <xliff:g id="APP_NAME">%1$s</xliff:g> per gestire il tuo <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sì"</string>
- <string name="consent_no" msgid="1335543792857823917">"No, grazie"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index 8663e56ecf14..807cdd471642 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"‏בחירה של <xliff:g id="PROFILE_NAME">%1$s</xliff:g> לניהול באמצעות &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string>
<string name="profile_name_watch" msgid="576290739483672360">"שעון"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"‏הגדרה של &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לניהול <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> נדרשת לניהול של <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"כן"</string>
- <string name="consent_no" msgid="1335543792857823917">"לא תודה"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index ca17336bfb23..92022be9fade 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; の管理対象となる<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の選択"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ウォッチ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; で <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; を管理するよう設定する"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> を管理するために <xliff:g id="APP_NAME">%1$s</xliff:g> が必要です。<xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"はい"</string>
- <string name="consent_no" msgid="1335543792857823917">"いいえ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 300c94f63cbe..64a79b48ec7e 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"აირჩიეთ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, რომელიც უნდა მართოს &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;-მა"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string>
<string name="profile_name_watch" msgid="576290739483672360">"საათი"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"დააყენეთ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;, რომ მართოს თქვენი <xliff:g id="PROFILE_NAME">%2$s</xliff:g> — &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"თქვენი <xliff:g id="PROFILE_NAME">%2$s</xliff:g>-ის სამართავად საჭიროა <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"დიახ"</string>
- <string name="consent_no" msgid="1335543792857823917">"არა, გმადლობთ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 94d6c3ed2d5f..edd5c0ee9cd0 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; арқылы басқарылатын <xliff:g id="PROFILE_NAME">%1$s</xliff:g> құрылғысын таңдаңыз"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string>
<string name="profile_name_watch" msgid="576290739483672360">"сағат"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>) құрылғысын басқаруға рұқсат беру"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> құрылғысын басқару үшін <xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы керек. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Иә"</string>
- <string name="consent_no" msgid="1335543792857823917">"Жоқ, рақмет"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index db13fe7884af..36c02de6790d 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"ជ្រើសរើស <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ដើម្បីឱ្យស្ថិតក្រោម​ការគ្រប់គ្រងរបស់ &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string>
<string name="profile_name_watch" msgid="576290739483672360">"នាឡិកា"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"កំណត់ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ដើម្បីគ្រប់គ្រង <xliff:g id="PROFILE_NAME">%2$s</xliff:g> របស់អ្នក - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ចាំបាច់ត្រូវមាន <xliff:g id="APP_NAME">%1$s</xliff:g> ដើម្បីគ្រប់គ្រង <xliff:g id="PROFILE_NAME">%2$s</xliff:g> របស់អ្នក។ <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"បាទ/ចាស"</string>
- <string name="consent_no" msgid="1335543792857823917">"ទេ អរគុណ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index 0225166849fd..56c1557e5fef 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ಮೂಲಕ ನಿರ್ವಹಿಸಬೇಕಾದ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ಸಾಧನ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ವೀಕ್ಷಿಸಿ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"ನಿಮ್ಮ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; ಅನ್ನು ನಿರ್ವಹಿಸಲು, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಅನ್ನು ನಿರ್ವಹಿಸಿ"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು, <xliff:g id="APP_NAME">%1$s</xliff:g> ಅಗತ್ಯವಿದೆ. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ಹೌದು"</string>
- <string name="consent_no" msgid="1335543792857823917">"ಬೇಡ, ಧನ್ಯವಾದಗಳು"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 1363e57e39a3..79c36dd017fa 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;에서 관리할 <xliff:g id="PROFILE_NAME">%1$s</xliff:g>을(를) 선택"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"기기"</string>
<string name="profile_name_watch" msgid="576290739483672360">"시계"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;에서 <xliff:g id="PROFILE_NAME">%2$s</xliff:g>(&lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;)을(를) 관리하도록 설정"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> 프로필을 관리하려면 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱이 필요합니다. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"예"</string>
- <string name="consent_no" msgid="1335543792857823917">"취소"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index c01e2350aa04..8a90b3dc7d6a 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; тарабынан башкарылсын"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
<string name="profile_name_watch" msgid="576290739483672360">"саат"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; түзмөгүңүздү башкарсын"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> профилиңизди башкаруу үчүн <xliff:g id="APP_NAME">%1$s</xliff:g> керек. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ооба"</string>
- <string name="consent_no" msgid="1335543792857823917">"Жок, рахмат"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index 68218dd79c50..a6564b347651 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"ເລືອກ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ເພື່ອໃຫ້ຖືກຈັດການໂດຍ &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ໂມງ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"ຕັ້ງ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ເພື່ອຈັດການ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; ຂອງທ່ານ"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ຕ້ອງໃຊ້ <xliff:g id="APP_NAME">%1$s</xliff:g> ເພື່ອຈັດການ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> ຂອງທ່ານ. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ແມ່ນແລ້ວ"</string>
- <string name="consent_no" msgid="1335543792857823917">"ບໍ່, ຂອບໃຈ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index 5fd8280affca..382f1cf69a2d 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Jūsų <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, kurį valdys &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; (pasirinkite)"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string>
<string name="profile_name_watch" msgid="576290739483672360">"laikrodis"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Nustatyti, kad <xliff:g id="PROFILE_NAME">%2$s</xliff:g> &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; būtų valdomas programos &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Norint valdyti jūsų <xliff:g id="PROFILE_NAME">%2$s</xliff:g>, reikalinga programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Taip"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, ačiū"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index bf036ec70d73..8d70bf788e27 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Profila (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) izvēle, ko pārvaldīt lietotnē &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string>
<string name="profile_name_watch" msgid="576290739483672360">"pulkstenis"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Lietotnes &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; iestatīšana profila (<xliff:g id="PROFILE_NAME">%2$s</xliff:g> — &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;) pārvaldībai"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Lai pārvaldītu profilu (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>), nepieciešama lietotne <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Jā"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nē, paldies"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index 427ca8f940a0..5322e98c37b7 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Изберете <xliff:g id="PROFILE_NAME">%1$s</xliff:g> со којшто ќе управува &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"уред"</string>
<string name="profile_name_watch" msgid="576290739483672360">"часовник"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Поставете ја &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да управува со <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> е потребна за да управува со <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Да"</string>
- <string name="consent_no" msgid="1335543792857823917">"Не, фала"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index a48c45f73ae7..a9262c7973fb 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ഉപയോഗിച്ച് മാനേജ് ചെയ്യുന്നതിന് ഒരു <xliff:g id="PROFILE_NAME">%1$s</xliff:g> തിരഞ്ഞെടുക്കുക"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ഉപകരണം"</string>
<string name="profile_name_watch" msgid="576290739483672360">"വാച്ച്"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"നിങ്ങളുടെ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> മാനേജ് ചെയ്യുന്നതിന് &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; സജ്ജീകരിക്കുക - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്ന ആപ്പിന് നിങ്ങളുടെ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> മാനേജ് ചെയ്യേണ്ടതുണ്ട്. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"വേണം"</string>
- <string name="consent_no" msgid="1335543792857823917">"വേണ്ട"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index 7ac20e613185..303286466f4b 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;-н удирдах<xliff:g id="PROFILE_NAME">%1$s</xliff:g>-г сонгоно уу"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string>
<string name="profile_name_watch" msgid="576290739483672360">"цаг"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g>-аа удирдахын тулд &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-г тохируулна уу - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Таны <xliff:g id="PROFILE_NAME">%2$s</xliff:g>-г удирдахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> шаардлагатай. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Тийм"</string>
- <string name="consent_no" msgid="1335543792857823917">"Үгүй, баярлалаа"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index 144698b9bc4e..01dae7d3a21e 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; द्वारे व्यवस्थापित करण्यासाठी <xliff:g id="PROFILE_NAME">%1$s</xliff:g> निवडा"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string>
<string name="profile_name_watch" msgid="576290739483672360">"पाहा"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"तुमची <xliff:g id="PROFILE_NAME">%2$s</xliff:g> व्यवस्थापित करण्यासाठी &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; सेट करा - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"तुमची <xliff:g id="PROFILE_NAME">%2$s</xliff:g> व्यवस्थापित करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> आवश्यक आहे. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"होय"</string>
- <string name="consent_no" msgid="1335543792857823917">"नाही, नको"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index 7bea2c91fd2d..4e0f58bc2653 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk diurus oleh &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string>
<string name="profile_name_watch" msgid="576290739483672360">"jam tangan"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Tetapkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengurus <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; anda"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> diperlukan untuk mengurus <xliff:g id="PROFILE_NAME">%2$s</xliff:g> anda. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ya"</string>
- <string name="consent_no" msgid="1335543792857823917">"Tidak perlu"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index 9c2783cdcbbb..050c8ce4364a 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; က စီမံခန့်ခွဲရန် <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ကို ရွေးချယ်ပါ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string>
<string name="profile_name_watch" msgid="576290739483672360">"နာရီ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"သင်၏ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; ကို စီမံခန့်ခွဲရန် &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို သတ်မှတ်ပါ"</string>
- <string name="profile_summary" msgid="2009764182871566255">"သင်၏ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> ကို စီမံခန့်ခွဲရန် <xliff:g id="APP_NAME">%1$s</xliff:g> ကို လိုအပ်ပါသည်။ <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yes"</string>
- <string name="consent_no" msgid="1335543792857823917">"မလိုပါ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 26fbb0350edc..a8e22033faed 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Velg <xliff:g id="PROFILE_NAME">%1$s</xliff:g> som skal administreres av &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="profile_name_watch" msgid="576290739483672360">"klokke"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Angi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; for å administrere <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> kreves for å administrere <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nei takk"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index f289b3780672..45bfb5f469ee 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"आफूले &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; प्रयोग गरी व्यवस्थापन गर्न चाहेको <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चयन गर्नुहोस्"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string>
<string name="profile_name_watch" msgid="576290739483672360">"घडी"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"आफ्नो <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; व्यवस्थापन गर्न &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; तोक्नुहोस्"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> व्यवस्थापन गर्न <xliff:g id="APP_NAME">%1$s</xliff:g> इन्स्टल गर्नु पर्ने हुन्छ। <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"अँ"</string>
- <string name="consent_no" msgid="1335543792857823917">"सहमत छुइनँ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index 0c9cdffd4e17..e7e03904843e 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Een <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiezen om te beheren met &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string>
<string name="profile_name_watch" msgid="576290739483672360">"horloge"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; instellen om je <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; te beheren"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Je hebt <xliff:g id="APP_NAME">%1$s</xliff:g> nodig om je <xliff:g id="PROFILE_NAME">%2$s</xliff:g> te beheren. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nee, bedankt"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index c8c680f8f3a9..1f516fa4c0d0 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ଦ୍ୱାରା ପରିଚାଳିତ ହେବା ପାଇଁ ଏକ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>କୁ ବାଛନ୍ତୁ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ୱାଚ୍"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"ଆପଣଙ୍କ <xliff:g id="PROFILE_NAME">%2$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ସେଟ୍ କରନ୍ତୁ - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ଆପଣଙ୍କ <xliff:g id="PROFILE_NAME">%2$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆବଶ୍ୟକ। <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ହଁ"</string>
- <string name="consent_no" msgid="1335543792857823917">"ନା, ଧନ୍ୟବାଦ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 0da94105a576..03693dc74274 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤੇ ਜਾਣ ਲਈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ਚੁਣੋ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ਸਮਾਰਟ-ਵਾਚ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡਾ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ ਸੈੱਟ ਕਰੋ"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ਤੁਹਾਡੇ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ <xliff:g id="APP_NAME">%1$s</xliff:g> ਦੀ ਲੋੜ ਹੈ। <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ਹਾਂ"</string>
- <string name="consent_no" msgid="1335543792857823917">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index b07af57a936a..7adf064e80b6 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Wybierz profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, którym ma zarządzać aplikacja &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string>
<string name="profile_name_watch" msgid="576290739483672360">"zegarek"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Ustaw aplikację &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; do zarządzania profilem <xliff:g id="PROFILE_NAME">%2$s</xliff:g> na urządzeniu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest wymagana do zarządzania profilem <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Tak"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nie, dziękuję"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 16906f62f9f1..b5ddc6db6f78 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Defina o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; como gerenciador do seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;)"</string>
- <string name="profile_summary" msgid="2009764182871566255">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> é necessário para gerenciar seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sim"</string>
- <string name="consent_no" msgid="1335543792857823917">"Agora não"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index 745d1630dd86..c06ac7de1c11 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerido pela app &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Defina a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; para gerir o seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> é necessária para gerir o seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sim"</string>
- <string name="consent_no" msgid="1335543792857823917">"Não, obrigado"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 16906f62f9f1..b5ddc6db6f78 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Defina o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; como gerenciador do seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;)"</string>
- <string name="profile_summary" msgid="2009764182871566255">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> é necessário para gerenciar seu <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Sim"</string>
- <string name="consent_no" msgid="1335543792857823917">"Agora não"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 187cfbdfe6f0..437e8dc78c76 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Alegeți un profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> pe care să îl gestioneze &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ceas"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Setați &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pentru a vă gestiona profilul <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> este necesară pentru a vă gestiona profilul <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Da"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nu, mulțumesc"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index 8dd9a392712b..d087959971b6 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Выберите устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), которым будет управлять приложение &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="profile_name_watch" msgid="576290739483672360">"часы"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; управлять устройством &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>)"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" необходимо для управления устройством (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>). <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Да"</string>
- <string name="consent_no" msgid="1335543792857823917">"Нет"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 9e7c02e0c0d9..365b6bfb3d2a 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; මගින් කළමනාකරණය කරනු ලැබීමට <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ක් තෝරන්න"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ඔරලෝසුව"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ඔබගේ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> කළමනාකරණය කිරීමට සකසන්න - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ඔබගේ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> කළමනාකරණය කිරීමට <xliff:g id="APP_NAME">%1$s</xliff:g> අවශ්‍යයි. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ඔව්"</string>
- <string name="consent_no" msgid="1335543792857823917">"එපා, ස්තුතියි"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 55a47c2df427..d5c099a36424 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Vyberte profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ktorý bude spravovať aplikácia &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string>
<string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Nastavte aplikáciu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;, aby spravovala profil <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Na správu profilu <xliff:g id="PROFILE_NAME">%2$s</xliff:g> je potrebná aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Áno"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nie, vďaka"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 159afd543609..d855db1cea72 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Izbira naprave <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ki jo bo upravljala aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ura"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Nastavitev aplikacije &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;, ki bo upravljala napravo <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Za upravljanje naprave <xliff:g id="PROFILE_NAME">%2$s</xliff:g> potrebujete aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Da"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ne, hvala"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index 6fa759c15905..7335446765da 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Zgjidh një profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> që do të menaxhohet nga &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string>
<string name="profile_name_watch" msgid="576290739483672360">"ora inteligjente"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Cakto &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; që të menaxhojë profilin tënd <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Nevojitet <xliff:g id="APP_NAME">%1$s</xliff:g> për të menaxhuar profilin tënd të <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Po"</string>
- <string name="consent_no" msgid="1335543792857823917">"Jo, faleminderit"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index fdbbe8e668f5..f3f65e17101b 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Одаберите профил <xliff:g id="PROFILE_NAME">%1$s</xliff:g> којим ће управљати апликација &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string>
<string name="profile_name_watch" msgid="576290739483672360">"сат"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Подесите апликацију &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да управља профилом <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је неопходна за управљање профилом <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Да"</string>
- <string name="consent_no" msgid="1335543792857823917">"Не, хвала"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index bfd25162aec6..574166822006 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Välj en <xliff:g id="PROFILE_NAME">%1$s</xliff:g> för hantering av &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="profile_name_watch" msgid="576290739483672360">"klocka"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Konfigurera &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; för att hantera din <xliff:g id="PROFILE_NAME">%2$s</xliff:g> – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> krävs för att hantera din <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ja"</string>
- <string name="consent_no" msgid="1335543792857823917">"Nej tack"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index 437ae7f332e8..357eb4a475b8 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Chagua <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ili idhibitiwe na &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string>
<string name="profile_name_watch" msgid="576290739483672360">"saa"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Weka &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ili udhibiti <xliff:g id="PROFILE_NAME">%2$s</xliff:g> yako - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g> linahitajika ili kudhibiti <xliff:g id="PROFILE_NAME">%2$s</xliff:g> yako. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ndiyo"</string>
- <string name="consent_no" msgid="1335543792857823917">"Hapana"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index 9b4a720a4863..651d9e276a7a 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ஆப்ஸ் நிர்வகிக்கக்கூடிய <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ஐத் தேர்ந்தெடுங்கள்"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string>
<string name="profile_name_watch" msgid="576290739483672360">"வாட்ச்"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; ஐ நிர்வகிக்க &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அமையுங்கள்"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> ஐ நிர்வகிக்க <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் வேண்டும். <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ஆம்"</string>
- <string name="consent_no" msgid="1335543792857823917">"வேண்டாம்"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index 6e785de583aa..9c3e334c9373 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ద్వారా మేనేజ్ చేయబడటానికి ఒక <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ను ఎంచుకోండి"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"పరికరం"</string>
<string name="profile_name_watch" msgid="576290739483672360">"వాచ్"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"మీ <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;ను మేనేజ్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ను సెటప్ చేయండి"</string>
- <string name="profile_summary" msgid="2009764182871566255">"మీ <xliff:g id="PROFILE_NAME">%2$s</xliff:g>ను మేనేజ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> అవసరం ఉంది. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"అవును"</string>
- <string name="consent_no" msgid="1335543792857823917">"వద్దు, ధన్యవాదాలు"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index b727d42035dd..557515af6ac8 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"เลือก<xliff:g id="PROFILE_NAME">%1$s</xliff:g>ที่จะให้มีการจัดการโดย &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"อุปกรณ์"</string>
<string name="profile_name_watch" msgid="576290739483672360">"นาฬิกา"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"ตั้งค่า &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ให้จัดการ<xliff:g id="PROFILE_NAME">%2$s</xliff:g>ของคุณ - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"ต้องใช้ <xliff:g id="APP_NAME">%1$s</xliff:g> ในการจัดการ<xliff:g id="PROFILE_NAME">%2$s</xliff:g> <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ใช่"</string>
- <string name="consent_no" msgid="1335543792857823917">"ไม่เป็นไร"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index a93282a8fae0..6cbf2e875881 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Pumili ng <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para pamahalaan ng &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="profile_name_watch" msgid="576290739483672360">"relo"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Itakda ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; para pamahalaan ang iyong <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Kailangan ang <xliff:g id="APP_NAME">%1$s</xliff:g> para pamahalaan ang iyong <xliff:g id="PROFILE_NAME">%2$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Oo"</string>
- <string name="consent_no" msgid="1335543792857823917">"Huwag na lang"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 3abe064d60bc..bc1ab31d9b90 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; tarafından yönetilecek bir <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="profile_name_watch" msgid="576290739483672360">"saat"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasını, <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; cihazınızı yönetecek şekilde ayarlayın"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="PROFILE_NAME">%2$s</xliff:g> yönetimi için gereklidir. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Evet"</string>
- <string name="consent_no" msgid="1335543792857823917">"Hayır, teşekkürler"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 161d95e127e8..33477c8f1429 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Виберіть <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, яким керуватиме додаток &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string>
<string name="profile_name_watch" msgid="576290739483672360">"годинник"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Налаштуйте додаток &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;, щоб керувати своїм пристроєм &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>)"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Щоб керувати своїм пристроєм (<xliff:g id="PROFILE_NAME">%2$s</xliff:g>), вам потрібен додаток <xliff:g id="APP_NAME">%1$s</xliff:g>. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Так"</string>
- <string name="consent_no" msgid="1335543792857823917">"Ні, дякую"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index dce18152dff4..83e20d8940cd 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"‏&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; کے ذریعے نظم کئے جانے کیلئے <xliff:g id="PROFILE_NAME">%1$s</xliff:g> کو منتخب کریں"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"آلہ"</string>
<string name="profile_name_watch" msgid="576290739483672360">"دیکھیں"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"‏اپنے <xliff:g id="PROFILE_NAME">%2$s</xliff:g> کا نظم کرنے کے لیے &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; کو سیٹ کریں - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"آپ کے <xliff:g id="PROFILE_NAME">%2$s</xliff:g> کا نظم کرنے کے لیے <xliff:g id="APP_NAME">%1$s</xliff:g> کی ضرورت ہے۔ <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"ہاں"</string>
- <string name="consent_no" msgid="1335543792857823917">"نہیں شکریہ"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 2ca27b530651..b16db730def4 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; boshqaradigan <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qurilmasini tanlang"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string>
<string name="profile_name_watch" msgid="576290739483672360">"soat"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; qurilmalarini boshqarish uchun &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasini sozlang"</string>
- <string name="profile_summary" msgid="2009764182871566255">"<xliff:g id="PROFILE_NAME">%2$s</xliff:g> qurilmasini boshqarish uchun <xliff:g id="APP_NAME">%1$s</xliff:g> zarur. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Ha"</string>
- <string name="consent_no" msgid="1335543792857823917">"Kerak emas"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 06a1ab6846ae..75d2de37cb14 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Chọn một <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sẽ do &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; quản lý"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string>
<string name="profile_name_watch" msgid="576290739483672360">"đồng hồ"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Đặt &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; để quản lý <xliff:g id="PROFILE_NAME">%2$s</xliff:g> của bạn – &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"Cần có <xliff:g id="APP_NAME">%1$s</xliff:g> để quản lý <xliff:g id="PROFILE_NAME">%2$s</xliff:g> của bạn. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Có"</string>
- <string name="consent_no" msgid="1335543792857823917">"Không, cảm ơn"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 12bfcf3629cd..788f8f9edce1 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"选择要由&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"设备"</string>
<string name="profile_name_watch" msgid="576290739483672360">"手表"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"设为由&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;管理您的<xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"若要管理<xliff:g id="PROFILE_NAME">%2$s</xliff:g>,您需要使用<xliff:g id="APP_NAME">%1$s</xliff:g>。<xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"好"</string>
- <string name="consent_no" msgid="1335543792857823917">"不用了"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index 0c583b211035..576f3f46e8ba 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"選擇由 &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; 管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="profile_name_watch" msgid="576290739483672360">"手錶"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"設定 &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 來管理您的 <xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"必須使用 <xliff:g id="APP_NAME">%1$s</xliff:g> 來管理您的<xliff:g id="PROFILE_NAME">%2$s</xliff:g>。<xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"是"</string>
- <string name="consent_no" msgid="1335543792857823917">"不用了,謝謝"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 519f0e8a7082..8a50658ad25c 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"選擇要讓「<xliff:g id="APP_NAME">%2$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="profile_name_watch" msgid="576290739483672360">"手錶"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"授權讓「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;管理你的<xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"如要管理你的<xliff:g id="PROFILE_NAME">%2$s</xliff:g>,必須使用「<xliff:g id="APP_NAME">%1$s</xliff:g>」。<xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"是"</string>
- <string name="consent_no" msgid="1335543792857823917">"不用了,謝謝"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index 7721b54166f5..fc3f19d72ee2 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -20,8 +20,12 @@
<string name="chooser_title" msgid="2262294130493605839">"Khetha i-<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ezophathwa yi-&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string>
<string name="profile_name_watch" msgid="576290739483672360">"buka"</string>
- <string name="confirmation_title" msgid="4751119145078041732">"Setha i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ukuba iphathe i-<xliff:g id="PROFILE_NAME">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
- <string name="profile_summary" msgid="2009764182871566255">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> iyadingeka ukuphatha i-<xliff:g id="PROFILE_NAME">%2$s</xliff:g> yakho. <xliff:g id="PRIVILEGES_DISCPLAIMER">%3$s</xliff:g>"</string>
- <string name="consent_yes" msgid="4055438216605487056">"Yebo"</string>
- <string name="consent_no" msgid="1335543792857823917">"Cha ngiyabonga"</string>
+ <!-- no translation found for confirmation_title (814973816731238955) -->
+ <skip />
+ <!-- no translation found for profile_summary (2059360676631420073) -->
+ <skip />
+ <!-- no translation found for consent_yes (8344487259618762872) -->
+ <skip />
+ <!-- no translation found for consent_no (2640796915611404382) -->
+ <skip />
</resources>
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index 731bdccb914f..4dd012a8d074 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -29,15 +29,15 @@
<string name="profile_name_watch">watch</string>
<!-- Title of the device association confirmation dialog. -->
- <string name="confirmation_title">Set &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%1$s</xliff:g>&lt;/strong&gt; to manage your <xliff:g id="profile_name" example="watch">%2$s</xliff:g> - &lt;strong&gt;<xliff:g id="device_name" example="ASUS ZenWatch 2">%3$s</xliff:g>&lt;/strong&gt;</string>
+ <string name="confirmation_title">Set &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%1$s</xliff:g>&lt;/strong&gt; to manage your &lt;strong&gt;<xliff:g id="device_name" example="ASUS ZenWatch 2">%2$s</xliff:g>&lt;/strong&gt;</string>
<!-- Text of the device profile permissions explanation in the association dialog. -->
- <string name="profile_summary"><xliff:g id="app_name" example="Android Wear">%1$s</xliff:g> is needed to manage your <xliff:g id="profile_name" example="watch">%2$s</xliff:g>. <xliff:g id="privileges_discplaimer" example="Android Wear will get access to your Notifications, Calendar and Contacts.">%3$s</xliff:g></string>
+ <string name="profile_summary">This app is needed to manage your <xliff:g id="profile_name" example="watch">%1$s</xliff:g>. <xliff:g id="privileges_discplaimer" example="Android Wear will get access to your Notifications, Calendar and Contacts.">%2$s</xliff:g></string>
<!-- Positive button for the device-app association consent dialog [CHAR LIMIT=30] -->
- <string name="consent_yes">Yes</string>
+ <string name="consent_yes">Allow</string>
<!-- Negative button for the device-app association consent dialog [CHAR LIMIT=30] -->
- <string name="consent_no">No thanks</string>
+ <string name="consent_no">Don\u2019t allow</string>
</resources>
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index d2ed73ef8298..6df57c132382 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -51,6 +51,14 @@ package android.net {
field public static final String TEST_TAP_PREFIX = "testtap";
}
+ public final class TestNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+ ctor public TestNetworkSpecifier(@NonNull String);
+ method public int describeContents();
+ method @Nullable public String getInterfaceName();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkSpecifier> CREATOR;
+ }
+
public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
ctor public VpnTransportInfo(int);
method public int describeContents();
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index b4a651c0607e..17a8ee1720c4 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -31,6 +31,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVIT
import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -382,11 +383,17 @@ public class NetworkRequest implements Parcelable {
return setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
.setSubscriptionId(subId).build());
} catch (NumberFormatException nfe) {
- // A StringNetworkSpecifier does not accept null or empty ("") strings. When network
- // specifiers were strings a null string and an empty string were considered
- // equivalent. Hence no meaning is attached to a null or empty ("") string.
- return setNetworkSpecifier(TextUtils.isEmpty(networkSpecifier) ? null
- : new StringNetworkSpecifier(networkSpecifier));
+ // An EthernetNetworkSpecifier or TestNetworkSpecifier does not accept null or empty
+ // ("") strings. When network specifiers were strings a null string and an empty
+ // string were considered equivalent. Hence no meaning is attached to a null or
+ // empty ("") string.
+ if (TextUtils.isEmpty(networkSpecifier)) {
+ return setNetworkSpecifier((NetworkSpecifier) null);
+ } else if (mNetworkCapabilities.hasTransport(TRANSPORT_TEST)) {
+ return setNetworkSpecifier(new TestNetworkSpecifier(networkSpecifier));
+ } else {
+ return setNetworkSpecifier(new EthernetNetworkSpecifier(networkSpecifier));
+ }
}
}
diff --git a/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java b/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java
new file mode 100644
index 000000000000..b7470a591d20
--- /dev/null
+++ b/packages/Connectivity/framework/src/android/net/TestNetworkSpecifier.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * A {@link NetworkSpecifier} used to identify test interfaces.
+ *
+ * @see TestNetworkManager
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class TestNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+
+ /**
+ * Name of the network interface.
+ */
+ @NonNull
+ private final String mInterfaceName;
+
+ public TestNetworkSpecifier(@NonNull String interfaceName) {
+ Preconditions.checkStringNotEmpty(interfaceName);
+ mInterfaceName = interfaceName;
+ }
+
+ // This may be null in the future to support specifiers based on data other than the interface
+ // name.
+ @Nullable
+ public String getInterfaceName() {
+ return mInterfaceName;
+ }
+
+ @Override
+ public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) {
+ return equals(other);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof TestNetworkSpecifier)) return false;
+ return TextUtils.equals(mInterfaceName, ((TestNetworkSpecifier) o).mInterfaceName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(mInterfaceName);
+ }
+
+ @Override
+ public String toString() {
+ return "TestNetworkSpecifier (" + mInterfaceName + ")";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mInterfaceName);
+ }
+
+ public static final @NonNull Creator<TestNetworkSpecifier> CREATOR =
+ new Creator<TestNetworkSpecifier>() {
+ public TestNetworkSpecifier createFromParcel(Parcel in) {
+ return new TestNetworkSpecifier(in.readString());
+ }
+ public TestNetworkSpecifier[] newArray(int size) {
+ return new TestNetworkSpecifier[size];
+ }
+ };
+}
diff --git a/packages/Connectivity/service/Android.bp b/packages/Connectivity/service/Android.bp
index e65b7b423bdc..856f3b85333a 100644
--- a/packages/Connectivity/service/Android.bp
+++ b/packages/Connectivity/service/Android.bp
@@ -50,12 +50,11 @@ cc_library_shared {
}
java_library {
- name: "service-connectivity",
+ name: "service-connectivity-pre-jarjar",
srcs: [
+ ":framework-connectivity-shared-srcs",
":connectivity-service-srcs",
],
- installable: true,
- jarjar_rules: "jarjar-rules.txt",
libs: [
"android.net.ipsec.ike",
"services.core",
@@ -67,7 +66,21 @@ java_library {
"net-utils-device-common",
"net-utils-framework-common",
"netd-client",
+ "PlatformProperties",
+ ],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.tethering",
],
+}
+
+java_library {
+ name: "service-connectivity",
+ installable: true,
+ static_libs: [
+ "service-connectivity-pre-jarjar",
+ ],
+ jarjar_rules: "jarjar-rules.txt",
apex_available: [
"//apex_available:platform",
"com.android.tethering",
diff --git a/packages/Connectivity/service/jarjar-rules.txt b/packages/Connectivity/service/jarjar-rules.txt
index d8205bf780fd..a7b419b020b5 100644
--- a/packages/Connectivity/service/jarjar-rules.txt
+++ b/packages/Connectivity/service/jarjar-rules.txt
@@ -1,2 +1,14 @@
+rule android.sysprop.** com.android.connectivity.sysprop.@1
rule com.android.net.module.util.** com.android.connectivity.net-utils.@1
-rule com.android.modules.utils.** com.android.connectivity.modules-utils.@1 \ No newline at end of file
+rule com.android.modules.utils.** com.android.connectivity.modules-utils.@1
+
+# internal util classes
+# Exclude AsyncChannel. TODO: remove AsyncChannel usage in ConnectivityService
+rule com.android.internal.util.AsyncChannel* @0
+# Exclude LocationPermissionChecker. This is going to be moved to libs/net
+rule com.android.internal.util.LocationPermissionChecker* @0
+rule android.util.LocalLog* com.android.connectivity.util.LocalLog@1
+# android.util.IndentingPrintWriter* should use a different package name from
+# the one in com.android.internal.util
+rule android.util.IndentingPrintWriter* android.connectivity.util.IndentingPrintWriter@1
+rule com.android.internal.util.** com.android.connectivity.util.@1
diff --git a/packages/CtsShim/build/shim/AndroidManifest.xml b/packages/CtsShim/build/shim/AndroidManifest.xml
index 7d2626d50083..1ffe56c0c76a 100644
--- a/packages/CtsShim/build/shim/AndroidManifest.xml
+++ b/packages/CtsShim/build/shim/AndroidManifest.xml
@@ -53,6 +53,9 @@
</intent-filter>
</activity>
+ <!-- The stub shared library for package visibility test -->
+ <library android:name="com.android.cts.ctsshim.shared_library" />
+
</application>
</manifest>
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index 4ef5e2b4f090..59ea9f0150bf 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -320,7 +320,7 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog
}
}
- private void installScratch() throws IOException, InterruptedException {
+ private void installScratch() throws IOException {
final long scratchSize = mDynSystem.suggestScratchSize();
Thread thread = new Thread() {
@Override
@@ -347,7 +347,11 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog
publishProgress(progress);
}
- Thread.sleep(100);
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // Ignore the error.
+ }
}
if (mInstallationSession == null) {
@@ -361,7 +365,7 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog
}
}
- private void installUserdata() throws IOException, InterruptedException {
+ private void installUserdata() throws IOException {
Thread thread = new Thread(() -> {
mInstallationSession = mDynSystem.createPartition("userdata", mUserdataSize, false);
});
@@ -383,7 +387,11 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog
publishProgress(progress);
}
- Thread.sleep(100);
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // Ignore the error.
+ }
}
if (mInstallationSession == null) {
@@ -397,8 +405,7 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog
}
}
- private void installImages()
- throws IOException, InterruptedException, ImageValidationException {
+ private void installImages() throws IOException, ImageValidationException {
if (mStream != null) {
if (mIsZip) {
installStreamingZipUpdate();
@@ -410,14 +417,12 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog
}
}
- private void installStreamingGzUpdate()
- throws IOException, InterruptedException, ImageValidationException {
+ private void installStreamingGzUpdate() throws IOException, ImageValidationException {
Log.d(TAG, "To install a streaming GZ update");
installImage("system", mSystemSize, new GZIPInputStream(mStream));
}
- private void installStreamingZipUpdate()
- throws IOException, InterruptedException, ImageValidationException {
+ private void installStreamingZipUpdate() throws IOException, ImageValidationException {
Log.d(TAG, "To install a streaming ZIP update");
ZipInputStream zis = new ZipInputStream(mStream);
@@ -432,8 +437,7 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog
}
}
- private void installLocalZipUpdate()
- throws IOException, InterruptedException, ImageValidationException {
+ private void installLocalZipUpdate() throws IOException, ImageValidationException {
Log.d(TAG, "To install a local ZIP update");
Enumeration<? extends ZipEntry> entries = mZipFile.entries();
@@ -449,7 +453,7 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog
}
private boolean installImageFromAnEntry(ZipEntry entry, InputStream is)
- throws IOException, InterruptedException, ImageValidationException {
+ throws IOException, ImageValidationException {
String name = entry.getName();
Log.d(TAG, "ZipEntry: " + name);
@@ -473,7 +477,7 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog
}
private void installImage(String partitionName, long uncompressedSize, InputStream is)
- throws IOException, InterruptedException, ImageValidationException {
+ throws IOException, ImageValidationException {
SparseInputStream sis = new SparseInputStream(new BufferedInputStream(is));
@@ -504,7 +508,11 @@ class InstallationAsyncTask extends AsyncTask<String, InstallationAsyncTask.Prog
return;
}
- Thread.sleep(100);
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // Ignore the error.
+ }
}
if (mInstallationSession == null) {
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
index ed49bf4d5385..231babea97c2 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
@@ -20,4 +20,8 @@ android_library {
],
sdk_version: "system_current",
min_sdk_version: "21",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.cellbroadcast",
+ ],
}
diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down.xml
index 827d0b583388..054452629c88 100644
--- a/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down.xml
@@ -16,11 +16,11 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:viewportWidth="24"
- android:viewportHeight="24"
+ android:viewportWidth="18"
+ android:viewportHeight="18"
android:width="24dp"
android:height="24dp">
<path
android:pathData="M7 10l5 5 5 -5z"
- android:fillColor="?android:attr/textColorPrimary"/>
-</vector> \ No newline at end of file
+ android:fillColor="@android:color/black"/>
+</vector>
diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
index 263c16b0749c..b38e3e3e89c1 100644
--- a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
@@ -24,21 +24,21 @@
android:bottom="8dp">
<shape>
<corners
- android:radius="20dp"/>
+ android:radius="28dp"/>
<solid
- android:color="?android:attr/colorPrimary"/>
+ android:color="?android:attr/colorAccent"/>
<stroke
- android:color="#1f000000"
+ android:color="?android:attr/colorPrimary"
android:width="1dp"/>
<size
- android:height="32dp"/>
+ android:height="@dimen/spinner_height"/>
</shape>
</item>
<item
android:gravity="center|end"
- android:width="24dp"
- android:height="24dp"
- android:end="4dp"
- android:drawable="@drawable/arrow_drop_down_24dp"/>
+ android:width="18dp"
+ android:height="18dp"
+ android:end="8dp"
+ android:drawable="@drawable/arrow_drop_down"/>
</layer-list> \ No newline at end of file
diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_dropdown_background.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_dropdown_background.xml
new file mode 100644
index 000000000000..8cac988632bc
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_dropdown_background.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item>
+ <shape>
+ <solid
+ android:color="?android:attr/colorAccent"/>
+ </shape>
+ </item>
+
+ <item>
+ <shape>
+ <solid android:color="#BBFFFFFF"/>
+ </shape>
+ </item>
+
+</layer-list>
diff --git a/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_dropdown_view.xml b/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_dropdown_view.xml
new file mode 100644
index 000000000000..a342c840cfbe
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_dropdown_view.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ style="@style/SettingsSpinnerTitleBar"
+ android:gravity="center_vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/settings_spinner_dropdown_background"/>
diff --git a/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml b/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml
index bdd370fe04ee..75de34e86bc4 100644
--- a/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml
@@ -19,7 +19,5 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="@style/SettingsSpinnerTitleBar"
- android:maxLines="1"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:ellipsize="marquee"/>
+ android:layout_height="wrap_content"/>
diff --git a/packages/SystemUI/res/drawable/controls_dialog_bg.xml b/packages/SettingsLib/SettingsSpinner/res/values/dimens.xml
index 1ccb176b8689..d526df6bedd4 100644
--- a/packages/SystemUI/res/drawable/controls_dialog_bg.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/values/dimens.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 The Android Open Source Project
+<!-- Copyright (C) 2021 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,8 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="?android:attr/colorBackground" />
- <corners android:radius="@dimen/notification_corner_radius" />
-</shape>
+
+<resources>
+ <dimen name="spinner_height">36dp</dimen>
+ <dimen name="spinner_padding_top_or_bottom">8dp</dimen>
+</resources>
diff --git a/packages/SettingsLib/SettingsSpinner/res/values/styles.xml b/packages/SettingsLib/SettingsSpinner/res/values/styles.xml
index 8af20e20ede9..f665f3836002 100644
--- a/packages/SettingsLib/SettingsSpinner/res/values/styles.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/values/styles.xml
@@ -18,9 +18,13 @@
<resources>
<style name="SettingsSpinnerTitleBar">
<item name="android:textAppearance">?android:attr/textAppearanceButton</item>
+ <item name="android:textColor">@android:color/black</item>
+ <item name="android:maxLines">1</item>
+ <item name="android:ellipsize">marquee</item>
+ <item name="android:minHeight">@dimen/spinner_height</item>
<item name="android:paddingStart">16dp</item>
<item name="android:paddingEnd">36dp</item>
- <item name="android:paddingTop">8dp</item>
- <item name="android:paddingBottom">8dp</item>
+ <item name="android:paddingTop">@dimen/spinner_padding_top_or_bottom</item>
+ <item name="android:paddingBottom">@dimen/spinner_padding_top_or_bottom</item>
</style>
-</resources> \ No newline at end of file
+</resources>
diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java
index 5ef8f7ac792b..0be80a9fd466 100644
--- a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java
+++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java
@@ -121,4 +121,11 @@ public class SettingsSpinner extends Spinner {
int mode) {
super(context, attrs, defStyleAttr, defStyleRes, mode, null);
}
-} \ No newline at end of file
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ setDropDownVerticalOffset(getMeasuredHeight() - (int) getContext().getResources()
+ .getDimension(R.dimen.spinner_padding_top_or_bottom));
+ }
+}
diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java
index a8ca0d8664f3..83da512ce879 100644
--- a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java
+++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java
@@ -30,8 +30,7 @@ import com.android.settingslib.widget.R;
public class SettingsSpinnerAdapter<T> extends ArrayAdapter<T> {
private static final int DEFAULT_RESOURCE = R.layout.settings_spinner_view;
- private static final int DFAULT_DROPDOWN_RESOURCE =
- android.R.layout.simple_spinner_dropdown_item;
+ private static final int DFAULT_DROPDOWN_RESOURCE = R.layout.settings_spinner_dropdown_view;
private final LayoutInflater mDefaultInflater;
/**
diff --git a/packages/SettingsLib/SettingsTheme/Android.bp b/packages/SettingsLib/SettingsTheme/Android.bp
index bda863a71453..73459c277df1 100644
--- a/packages/SettingsLib/SettingsTheme/Android.bp
+++ b/packages/SettingsLib/SettingsTheme/Android.bp
@@ -18,4 +18,8 @@ android_library {
sdk_version: "system_current",
min_sdk_version: "21",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.cellbroadcast",
+ ],
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index ed2b6c92530b..e8e10a4def3e 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -153,6 +153,7 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.DOZE_TAP_SCREEN_GESTURE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.DOZE_WAKE_DISPLAY_GESTURE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOZE_QUICK_PICKUP_GESTURE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.NFC_PAYMENT_DEFAULT_COMPONENT, COMPONENT_NAME_VALIDATOR);
VALIDATORS.put(
Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN, NON_NEGATIVE_INTEGER_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index e427981b87d7..400742ba7d78 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1937,8 +1937,11 @@ public class SettingsProvider extends ContentProvider {
if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
return;
}
- checkReadableAnnotation(settingsType, settingName);
ApplicationInfo ai = getCallingApplicationInfoOrThrow();
+ if (ai.isSystemApp() || ai.isSignedWithPlatformKey()) {
+ return;
+ }
+ checkReadableAnnotation(settingsType, settingName);
if (!ai.isInstantApp()) {
return;
}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 4dc6d1475c4a..c520568a78e5 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -745,6 +745,7 @@ public class SettingsBackupTest {
Settings.Secure.SILENCE_GESTURE,
Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
+ Settings.Secure.DOZE_QUICK_PICKUP_GESTURE,
Settings.Secure.FACE_UNLOCK_RE_ENROLL,
Settings.Secure.TAP_GESTURE,
Settings.Secure.NEARBY_SHARING_COMPONENT, // not user configurable
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b6d942a29d49..e0097df62078 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -578,7 +578,7 @@
<!-- People Space UI Screen -->
<activity android:name=".people.PeopleSpaceActivity"
- android:label="People"
+ android:label="@string/people_tile_title"
android:enabled="true"
android:exported="true"
android:theme="@android:style/Theme.Material.NoActionBar">
@@ -592,7 +592,7 @@
<!-- People Space Widget -->
<receiver
android:name=".people.widget.PeopleSpaceWidgetProvider"
- android:label="People Space"
+ android:label="@string/people_tile_title"
android:enabled="true"
android:exported="true">
<intent-filter>
@@ -751,6 +751,17 @@
android:visibleToInstantApps="true">
</activity>
+ <activity android:name=".controls.ui.ControlsActivity"
+ android:label="@string/quick_controls_title"
+ android:theme="@style/Theme.ControlsActivity"
+ android:excludeFromRecents="true"
+ android:showWhenLocked="true"
+ android:showForAllUsers="true"
+ android:launchMode="singleInstance"
+ android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
+ android:visibleToInstantApps="true">
+ </activity>
+
<receiver android:name=".controls.management.ControlsRequestReceiver"
android:exported="true">
<intent-filter>
diff --git a/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml b/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml
new file mode 100644
index 000000000000..34675ab891c1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_footer_action_chip_background.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:insetTop="@dimen/qs_footer_action_inset"
+ android:insetBottom="@dimen/qs_footer_action_inset">
+ <ripple
+ android:color="?android:attr/colorControlHighlight"
+ android:height="44dp">
+ <item android:id="@android:id/mask">
+ <shape android:shape="rectangle">
+ <solid android:color="@android:color/white"/>
+ <corners android:radius="@dimen/screenshot_button_corner_radius"/>
+ </shape>
+ </item>
+ <item>
+ <shape android:shape="rectangle">
+ <stroke android:width="1dp" android:color="@color/qs_footer_action_border"/>
+ <solid android:color="@android:color/transparent"/>
+ <corners android:radius="@dimen/screenshot_button_corner_radius"/>
+ </shape>
+ </item>
+ </ripple>
+</inset> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_footer_action_chip_background_borderless.xml b/packages/SystemUI/res/drawable/qs_footer_action_chip_background_borderless.xml
new file mode 100644
index 000000000000..596ed711dd43
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_footer_action_chip_background_borderless.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:insetTop="@dimen/qs_footer_action_inset"
+ android:insetBottom="@dimen/qs_footer_action_inset">
+ <ripple
+ android:color="?android:attr/colorControlHighlight">
+ <item android:id="@android:id/mask">
+ <shape android:shape="rectangle">
+ <solid android:color="@android:color/white"/>
+ <corners android:radius="@dimen/screenshot_button_corner_radius"/>
+ </shape>
+ </item>
+ <item>
+ <shape android:shape="rectangle">
+ <solid android:color="@android:color/transparent"/>
+ <corners android:radius="@dimen/screenshot_button_corner_radius"/>
+ </shape>
+ </item>
+ </ripple>
+</inset> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/auth_biometric_contents.xml b/packages/SystemUI/res/layout/auth_biometric_contents.xml
index aed067c30253..eef37ab20c69 100644
--- a/packages/SystemUI/res/layout/auth_biometric_contents.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_contents.xml
@@ -39,37 +39,34 @@
<Space android:id="@+id/space_above_icon"
android:layout_width="match_parent"
- android:layout_height="48dp"
- android:visibility="visible" />
+ android:layout_height="48dp" />
- <!-- Use a frame layout since certain biometrics (such as UDFPS) require the icon to be centered
- within a certain area on the display. This makes it easy to 1) guarantee max size, and
- 2) center the icon within the reserved area. -->
- <FrameLayout android:id="@+id/biometric_icon_frame"
+ <FrameLayout
+ android:id="@+id/biometric_icon_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal">
+
<ImageView
android:id="@+id/biometric_icon"
android:layout_width="@dimen/biometric_dialog_biometric_icon_size"
android:layout_height="@dimen/biometric_dialog_biometric_icon_size"
android:layout_gravity="center"
android:scaleType="fitXY" />
+
</FrameLayout>
- <!-- For sensors such as UDFPS, this view is used during custom measurement/layoutto add extra
+ <!-- For sensors such as UDFPS, this view is used during custom measurement/layout to add extra
padding so that the biometric icon is always in the right physical position. -->
<Space android:id="@+id/space_below_icon"
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:visibility="gone" />
+ android:layout_height="12dp" />
<TextView
android:id="@+id/indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="24dp"
- android:paddingVertical="12dp"
android:textSize="12sp"
android:gravity="center_horizontal"
android:accessibilityLiveRegion="polite"
@@ -84,6 +81,7 @@
style="?android:attr/buttonBarStyle"
android:orientation="horizontal"
android:paddingTop="16dp">
+
<Space android:id="@+id/leftSpacer"
android:layout_width="8dp"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/controls_detail_dialog.xml b/packages/SystemUI/res/layout/controls_detail_dialog.xml
index ee5315ad782f..28fc86372092 100644
--- a/packages/SystemUI/res/layout/controls_detail_dialog.xml
+++ b/packages/SystemUI/res/layout/controls_detail_dialog.xml
@@ -20,8 +20,8 @@
android:id="@+id/control_detail_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginTop="@dimen/controls_activity_view_top_offset"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:background="@android:color/black">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -30,7 +30,7 @@
<ImageView
android:id="@+id/control_detail_close"
android:contentDescription="@string/accessibility_desc_close"
- android:src="@drawable/ic_close"
+ android:src="@drawable/ic_arrow_back"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:tint="@color/control_primary_text"
android:layout_width="48dp"
@@ -56,7 +56,6 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
- android:background="@android:color/black"
android:orientation="vertical" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/controls_in_dialog.xml b/packages/SystemUI/res/layout/controls_fullscreen.xml
index 983999f9a5f8..1b2d2e2e9c89 100644
--- a/packages/SystemUI/res/layout/controls_in_dialog.xml
+++ b/packages/SystemUI/res/layout/controls_fullscreen.xml
@@ -20,11 +20,8 @@
android:id="@+id/control_detail_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginVertical="@dimen/controls_activity_view_top_offset"
- android:layout_marginHorizontal="@dimen/controls_activity_view_side_offset"
- android:padding="8dp"
android:orientation="vertical"
- android:background="@drawable/controls_dialog_bg">
+ android:background="@android:color/black">
<com.android.systemui.globalactions.MinHeightScrollView
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/controls_with_favorites.xml b/packages/SystemUI/res/layout/controls_with_favorites.xml
index b060afdc18e3..9d011482d011 100644
--- a/packages/SystemUI/res/layout/controls_with_favorites.xml
+++ b/packages/SystemUI/res/layout/controls_with_favorites.xml
@@ -25,8 +25,21 @@
<!-- make sure the header stays centered in the layout by adding a spacer -->
<Space
+ android:id="@+id/controls_spacer"
android:layout_width="@dimen/controls_header_menu_size"
- android:layout_height="1dp" />
+ android:layout_height="1dp"
+ android:visibility="gone" />
+
+ <ImageView
+ android:id="@+id/controls_close"
+ android:contentDescription="@string/accessibility_desc_close"
+ android:src="@drawable/ic_close"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ android:tint="@color/control_primary_text"
+ android:layout_width="@dimen/controls_header_menu_size"
+ android:layout_height="@dimen/controls_header_menu_size"
+ android:padding="12dp"
+ android:visibility="gone" />
<!-- need to keep this outer view in order to have a correctly sized anchor
for the dropdown menu, as well as dropdown background in the right place -->
<LinearLayout
diff --git a/packages/SystemUI/res/layout/people_space_activity.xml b/packages/SystemUI/res/layout/people_space_activity.xml
index 07af01b0db72..1784cae816ce 100644
--- a/packages/SystemUI/res/layout/people_space_activity.xml
+++ b/packages/SystemUI/res/layout/people_space_activity.xml
@@ -25,19 +25,30 @@
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="vertical"
- android:padding="16dp"
+ android:padding="24dp"
android:clipChildren="false"
android:clipToPadding="false">
<TextView
+ android:id="@+id/select_conversation_title"
+ android:gravity="center"
+ android:text="@string/select_conversation_title"
+ android:layout_width="wrap_content"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+ android:textSize="24sp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"/>
+
+ <TextView
android:id="@+id/select_conversation"
+ android:gravity="center"
android:text="@string/select_conversation_text"
android:layout_width="match_parent"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
- android:textSize="24sp"
+ android:textSize="16sp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- android:paddingBottom="16dp" />
+ android:padding="24dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/people_space_placeholder_layout.xml b/packages/SystemUI/res/layout/people_space_placeholder_layout.xml
new file mode 100644
index 000000000000..3ced1ff6c74b
--- /dev/null
+++ b/packages/SystemUI/res/layout/people_space_placeholder_layout.xml
@@ -0,0 +1,75 @@
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <LinearLayout
+ android:background="@drawable/people_space_tile_view_card"
+ android:id="@+id/item"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:gravity="center"
+ android:paddingVertical="2dp"
+ android:paddingHorizontal="8dp"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <ImageView
+ android:background="@drawable/ic_person"
+ android:id="@+id/person_icon_only"
+ android:layout_width="60dp"
+ android:layout_height="60dp"/>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:paddingStart="8dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:id="@+id/availability"
+ android:layout_width="10dp"
+ android:layout_height="10dp"
+ android:background="@drawable/circle_green_10dp"/>
+ <TextView
+ android:id="@+id/name"
+ android:text="@string/empty_user_name"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="14sp"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <TextView
+ android:id="@+id/last_interaction"
+ android:text="@string/empty_status"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+ android:textSize="12sp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="3"
+ android:ellipsize="end"/>
+ </LinearLayout>
+ </LinearLayout>
+ </LinearLayout>
+</LinearLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_carrier.xml b/packages/SystemUI/res/layout/qs_carrier.xml
index a5b8cfa5d60b..c521dc2b45a5 100644
--- a/packages/SystemUI/res/layout/qs_carrier.xml
+++ b/packages/SystemUI/res/layout/qs_carrier.xml
@@ -28,13 +28,6 @@
android:clipToPadding="false"
android:focusable="true" >
- <include
- layout="@layout/mobile_signal_group"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="@dimen/qs_carrier_margin_width"
- android:visibility="gone" />
-
<com.android.systemui.util.AutoMarqueeTextView
android:id="@+id/qs_carrier_text"
android:layout_width="wrap_content"
@@ -46,4 +39,11 @@
android:singleLine="true"
android:maxEms="7"/>
+ <include
+ layout="@layout/mobile_signal_group"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/qs_carrier_margin_width"
+ android:visibility="gone" />
+
</com.android.systemui.qs.carrier.QSCarrier> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index 93dd1a12f147..02179722b35c 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -89,7 +89,7 @@
android:background="?android:attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:clipToPadding="false"
- android:contentDescription="@string/accessibility_quick_settings_edit"
+ android:contentDescription="@string/accessibility_quick_settings_power_menu"
android:focusable="true"
android:padding="@dimen/qs_footer_icon_padding"
android:src="@*android:drawable/ic_lock_power_off"
diff --git a/packages/SystemUI/res/layout/qs_footer_impl_two_lines.xml b/packages/SystemUI/res/layout/qs_footer_impl_two_lines.xml
new file mode 100644
index 000000000000..726e69f6e50c
--- /dev/null
+++ b/packages/SystemUI/res/layout/qs_footer_impl_two_lines.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 2021, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+-->
+
+<!-- Extends FrameLayout -->
+<com.android.systemui.qs.QSFooterView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/qs_footer"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/qs_footer_height"
+ android:layout_marginStart="@dimen/qs_footer_margin"
+ android:layout_marginEnd="@dimen/qs_footer_margin"
+ android:background="@android:color/transparent"
+ android:baselineAligned="false"
+ android:clickable="false"
+ android:clipChildren="false"
+ android:clipToPadding="false">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:layout_gravity="center_vertical">
+
+ <TextView
+ android:id="@+id/build"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:paddingStart="@dimen/qs_tile_margin_horizontal"
+ android:paddingEnd="4dp"
+ android:layout_weight="1"
+ android:clickable="true"
+ android:ellipsize="marquee"
+ android:focusable="true"
+ android:gravity="center_vertical"
+ android:singleLine="true"
+ android:textAppearance="@style/TextAppearance.QS.Status"
+ android:visibility="gone" />
+
+ <com.android.systemui.qs.PageIndicator
+ android:id="@+id/footer_page_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical"
+ android:visibility="gone" />
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/qs_footer_actions_container"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:gravity="center_vertical">
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@android:id/edit"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:layout_marginEnd="@dimen/qs_tile_margin_horizontal"
+ android:layout_weight="1"
+ android:background="@drawable/qs_footer_action_chip_background"
+ android:clickable="true"
+ android:clipToPadding="false"
+ android:contentDescription="@string/accessibility_quick_settings_edit"
+ android:focusable="true"
+ android:padding="@dimen/qs_footer_icon_padding"
+ android:src="@*android:drawable/ic_mode_edit"
+ android:tint="?android:attr/colorForeground" />
+
+ <com.android.systemui.statusbar.phone.MultiUserSwitch
+ android:id="@+id/multi_user_switch"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:layout_marginEnd="@dimen/qs_tile_margin_horizontal"
+ android:layout_weight="1"
+ android:background="@drawable/qs_footer_action_chip_background"
+ android:focusable="true">
+
+ <ImageView
+ android:id="@+id/multi_user_avatar"
+ android:layout_width="@dimen/multi_user_avatar_expanded_size"
+ android:layout_height="@dimen/multi_user_avatar_expanded_size"
+ android:layout_gravity="center"
+ android:scaleType="centerInside" />
+ </com.android.systemui.statusbar.phone.MultiUserSwitch>
+
+ <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
+ android:id="@+id/settings_button_container"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:layout_marginEnd="@dimen/qs_tile_margin_horizontal"
+ android:background="@drawable/qs_footer_action_chip_background"
+ android:layout_weight="1"
+ android:clipChildren="false"
+ android:clipToPadding="false">
+
+ <com.android.systemui.statusbar.phone.SettingsButton
+ android:id="@+id/settings_button"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:layout_gravity="center"
+ android:contentDescription="@string/accessibility_quick_settings_settings"
+ android:background="@drawable/qs_footer_action_chip_background_borderless"
+ android:padding="@dimen/qs_footer_icon_padding"
+ android:scaleType="centerInside"
+ android:src="@drawable/ic_settings"
+ android:tint="?android:attr/colorForeground" />
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/tuner_icon"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingStart="36dp"
+ android:paddingEnd="4dp"
+ android:src="@drawable/tuner"
+ android:tint="?android:attr/textColorTertiary"
+ android:visibility="invisible" />
+
+ </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/pm_lite"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:layout_weight="1"
+ android:background="@drawable/qs_footer_action_chip_background"
+ android:clickable="true"
+ android:clipToPadding="false"
+ android:focusable="true"
+ android:padding="@dimen/qs_footer_icon_padding"
+ android:src="@*android:drawable/ic_lock_power_off"
+ android:contentDescription="@string/accessibility_quick_settings_power_menu"
+ android:tint="?android:attr/colorForeground" />
+
+ </LinearLayout>
+ </LinearLayout>
+
+</com.android.systemui.qs.QSFooterView>
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 77f17439c487..d29cf872fd26 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -42,7 +42,10 @@
android:background="@android:color/transparent"
android:focusable="true"
android:accessibilityTraversalBefore="@android:id/edit">
- <include layout="@layout/qs_footer_impl" />
+ <ViewStub
+ android:id="@+id/qs_footer_stub"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
<include layout="@layout/qs_media_divider"
android:id="@+id/divider"/>
</com.android.systemui.qs.QSPanel>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index c36f7cd630a9..424172458b80 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -36,6 +36,7 @@
<color name="qs_user_detail_icon_muted">#FFFFFFFF</color> <!-- not so muted after all -->
<color name="qs_tile_disabled_color">#9E9E9E</color> <!-- 38% black -->
<color name="qs_customize_decoration">@color/GM2_grey_300</color>
+ <color name="qs_footer_action_border">#2E312C</color>
<!-- The color of the background in the separated list of the Global Actions menu -->
<color name="global_actions_separated_background">#F5F5F5</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index b75a0bc1525a..92d9ca9e94d8 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -107,7 +107,7 @@
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
<string name="quick_settings_tiles_stock" translatable="false">
- wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse,reduce_brightness,cameratoggle,mictoggle,controls
+ wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse,reduce_brightness,cameratoggle,mictoggle,controls,alarm
</string>
<!-- The tiles to display in QuickSettings -->
@@ -180,6 +180,9 @@
<!-- Doze: duration to avoid false pickup gestures triggered by notification vibrations -->
<integer name="doze_pickup_vibration_threshold">2000</integer>
+ <!-- Doze: quick pickup duration to stay in AOD until the next gesture is triggered -->
+ <integer name="doze_quick_pickup_aod_duration">5000</integer>
+
<!-- Type of a sensor that provides a low-power estimate of the desired display
brightness, suitable to listen to while the device is asleep (e.g. during
always-on display) -->
@@ -577,6 +580,9 @@
<!-- Whether wallet view is shown in landscape / seascape orientations -->
<bool name="global_actions_show_landscape_wallet_view">false</bool>
+ <!-- Package name of the preferred system app to perform eSOS action -->
+ <string name="config_preferredEmergencySosPackage" translatable="false"></string>
+
<!-- Whether to use the split 2-column notification shade -->
<bool name="config_use_split_notification_shade">false</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 392eb496031a..885cd254a1ea 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -167,15 +167,11 @@
and the notification won't use this much, but is measured with wrap_content -->
<dimen name="notification_messaging_actions_min_height">196dp</dimen>
- <!-- Height of a call notification. Note that this is an upper bound
- and the notification won't use this much, but is measured with wrap_content -->
- <dimen name="call_notification_full_height">172dp</dimen>
-
<!-- a threshold in dp per second that is considered fast scrolling -->
<dimen name="scroll_fast_threshold">1500dp</dimen>
<!-- Height of a the shelf with the notification icons -->
- <dimen name="notification_shelf_height">32dp</dimen>
+ <dimen name="notification_shelf_height">48dp</dimen>
<!-- Minimum height of a notification to be interactable -->
<dimen name="notification_min_interaction_height">40dp</dimen>
@@ -415,6 +411,9 @@
<!-- The size of each of the icon buttons in the QS footer -->
<dimen name="qs_footer_action_button_size">@dimen/qs_footer_height</dimen>
+ <!-- (48dp - 44dp) / 2 -->
+ <dimen name="qs_footer_action_inset">2dp</dimen>
+
<!-- Margins on each side of QS Footer -->
<dimen name="qs_footer_margin">2dp</dimen>
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index e5518928c98c..8cd5757247e2 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -46,4 +46,6 @@
<bool name="flag_navigation_bar_overlay">false</bool>
<bool name="flag_pm_lite">false</bool>
+
+ <bool name="flag_alarm_tile">false</bool>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 783f80c2ee02..6207449d63e6 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2312,6 +2312,9 @@
<!-- accessibility label for button to edit quick settings [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_edit">Edit order of settings.</string>
+ <!-- accessibility label for button to open power menu [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_power_menu">Power menu</string>
+
<!-- accessibility label for paging indicator in quick settings [CHAR LIMITi=NONE] -->
<string name="accessibility_quick_settings_page">Page <xliff:g name="current_page" example="1">%1$d</xliff:g> of <xliff:g name="num_pages" example="2">%2$d</xliff:g></string>
@@ -2808,44 +2811,44 @@
<!-- Text to display when copying the build number off QS [CHAR LIMIT=NONE]-->
<string name="build_number_copy_toast">Build number copied to clipboard.</string>
- <!-- Status for last interaction with exact time [CHAR LIMIT=120] -->
- <string name="last_interaction_status" translatable="false">Last chatted <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
- <!-- Status for last interaction when less than a certain time window [CHAR LIMIT=120] -->
- <string name="last_interaction_status_less_than" translatable="false">Last chatted less than <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
- <!-- Status for last interaction when over a certain time window [CHAR LIMIT=120] -->
- <string name="last_interaction_status_over" translatable="false">Last chatted over <xliff:g id="duration" example="1 week">%1$s</xliff:g> ago</string>
- <!-- Status for conversation without interaction data [CHAR LIMIT=120] -->
- <string name="basic_status" translatable="false">Open conversation</string>
- <!-- Status for conversation without interaction data [CHAR LIMIT=120] -->
- <string name="select_conversation_text" translatable="false">Select one conversation to show in your widget:</string>
- <!-- Timestamp for notification with exact time [CHAR LIMIT=120] -->
- <string name="timestamp" translatable="false"><xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
- <!-- Timestamp for notification when less than a certain time window [CHAR LIMIT=120] -->
- <string name="less_than_timestamp" translatable="false">Less than <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
- <!-- Timestamp for notification when over a certain time window [CHAR LIMIT=120] -->
- <string name="over_timestamp" translatable="false">Over <xliff:g id="duration" example="1 week">%1$s</xliff:g> ago</string>
- <!-- Status text for a birthday today [CHAR LIMIT=30] -->
- <string name="birthday_status" translatable="false">Birthday</string>
- <!-- Status text for an upcoming birthday [CHAR LIMIT=30] -->
- <string name="upcoming_birthday_status" translatable="false">Birthday soon</string>
- <!-- Status text for an anniversary [CHAR LIMIT=30] -->
- <string name="anniversary_status" translatable="false">Anniversary</string>
- <!-- Status text for sharing location [CHAR LIMIT=30] -->
- <string name="location_status" translatable="false">Sharing location</string>
- <!-- Status text for a new story posted [CHAR LIMIT=30] -->
- <string name="new_story_status" translatable="false">New story</string>
- <!-- Status text for watching a video [CHAR LIMIT=30] -->
- <string name="video_status" translatable="false">Watching</string>
- <!-- Status text for listening to audio [CHAR LIMIT=30] -->
- <string name="audio_status" translatable="false">Listening</string>
- <!-- Status text for playing a game [CHAR LIMIT=30] -->
- <string name="game_status" translatable="false">Playing</string>
- <!-- Empty user name before user has selected a friend [CHAR LIMIT=30] -->
- <string name="empty_user_name" translatable="false">Your friend</string>
- <!-- Empty status shown before user has selected a friend [CHAR LIMIT=30] -->
- <string name="empty_status" translatable="false">Their status</string>
- <!-- Default text for missed call notifications [CHAR LIMIT=30] -->
- <string name="missed_call" translatable="false">Missed call</string>
+ <!-- Status for conversation without interaction data [CHAR LIMIT=120] -->
+ <string name="basic_status">Open conversation</string>
+ <!--Title text for Conversation widget set up screen [CHAR LIMIT=180] -->
+ <string name="select_conversation_title">Conversation widgets</string>
+ <!--Text explaining to tap a conversation to select it show in their Conversation widget [CHAR LIMIT=180] -->
+ <string name="select_conversation_text">Tap a conversation to add it to your Home screen</string>
+ <!-- Timestamp for notification with exact time [CHAR LIMIT=25] -->
+ <string name="timestamp"><xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
+ <!-- Timestamp for notification when less than a certain time window [CHAR LIMIT=25] -->
+ <string name="less_than_timestamp">Less than <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
+ <!-- Timestamp for notification when over a certain time window [CHAR LIMIT=25] -->
+ <string name="over_timestamp">Over <xliff:g id="duration" example="1 week">%1$s</xliff:g> ago</string>
+ <!-- Status text on the Conversation widget for a birthday today [CHAR LIMIT=20] -->
+ <string name="birthday_status">Birthday</string>
+ <!-- Status text on the Conversation widget for an upcoming birthday [CHAR LIMIT=20] -->
+ <string name="upcoming_birthday_status">Birthday soon</string>
+ <!-- Status text on the Conversation widget for an anniversary [CHAR LIMIT=20] -->
+ <string name="anniversary_status">Anniversary</string>
+ <!-- Status text on the Conversation widget for sharing location [CHAR LIMIT=20] -->
+ <string name="location_status">Sharing location</string>
+ <!-- Status text on the Conversation widget for a new story posted [CHAR LIMIT=20] -->
+ <string name="new_story_status">New story</string>
+ <!-- Status text on the Conversation widget for watching a video [CHAR LIMIT=20] -->
+ <string name="video_status">Watching</string>
+ <!-- Status text on the Conversation widget for listening to audio [CHAR LIMIT=20] -->
+ <string name="audio_status">Listening</string>
+ <!-- Status text on the Conversation widget for playing a game [CHAR LIMIT=20] -->
+ <string name="game_status">Playing</string>
+ <!-- Empty user name before user has selected a friend for their Conversation widget [CHAR LIMIT=20] -->
+ <string name="empty_user_name">Friends</string>
+ <!-- Empty status shown before user has selected a friend for their Conversation widget [CHAR LIMIT=20] -->
+ <string name="empty_status">Let’s chat tonight!</string>
+ <!-- Default text for missed call notifications on their Conversation widget [CHAR LIMIT=20] -->
+ <string name="missed_call">Missed call</string>
+ <!-- Description text for adding a Conversation widget [CHAR LIMIT=100] -->
+ <string name="people_tile_description">See recent messages, missed calls, and status updates</string>
+ <!-- Title text displayed for the Conversation widget [CHAR LIMIT=50] -->
+ <string name="people_tile_title">Conversation</string>
<!-- Title to display in a notification when ACTION_BATTERY_CHANGED.EXTRA_PRESENT field is false
[CHAR LIMIT=NONE] -->
@@ -2858,4 +2861,7 @@
<string name="qs_remove_labels" translatable="false"></string>
<string name="qs_tile_label_fontFamily" translatable="false">@*android:string/config_headlineFontFamily</string>
+
+ <!-- Secondary label for alarm tile when there is no next alarm information [CHAR LIMIT=20] -->
+ <string name="qs_alarm_tile_no_alarm">No alarm set</string>
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index ec26b8d7a6a8..fb885cb3fdbe 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -244,6 +244,8 @@
<item name="android:paddingTop">12dp</item>
<item name="android:paddingHorizontal">24dp</item>
<item name="android:textSize">24sp</item>
+ <item name="android:singleLine">true</item>
+ <item name="android:ellipsize">marquee</item>
</style>
<style name="TextAppearance.AuthCredential.Subtitle">
@@ -251,6 +253,8 @@
<item name="android:paddingTop">8dp</item>
<item name="android:paddingHorizontal">24dp</item>
<item name="android:textSize">16sp</item>
+ <item name="android:singleLine">true</item>
+ <item name="android:ellipsize">marquee</item>
</style>
<style name="TextAppearance.AuthCredential.Description">
@@ -258,6 +262,8 @@
<item name="android:paddingTop">8dp</item>
<item name="android:paddingHorizontal">24dp</item>
<item name="android:textSize">14sp</item>
+ <item name="android:singleLine">true</item>
+ <item name="android:ellipsize">marquee</item>
</style>
<style name="TextAppearance.AuthCredential.Error">
@@ -643,6 +649,16 @@
<item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
</style>
+ <style name="Theme.ControlsActivity" parent="@android:style/Theme.DeviceDefault.NoActionBar">
+ <item name="android:windowActivityTransitions">true</item>
+ <item name="android:windowContentTransitions">false</item>
+ <item name="android:windowIsTranslucent">false</item>
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:windowAnimationStyle">@null</item>
+ <item name="android:statusBarColor">@*android:color/transparent</item>
+ <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
+ </style>
+
<style name="Theme.CreateUser" parent="@style/Theme.SystemUI">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#33000000</item>
@@ -654,30 +670,12 @@
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
</style>
- <style name="Theme.SystemUI.Dialog.Control.DetailPanel" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
- <item name="android:windowAnimationStyle">@style/Animation.Bottomsheet</item>
- <item name="android:windowFullscreen">true</item>
+ <style name="Theme.SystemUI.Dialog.Control.DetailPanel" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
+ <item name="android:windowFullscreen">false</item>
<item name="android:windowIsFloating">false</item>
- <item name="android:windowBackground">@null</item>
- <item name="android:backgroundDimEnabled">true</item>
- </style>
-
- <style name="Animation.Bottomsheet">
- <item name="android:windowEnterAnimation">@anim/bottomsheet_in</item>
- <item name="android:windowExitAnimation">@anim/bottomsheet_out</item>
- </style>
-
- <style name="Theme.SystemUI.Dialog.Control.LockScreen" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
- <item name="android:windowAnimationStyle">@style/Animation.ControlDialog</item>
- <item name="android:windowFullscreen">true</item>
- <item name="android:windowIsFloating">false</item>
- <item name="android:windowBackground">@null</item>
- <item name="android:backgroundDimEnabled">true</item>
- </style>
-
- <style name="Animation.ControlDialog">
- <item name="android:windowEnterAnimation">@*android:anim/dialog_enter</item>
- <item name="android:windowExitAnimation">@*android:anim/dialog_exit</item>
+ <item name="android:windowBackground">@android:color/black</item>
+ <item name="android:backgroundDimEnabled">false</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
</style>
<style name="Control" />
diff --git a/packages/SystemUI/res/xml/people_space_widget_info.xml b/packages/SystemUI/res/xml/people_space_widget_info.xml
index fbdac5e1789b..35188d8e11ad 100644
--- a/packages/SystemUI/res/xml/people_space_widget_info.xml
+++ b/packages/SystemUI/res/xml/people_space_widget_info.xml
@@ -20,8 +20,9 @@
android:minResizeWidth="110dp"
android:minResizeHeight="55dp"
android:updatePeriodMillis="60000"
- android:previewImage="@drawable/ic_person"
+ android:description="@string/people_tile_description"
+ android:previewLayout="@layout/people_space_placeholder_layout"
android:resizeMode="horizontal|vertical"
android:configure="com.android.systemui.people.PeopleSpaceActivity"
- android:initialLayout="@layout/people_space_widget">
+ android:initialLayout="@layout/people_space_placeholder_layout">
</appwidget-provider>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a4054bea1167..69e6ed043172 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2077,8 +2077,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
boolean shouldListenForUdfps() {
return shouldListenForFingerprint()
&& !mBouncer
- && mStatusBarState != StatusBarState.SHADE_LOCKED
- && mStatusBarState != StatusBarState.FULLSCREEN_USER_SWITCHER
&& mStrongAuthTracker.hasUserAuthenticatedSinceBoot();
}
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 3852b24fe4b3..fba34e0b8ad3 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -367,7 +367,7 @@ public class SwipeHelper implements Gefingerpoken {
}
/**
- * @param view The view to be dismissed
+ * @param animView The view to be dismissed
* @param velocity The desired pixels/second speed at which the view should move
* @param endAction The action to perform at the end
* @param delay The delay after which we should start
@@ -477,12 +477,8 @@ public class SwipeHelper implements Gefingerpoken {
public void snapChild(final View animView, final float targetLeft, float velocity) {
final boolean canBeDismissed = mCallback.canChildBeDismissed(animView);
- AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed);
- }
- };
+ AnimatorUpdateListener updateListener = animation -> onTranslationUpdate(animView,
+ (float) animation.getAnimatedValue(), canBeDismissed);
Animator anim = getViewTranslationAnimator(animView, targetLeft, updateListener);
if (anim == null) {
@@ -501,8 +497,6 @@ public class SwipeHelper implements Gefingerpoken {
mSnappingChild = false;
if (!wasCancelled) {
updateSwipeProgressFromOffset(animView, canBeDismissed);
- onChildSnappedBack(animView, targetLeft);
- mCallback.onChildSnappedBack(animView, targetLeft);
resetSwipeState();
}
}
@@ -513,6 +507,7 @@ public class SwipeHelper implements Gefingerpoken {
mFlingAnimationUtils.apply(anim, getTranslation(animView), targetLeft, velocity,
maxDistance);
anim.start();
+ mCallback.onChildSnappedBack(animView, targetLeft);
}
/**
@@ -594,13 +589,12 @@ public class SwipeHelper implements Gefingerpoken {
if (!mIsSwiping && !mMenuRowIntercepting) {
if (mCallback.getChildAtPosition(ev) != null) {
-
// We are dragging directly over a card, make sure that we also catch the gesture
// even if nobody else wants the touch event.
+ mTouchedView = mCallback.getChildAtPosition(ev);
onInterceptTouchEvent(ev);
return true;
} else {
-
// We are not doing anything, make sure the long press callback
// is not still ticking like a bomb waiting to go off.
cancelLongPress();
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index e85cafaf47ac..d3168c8d2a05 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -170,7 +170,9 @@ public class AssistManager {
boolean visible = false;
if (mView != null) {
visible = mView.isShowing();
- mWindowManager.removeView(mView);
+ if (mView.isAttachedToWindow()) {
+ mWindowManager.removeView(mView);
+ }
}
mView = (AssistOrbContainer) LayoutInflater.from(mContext).inflate(
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java
index cc608ef87bc6..007080bc8603 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java
@@ -16,17 +16,22 @@
package com.android.systemui.biometrics;
+import android.annotation.IdRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.graphics.Insets;
import android.graphics.Rect;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.Surface;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.widget.FrameLayout;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
/**
@@ -51,53 +56,38 @@ public class AuthBiometricUdfpsView extends AuthBiometricFingerprintView {
mSensorProps = prop;
}
- /**
- * For devices where the sensor is too high up, calculates the amount of padding necessary to
- * move/center the biometric icon within the sensor's physical location.
- */
- static int calculateBottomSpacerHeight(int displayHeightPx, int navbarHeightPx,
- int dialogBottomMarginPx, @NonNull View buttonBar, @NonNull View textIndicator,
- @NonNull FingerprintSensorPropertiesInternal sensorProperties) {
- final int sensorDistanceFromBottom = displayHeightPx - sensorProperties.sensorLocationY
- - sensorProperties.sensorRadius;
-
- final int spacerHeight = sensorDistanceFromBottom
- - textIndicator.getMeasuredHeight()
- - buttonBar.getMeasuredHeight()
- - dialogBottomMarginPx
- - navbarHeightPx;
-
- Log.d(TAG, "Display height: " + displayHeightPx
- + ", Distance from bottom: " + sensorDistanceFromBottom
- + ", Bottom margin: " + dialogBottomMarginPx
- + ", Navbar height: " + navbarHeightPx
- + ", Spacer height: " + spacerHeight);
-
- return spacerHeight;
- }
-
@Override
+ @NonNull
AuthDialog.LayoutParams onMeasureInternal(int width, int height) {
- final View spaceBelowIcon = findViewById(R.id.space_below_icon);
- spaceBelowIcon.setVisibility(View.VISIBLE);
+ final int displayRotation = getDisplay().getRotation();
+ switch (displayRotation) {
+ case Surface.ROTATION_0:
+ return onMeasureInternalPortrait(width, height);
+ case Surface.ROTATION_90:
+ case Surface.ROTATION_270:
+ return onMeasureInternalLandscape(width, height);
+ default:
+ Log.e(TAG, "Unsupported display rotation: " + displayRotation);
+ return super.onMeasureInternal(width, height);
+ }
+ }
+ @NonNull
+ private AuthDialog.LayoutParams onMeasureInternalPortrait(int width, int height) {
// Get the height of the everything below the icon. Currently, that's the indicator and
- // button bar
- final View textIndicator = findViewById(R.id.indicator);
- final View buttonBar = findViewById(R.id.button_bar);
+ // button bar.
+ final int textIndicatorHeight = getViewHeightPx(R.id.indicator);
+ final int buttonBarHeight = getViewHeightPx(R.id.button_bar);
// Figure out where the bottom of the sensor anim should be.
// Navbar + dialogMargin + buttonBar + textIndicator + spacerHeight = sensorDistFromBottom
- final int dialogBottomMarginPx = getResources()
- .getDimensionPixelSize(R.dimen.biometric_dialog_border_padding);
- final WindowManager wm = getContext().getSystemService(WindowManager.class);
- final Rect bounds = wm.getCurrentWindowMetrics().getBounds();
- final int navbarHeight = wm.getCurrentWindowMetrics().getWindowInsets()
- .getInsets(WindowInsets.Type.navigationBars()).toRect().height();
- final int displayHeight = bounds.height();
-
- final int spacerHeight = calculateBottomSpacerHeight(displayHeight, navbarHeight,
- dialogBottomMarginPx, buttonBar, textIndicator, mSensorProps);
+ final int dialogMargin = getDialogMarginPx();
+ final WindowManager windowManager = getContext().getSystemService(WindowManager.class);
+ final int displayHeight = getWindowBounds(windowManager).height();
+ final Insets navbarInsets = getNavbarInsets(windowManager);
+ final int bottomSpacerHeight = calculateBottomSpacerHeightForPortrait(
+ mSensorProps, displayHeight, textIndicatorHeight, buttonBarHeight,
+ dialogMargin, navbarInsets.bottom);
// Go through each of the children and do the custom measurement.
int totalHeight = 0;
@@ -105,22 +95,25 @@ public class AuthBiometricUdfpsView extends AuthBiometricFingerprintView {
final int sensorDiameter = mSensorProps.sensorRadius * 2;
for (int i = 0; i < numChildren; i++) {
final View child = getChildAt(i);
-
if (child.getId() == R.id.biometric_icon_frame) {
- // Create a frame that's exactly the size of the sensor circle
- child.measure(
- MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
- } else if (child.getId() == R.id.biometric_icon) {
- // Icon should never be larger than the circle
- child.measure(
+ final FrameLayout iconFrame = (FrameLayout) child;
+ final View icon = iconFrame.getChildAt(0);
+
+ // Ensure that the icon is never larger than the sensor.
+ icon.measure(
MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST));
+
+ // Create a frame that's exactly the height of the sensor circle.
+ iconFrame.measure(
+ MeasureSpec.makeMeasureSpec(
+ child.getLayoutParams().width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
} else if (child.getId() == R.id.space_above_icon) {
child.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(child.getLayoutParams().height,
- MeasureSpec.EXACTLY));
+ MeasureSpec.makeMeasureSpec(
+ child.getLayoutParams().height, MeasureSpec.EXACTLY));
} else if (child.getId() == R.id.button_bar) {
child.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
@@ -128,8 +121,9 @@ public class AuthBiometricUdfpsView extends AuthBiometricFingerprintView {
MeasureSpec.EXACTLY));
} else if (child.getId() == R.id.space_below_icon) {
// Set the spacer height so the fingerprint icon is on the physical sensor area
- child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(spacerHeight, MeasureSpec.EXACTLY));
+ child.measure(
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(bottomSpacerHeight, MeasureSpec.EXACTLY));
} else {
child.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
@@ -143,4 +137,184 @@ public class AuthBiometricUdfpsView extends AuthBiometricFingerprintView {
return new AuthDialog.LayoutParams(width, totalHeight);
}
+
+ @NonNull
+ private AuthDialog.LayoutParams onMeasureInternalLandscape(int width, int height) {
+ // Find the spacer height needed to vertically align the icon with the sensor.
+ final int titleHeight = getViewHeightPx(R.id.title);
+ final int subtitleHeight = getViewHeightPx(R.id.subtitle);
+ final int descriptionHeight = getViewHeightPx(R.id.description);
+ final int topSpacerHeight = getViewHeightPx(R.id.space_above_icon);
+ final int textIndicatorHeight = getViewHeightPx(R.id.indicator);
+ final int buttonBarHeight = getViewHeightPx(R.id.button_bar);
+ final WindowManager windowManager = getContext().getSystemService(WindowManager.class);
+ final Insets navbarInsets = getNavbarInsets(windowManager);
+ final int bottomSpacerHeight = calculateBottomSpacerHeightForLandscape(titleHeight,
+ subtitleHeight, descriptionHeight, topSpacerHeight, textIndicatorHeight,
+ buttonBarHeight, navbarInsets.bottom);
+
+ // Find the spacer width needed to horizontally align the icon with the sensor.
+ final int displayWidth = getWindowBounds(windowManager).width();
+ final int dialogMargin = getDialogMarginPx();
+ final int horizontalInset = navbarInsets.left + navbarInsets.right;
+ final int horizontalSpacerWidth = calculateHorizontalSpacerWidthForLandscape(
+ mSensorProps, displayWidth, dialogMargin, horizontalInset);
+
+ final int sensorDiameter = mSensorProps.sensorRadius * 2;
+ final int remeasuredWidth = sensorDiameter + 2 * horizontalSpacerWidth;
+
+ int remeasuredHeight = 0;
+ final int numChildren = getChildCount();
+ for (int i = 0; i < numChildren; i++) {
+ final View child = getChildAt(i);
+ if (child.getId() == R.id.biometric_icon_frame) {
+ final FrameLayout iconFrame = (FrameLayout) child;
+ final View icon = iconFrame.getChildAt(0);
+
+ // Ensure that the icon is never larger than the sensor.
+ icon.measure(
+ MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST),
+ MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST));
+
+ // Create a frame that's exactly the height of the sensor circle.
+ iconFrame.measure(
+ MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY));
+ } else if (child.getId() == R.id.space_above_icon || child.getId() == R.id.button_bar) {
+ // Adjust the width of the top spacer and button bar while preserving their heights.
+ child.measure(
+ MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(
+ child.getLayoutParams().height, MeasureSpec.EXACTLY));
+ } else if (child.getId() == R.id.space_below_icon) {
+ // Adjust the bottom spacer height to align the fingerprint icon with the sensor.
+ child.measure(
+ MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(bottomSpacerHeight, MeasureSpec.EXACTLY));
+ } else {
+ // Use the remeasured width for all other child views.
+ child.measure(
+ MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
+ }
+
+ if (child.getVisibility() != View.GONE) {
+ remeasuredHeight += child.getMeasuredHeight();
+ }
+ }
+
+ return new AuthDialog.LayoutParams(remeasuredWidth, remeasuredHeight);
+ }
+
+ private int getViewHeightPx(@IdRes int viewId) {
+ final View view = findViewById(viewId);
+ return view != null ? view.getMeasuredHeight() : 0;
+ }
+
+ private int getDialogMarginPx() {
+ return getResources().getDimensionPixelSize(R.dimen.biometric_dialog_border_padding);
+ }
+
+ @NonNull
+ private static Insets getNavbarInsets(@Nullable WindowManager windowManager) {
+ return windowManager != null && windowManager.getCurrentWindowMetrics() != null
+ ? windowManager.getCurrentWindowMetrics().getWindowInsets()
+ .getInsets(WindowInsets.Type.navigationBars())
+ : Insets.NONE;
+ }
+
+ @NonNull
+ private static Rect getWindowBounds(@Nullable WindowManager windowManager) {
+ return windowManager != null && windowManager.getCurrentWindowMetrics() != null
+ ? windowManager.getCurrentWindowMetrics().getBounds()
+ : new Rect();
+ }
+
+ /**
+ * For devices in portrait orientation where the sensor is too high up, calculates the amount of
+ * padding necessary to center the biometric icon within the sensor's physical location.
+ */
+ @VisibleForTesting
+ static int calculateBottomSpacerHeightForPortrait(
+ @NonNull FingerprintSensorPropertiesInternal sensorProperties, int displayHeightPx,
+ int textIndicatorHeightPx, int buttonBarHeightPx, int dialogMarginPx,
+ int navbarBottomInsetPx) {
+
+ final int sensorDistanceFromBottom = displayHeightPx
+ - sensorProperties.sensorLocationY
+ - sensorProperties.sensorRadius;
+
+ final int spacerHeight = sensorDistanceFromBottom
+ - textIndicatorHeightPx
+ - buttonBarHeightPx
+ - dialogMarginPx
+ - navbarBottomInsetPx;
+
+ Log.d(TAG, "Display height: " + displayHeightPx
+ + ", Distance from bottom: " + sensorDistanceFromBottom
+ + ", Bottom margin: " + dialogMarginPx
+ + ", Navbar bottom inset: " + navbarBottomInsetPx
+ + ", Bottom spacer height (portrait): " + spacerHeight);
+
+ return spacerHeight;
+ }
+
+ /**
+ * For devices in landscape orientation where the sensor is too high up, calculates the amount
+ * of padding necessary to center the biometric icon within the sensor's physical location.
+ */
+ @VisibleForTesting
+ static int calculateBottomSpacerHeightForLandscape(int titleHeightPx, int subtitleHeightPx,
+ int descriptionHeightPx, int topSpacerHeightPx, int textIndicatorHeightPx,
+ int buttonBarHeightPx, int navbarBottomInsetPx) {
+
+ final int dialogHeightAboveIcon = titleHeightPx
+ + subtitleHeightPx
+ + descriptionHeightPx
+ + topSpacerHeightPx;
+
+ final int dialogHeightBelowIcon = textIndicatorHeightPx + buttonBarHeightPx;
+
+ final int bottomSpacerHeight = dialogHeightAboveIcon
+ - dialogHeightBelowIcon
+ - navbarBottomInsetPx;
+
+ Log.d(TAG, "Title height: " + titleHeightPx
+ + ", Subtitle height: " + subtitleHeightPx
+ + ", Description height: " + descriptionHeightPx
+ + ", Top spacer height: " + topSpacerHeightPx
+ + ", Text indicator height: " + textIndicatorHeightPx
+ + ", Button bar height: " + buttonBarHeightPx
+ + ", Navbar bottom inset: " + navbarBottomInsetPx
+ + ", Bottom spacer height (landscape): " + bottomSpacerHeight);
+
+ return bottomSpacerHeight;
+ }
+
+ /**
+ * For devices in landscape orientation where the sensor is too left/right, calculates the
+ * amount of padding necessary to center the biometric icon within the sensor's physical
+ * location.
+ */
+ @VisibleForTesting
+ static int calculateHorizontalSpacerWidthForLandscape(
+ @NonNull FingerprintSensorPropertiesInternal sensorProperties, int displayWidthPx,
+ int dialogMarginPx, int navbarHorizontalInsetPx) {
+
+ final int sensorDistanceFromEdge = displayWidthPx
+ - sensorProperties.sensorLocationY
+ - sensorProperties.sensorRadius;
+
+ final int horizontalPadding = sensorDistanceFromEdge
+ - dialogMarginPx
+ - navbarHorizontalInsetPx;
+
+ Log.d(TAG, "Display width: " + displayWidthPx
+ + ", Distance from edge: " + sensorDistanceFromEdge
+ + ", Dialog margin: " + dialogMarginPx
+ + ", Navbar horizontal inset: " + navbarHorizontalInsetPx
+ + ", Horizontal spacer width (landscape): " + horizontalPadding);
+
+ return horizontalPadding;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index 18206efefe9a..d59a865e2add 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -742,6 +742,7 @@ public abstract class AuthBiometricView extends LinearLayout {
* @param height Height to constrain the measurements to.
* @return See {@link AuthDialog.LayoutParams}
*/
+ @NonNull
AuthDialog.LayoutParams onMeasureInternal(int width, int height) {
int totalHeight = 0;
final int numChildren = getChildCount();
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 935f89343754..d05e9278762d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -32,8 +32,10 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.UserManager;
import android.util.Log;
+import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
+import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
@@ -433,6 +435,29 @@ public class AuthContainerView extends LinearLayout
+ mConfig.mPromptInfo.getAuthenticators());
}
+ if (mBiometricView instanceof AuthBiometricUdfpsView) {
+ final int displayRotation = getDisplay().getRotation();
+ switch (displayRotation) {
+ case Surface.ROTATION_0:
+ mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM);
+ setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
+ break;
+ case Surface.ROTATION_90:
+ mPanelController.setPosition(AuthPanelController.POSITION_RIGHT);
+ setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT);
+ break;
+ case Surface.ROTATION_270:
+ mPanelController.setPosition(AuthPanelController.POSITION_LEFT);
+ setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
+ break;
+ default:
+ Log.e(TAG, "Unsupported display rotation: " + displayRotation);
+ mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM);
+ setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
+ break;
+ }
+ }
+
if (mConfig.mSkipIntro) {
mContainerState = STATE_SHOWING;
} else {
@@ -476,6 +501,13 @@ public class AuthContainerView extends LinearLayout
}
}
+ private void setScrollViewGravity(int gravity) {
+ final FrameLayout.LayoutParams params =
+ (FrameLayout.LayoutParams) mBiometricScrollView.getLayoutParams();
+ params.gravity = gravity;
+ mBiometricScrollView.setLayoutParams(params);
+ }
+
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
index 11503fbd0b1d..fa50f895f83e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
@@ -18,6 +18,7 @@ package com.android.systemui.biometrics;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
+import android.annotation.IntDef;
import android.content.Context;
import android.graphics.Outline;
import android.util.Log;
@@ -27,10 +28,20 @@ import android.view.animation.AccelerateDecelerateInterpolator;
import com.android.systemui.R;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Controls the back panel and its animations for the BiometricPrompt UI.
*/
public class AuthPanelController extends ViewOutlineProvider {
+ public static final int POSITION_BOTTOM = 1;
+ public static final int POSITION_LEFT = 2;
+ public static final int POSITION_RIGHT = 3;
+
+ @IntDef({POSITION_BOTTOM, POSITION_LEFT, POSITION_RIGHT})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Position {}
private static final String TAG = "BiometricPrompt/AuthPanelController";
private static final boolean DEBUG = false;
@@ -38,6 +49,7 @@ public class AuthPanelController extends ViewOutlineProvider {
private final Context mContext;
private final View mPanelView;
+ @Position private int mPosition = POSITION_BOTTOM;
private boolean mUseFullScreen;
private int mContainerWidth;
@@ -51,21 +63,44 @@ public class AuthPanelController extends ViewOutlineProvider {
@Override
public void getOutline(View view, Outline outline) {
- final int left = (mContainerWidth - mContentWidth) / 2;
- final int right = mContainerWidth - left;
-
- // If the content fits within the container, shrink the height to wrap the content.
- // Otherwise, set the outline to be the display size minus the margin - the content within
- // is scrollable.
- final int top = mContentHeight < mContainerHeight
- ? mContainerHeight - mContentHeight - mMargin
- : mMargin;
-
- // TODO(b/139954942) Likely don't need to "+1" after we resolve the navbar styling.
- final int bottom = mContainerHeight - mMargin + 1;
+ final int left = getLeftBound(mPosition);
+ final int right = left + mContentWidth;
+
+ // If the content fits in the container, shrink the height to wrap it. Otherwise, expand to
+ // fill the display (minus the margin), since the content is scrollable.
+ final int top = getTopBound(mPosition);
+ final int bottom = Math.min(top + mContentHeight, mContainerHeight - mMargin);
+
outline.setRoundRect(left, top, right, bottom, mCornerRadius);
}
+ private int getLeftBound(@Position int position) {
+ switch (position) {
+ case POSITION_BOTTOM:
+ return (mContainerWidth - mContentWidth) / 2;
+ case POSITION_LEFT:
+ return mMargin;
+ case POSITION_RIGHT:
+ return mContainerWidth - mContentWidth - mMargin;
+ default:
+ Log.e(TAG, "Unrecognized position: " + position);
+ return getLeftBound(POSITION_BOTTOM);
+ }
+ }
+
+ private int getTopBound(@Position int position) {
+ switch (position) {
+ case POSITION_BOTTOM:
+ return Math.max(mContainerHeight - mContentHeight - mMargin, mMargin);
+ case POSITION_LEFT:
+ case POSITION_RIGHT:
+ return Math.max((mContainerHeight - mContentHeight) / 2, mMargin);
+ default:
+ Log.e(TAG, "Unrecognized position: " + position);
+ return getTopBound(POSITION_BOTTOM);
+ }
+ }
+
public void setContainerDimensions(int containerWidth, int containerHeight) {
if (DEBUG) {
Log.v(TAG, "Container Width: " + containerWidth + " Height: " + containerHeight);
@@ -74,6 +109,10 @@ public class AuthPanelController extends ViewOutlineProvider {
mContainerHeight = containerHeight;
}
+ public void setPosition(@Position int position) {
+ mPosition = position;
+ }
+
public void setUseFullScreen(boolean fullScreen) {
mUseFullScreen = fullScreen;
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 1d789ca15dfb..4b6a8f639cc4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -451,6 +451,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
mStatusBar.addExpansionChangedListener(mStatusBarExpansionListener);
mStatusBarStateController.addCallback(mStatusBarStateListener);
+ mStatusBarStateListener.onStateChanged(mStatusBarStateController.getState());
mWindowManager.addView(mView, computeLayoutParams(animation));
mView.setOnTouchListener(mOnTouchListener);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
index 14eca1b1cb2c..667b7a7cf0a3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
@@ -122,6 +122,8 @@ public class UdfpsEnrollHelper {
@NonNull
PointF getNextGuidedEnrollmentPoint() {
final int index = mLocationsEnrolled - NUM_CENTER_TOUCHES;
- return mGuidedEnrollmentPoints.get(index % mGuidedEnrollmentPoints.size());
+ final PointF originalPoint = mGuidedEnrollmentPoints
+ .get(index % mGuidedEnrollmentPoints.size());
+ return new PointF(originalPoint.x * 0.5f, originalPoint.y * 0.5f);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java
index 64576a97ddb2..f7fe14a8e841 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java
@@ -22,7 +22,6 @@ import static com.android.systemui.classifier.FalsingModule.DOUBLE_TAP_TOUCH_SLO
import android.view.MotionEvent;
import java.util.List;
-import java.util.Queue;
import javax.inject.Inject;
import javax.inject.Named;
@@ -49,8 +48,7 @@ public class DoubleTapClassifier extends FalsingClassifier {
@Override
Result calculateFalsingResult(double historyPenalty, double historyConfidence) {
List<MotionEvent> secondTapEvents = getRecentMotionEvents();
- Queue<? extends List<MotionEvent>> historicalEvents = getHistoricalEvents();
- List<MotionEvent> firstTapEvents = historicalEvents.peek();
+ List<MotionEvent> firstTapEvents = getPriorMotionEvents();
StringBuilder reason = new StringBuilder();
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java
index dbfeacfa91c4..f40045b0f08e 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java
@@ -21,7 +21,6 @@ import android.view.MotionEvent;
import com.android.systemui.util.sensors.ProximitySensor;
import java.util.List;
-import java.util.Queue;
/**
* Base class for rules that determine False touches.
@@ -40,8 +39,8 @@ public abstract class FalsingClassifier {
return mDataProvider.getRecentMotionEvents();
}
- Queue<? extends List<MotionEvent>> getHistoricalEvents() {
- return mDataProvider.getHistoricalMotionEvents();
+ List<MotionEvent> getPriorMotionEvents() {
+ return mDataProvider.getPriorMotionEvents();
}
MotionEvent getFirstMotionEvent() {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index 4bacc1598490..336f13f117d3 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -23,13 +23,9 @@ import android.view.MotionEvent.PointerProperties;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.util.time.SystemClock;
import java.util.ArrayList;
-import java.util.Deque;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Queue;
import javax.inject.Inject;
@@ -40,24 +36,23 @@ import javax.inject.Inject;
public class FalsingDataProvider {
private static final long MOTION_EVENT_AGE_MS = 1000;
- private static final long EXTENDED_MOTION_EVENT_AGE_MS = 30 * 1000;
private static final float THREE_HUNDRED_SIXTY_DEG = (float) (2 * Math.PI);
private final int mWidthPixels;
private final int mHeightPixels;
private final BatteryController mBatteryController;
- private final SystemClock mSystemClock;
private final float mXdpi;
private final float mYdpi;
private final List<SessionListener> mSessionListeners = new ArrayList<>();
private final List<MotionEventListener> mMotionEventListeners = new ArrayList<>();
- private final List<GestureCompleteListener> mGestuerCompleteListeners = new ArrayList<>();
+ private final List<GestureCompleteListener> mGestureCompleteListeners = new ArrayList<>();
private @Classifier.InteractionType int mInteractionType;
- private final Deque<TimeLimitedMotionEventBuffer> mExtendedMotionEvents = new LinkedList<>();
private TimeLimitedMotionEventBuffer mRecentMotionEvents =
new TimeLimitedMotionEventBuffer(MOTION_EVENT_AGE_MS);
+ private List<MotionEvent> mPriorMotionEvents;
+
private boolean mDirty = true;
private float mAngle = 0;
@@ -66,14 +61,12 @@ public class FalsingDataProvider {
private boolean mJustUnlockedWithFace;
@Inject
- public FalsingDataProvider(DisplayMetrics displayMetrics, BatteryController batteryController,
- SystemClock systemClock) {
+ public FalsingDataProvider(DisplayMetrics displayMetrics, BatteryController batteryController) {
mXdpi = displayMetrics.xdpi;
mYdpi = displayMetrics.ydpi;
mWidthPixels = displayMetrics.widthPixels;
mHeightPixels = displayMetrics.heightPixels;
mBatteryController = batteryController;
- mSystemClock = systemClock;
FalsingClassifier.logInfo("xdpi, ydpi: " + getXdpi() + ", " + getYdpi());
FalsingClassifier.logInfo("width, height: " + getWidthPixels() + ", " + getHeightPixels());
@@ -111,10 +104,10 @@ public class FalsingDataProvider {
private void completePriorGesture() {
if (!mRecentMotionEvents.isEmpty()) {
- mGestuerCompleteListeners.forEach(listener -> listener.onGestureComplete(
+ mGestureCompleteListeners.forEach(listener -> listener.onGestureComplete(
mRecentMotionEvents.get(mRecentMotionEvents.size() - 1).getEventTime()));
- mExtendedMotionEvents.addFirst(mRecentMotionEvents);
+ mPriorMotionEvents = mRecentMotionEvents;
}
}
@@ -140,14 +133,8 @@ public class FalsingDataProvider {
return mRecentMotionEvents;
}
- /** Returns recent gestures, exclusive of the most recent gesture. Newer gestures come first. */
- public Queue<? extends List<MotionEvent>> getHistoricalMotionEvents() {
- long nowMs = mSystemClock.uptimeMillis();
-
- mExtendedMotionEvents.removeIf(
- motionEvents -> motionEvents.isFullyExpired(nowMs - EXTENDED_MOTION_EVENT_AGE_MS));
-
- return mExtendedMotionEvents;
+ public List<MotionEvent> getPriorMotionEvents() {
+ return mPriorMotionEvents;
}
/**
@@ -344,12 +331,12 @@ public class FalsingDataProvider {
/** Register a {@link GestureCompleteListener}. */
public void addGestureCompleteListener(GestureCompleteListener listener) {
- mGestuerCompleteListeners.add(listener);
+ mGestureCompleteListeners.add(listener);
}
/** Unregister a {@link GestureCompleteListener}. */
public void removeGestureCompleteListener(GestureCompleteListener listener) {
- mGestuerCompleteListeners.remove(listener);
+ mGestureCompleteListeners.remove(listener);
}
void onSessionStarted() {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
index 7969b4e83ac0..e5da38936593 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
@@ -42,18 +42,6 @@ public class TimeLimitedMotionEventBuffer implements List<MotionEvent> {
mMotionEvents = new LinkedList<>();
}
- /**
- * Returns true if the most recent event in the buffer is past the expiration time.
- *
- * This method does not mutate the underlying data. This method does imply that, if the supplied
- * expiration time is old enough and a new {@link MotionEvent} gets added to the buffer, all
- * prior events would be removed.
- */
- public boolean isFullyExpired(long expirationMs) {
- return mMotionEvents.isEmpty()
- || mMotionEvents.getLast().getEventTime() <= expirationMs;
- }
-
private void ejectOldEvents() {
if (mMotionEvents.isEmpty()) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
index fbdeb30d3911..ed625de9dce8 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
@@ -31,6 +31,7 @@ import com.android.systemui.controls.management.ControlsProviderSelectorActivity
import com.android.systemui.controls.management.ControlsRequestDialog
import com.android.systemui.controls.ui.ControlActionCoordinator
import com.android.systemui.controls.ui.ControlActionCoordinatorImpl
+import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.controls.ui.ControlsUiControllerImpl
import com.android.systemui.dagger.SysUISingleton
@@ -113,4 +114,9 @@ abstract class ControlsModule {
abstract fun provideControlsRequestDialog(
activity: ControlsRequestDialog
): Activity
+
+ @Binds
+ @IntoMap
+ @ClassKey(ControlsActivity::class)
+ abstract fun provideControlsActivity(activity: ControlsActivity): Activity
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
index fc89783018bc..7dd1d28170b2 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
@@ -32,7 +32,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.controls.CustomIconCache
import com.android.systemui.controls.controller.ControlsControllerImpl
import com.android.systemui.controls.controller.StructureInfo
-import com.android.systemui.controls.ui.ControlsDialog
+import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.globalactions.GlobalActionsComponent
import com.android.systemui.settings.CurrentUserTracker
@@ -112,7 +112,11 @@ class ControlsEditingActivity @Inject constructor(
if (backToGlobalActions) {
globalActionsComponent.handleShowGlobalActionsMenu()
} else {
- ControlsDialog(applicationContext, broadcastDispatcher).show(uiController)
+ val i = Intent().apply {
+ component = ComponentName(applicationContext, ControlsActivity::class.java)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ startActivity(i)
}
animateExitAndFinish()
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
index 2d647a907b17..309901443393 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
@@ -40,7 +40,7 @@ import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.TooltipManager
import com.android.systemui.controls.controller.ControlsControllerImpl
import com.android.systemui.controls.controller.StructureInfo
-import com.android.systemui.controls.ui.ControlsDialog
+import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.globalactions.GlobalActionsComponent
@@ -352,7 +352,11 @@ class ControlsFavoritingActivity @Inject constructor(
if (backToGlobalActions) {
globalActionsComponent.handleShowGlobalActionsMenu()
} else {
- ControlsDialog(applicationContext, broadcastDispatcher).show(uiController)
+ val i = Intent().apply {
+ component = ComponentName(applicationContext, ControlsActivity::class.java)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ startActivity(i)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
index d5e41d031eac..fa1c41f01e6c 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
@@ -32,7 +32,7 @@ import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver
import com.android.systemui.R
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.controls.controller.ControlsController
-import com.android.systemui.controls.ui.ControlsDialog
+import com.android.systemui.controls.ui.ControlsActivity
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -116,7 +116,11 @@ class ControlsProviderSelectorActivity @Inject constructor(
if (backToGlobalActions) {
globalActionsComponent.handleShowGlobalActionsMenu()
} else {
- ControlsDialog(applicationContext, broadcastDispatcher).show(uiController)
+ val i = Intent().apply {
+ component = ComponentName(applicationContext, ControlsActivity::class.java)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ startActivity(i)
}
animateExitAndFinish()
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
index d06568a7caf9..0db15e83fc93 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
@@ -16,6 +16,7 @@
package com.android.systemui.controls.ui
+import android.content.Context
import android.service.controls.Control
/**
@@ -24,8 +25,8 @@ import android.service.controls.Control
*/
interface ControlActionCoordinator {
- // Handle actions launched from GlobalActionsDialog or ControlDialog
- var startedFromGlobalActions: Boolean
+ // If launched from an Activity, continue within this stack
+ var activityContext: Context?
/**
* Close any dialogs which may have been open
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
index 6b300f4e07e4..58a5981845c7 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
@@ -18,6 +18,7 @@ package com.android.systemui.controls.ui
import android.annotation.MainThread
import android.app.Dialog
+import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
@@ -60,7 +61,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
private var pendingAction: Action? = null
private var actionsInProgress = mutableSetOf<String>()
- override var startedFromGlobalActions: Boolean = true
+ override var activityContext: Context? = null
companion object {
private const val RESPONSE_TIMEOUT_IN_MILLIS = 3000L
@@ -83,7 +84,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
bouncerOrRun(createAction(cvh.cws.ci.controlId, {
cvh.layout.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK)
if (cvh.usePanel()) {
- showDialog(cvh, control.getAppIntent().getIntent())
+ showDetail(cvh, control.getAppIntent().getIntent())
} else {
cvh.action(CommandAction(templateId))
}
@@ -109,7 +110,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
// Long press snould only be called when there is valid control state, otherwise ignore
cvh.cws.control?.let {
cvh.layout.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
- showDialog(cvh, it.getAppIntent().getIntent())
+ showDetail(cvh, it.getAppIntent().getIntent())
}
}, false /* blockable */))
}
@@ -151,10 +152,16 @@ class ControlActionCoordinatorImpl @Inject constructor(
activityStarter.dismissKeyguardThenExecute({
Log.d(ControlsUiController.TAG, "Device unlocked, invoking controls action")
if (closeDialog) {
- if (startedFromGlobalActions) {
+ activityContext?.let {
+ val i = Intent().apply {
+ component = ComponentName(context, ControlsActivity::class.java)
+ addFlags(
+ Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+ putExtra(ControlsUiController.BACK_TO_GLOBAL_ACTIONS, false)
+ }
+ it.startActivity(i)
+ } ?: run {
globalActionsComponent.handleShowGlobalActionsMenu()
- } else {
- ControlsDialog(context, broadcastDispatcher).show(lazyUiController.get())
}
} else {
action.invoke()
@@ -170,9 +177,9 @@ class ControlActionCoordinatorImpl @Inject constructor(
bgExecutor.execute { vibrator.vibrate(effect) }
}
- private fun showDialog(cvh: ControlViewHolder, intent: Intent) {
+ private fun showDetail(cvh: ControlViewHolder, intent: Intent) {
bgExecutor.execute {
- val activities: List<ResolveInfo> = cvh.context.packageManager.queryIntentActivities(
+ val activities: List<ResolveInfo> = context.packageManager.queryIntentActivities(
intent,
PackageManager.MATCH_DEFAULT_ONLY
)
@@ -180,8 +187,8 @@ class ControlActionCoordinatorImpl @Inject constructor(
uiExecutor.execute {
// make sure the intent is valid before attempting to open the dialog
if (activities.isNotEmpty() && taskViewFactory.isPresent) {
- taskViewFactory.get().create(cvh.context, uiExecutor, {
- dialog = DetailDialog(cvh, it, intent).also {
+ taskViewFactory.get().create(context, uiExecutor, {
+ dialog = DetailDialog(activityContext, it, intent, cvh).also {
it.setOnDismissListener { _ -> dialog = null }
it.show()
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
new file mode 100644
index 000000000000..a35b792ac7f1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.controls.ui
+
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowInsets
+import android.view.WindowInsets.Type
+
+import com.android.systemui.R
+import com.android.systemui.controls.management.ControlsAnimations
+import com.android.systemui.util.LifecycleActivity
+import javax.inject.Inject
+
+/**
+ * Displays Device Controls inside an activity
+ */
+class ControlsActivity @Inject constructor(
+ private val uiController: ControlsUiController
+) : LifecycleActivity() {
+
+ private lateinit var parent: ViewGroup
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContentView(R.layout.controls_fullscreen)
+
+ requireViewById<ViewGroup>(R.id.control_detail_root).apply {
+ setOnApplyWindowInsetsListener {
+ v: View, insets: WindowInsets ->
+ v.apply {
+ val l = getPaddingLeft()
+ val t = getPaddingTop()
+ val r = getPaddingRight()
+ setPadding(l, t, r, insets.getInsets(Type.systemBars()).bottom)
+ }
+
+ WindowInsets.CONSUMED
+ }
+ }
+ }
+
+ override fun onStart() {
+ super.onStart()
+
+ parent = requireViewById<ViewGroup>(R.id.global_actions_controls)
+ parent.alpha = 0f
+ uiController.show(parent, { animateExitAndFinish() }, this)
+ }
+
+ override fun onResume() {
+ super.onResume()
+
+ ControlsAnimations.enterAnimation(parent).start()
+ }
+
+ override fun onBackPressed() {
+ animateExitAndFinish()
+ }
+
+ override fun onStop() {
+ super.onStop()
+
+ uiController.hide()
+ }
+
+ private fun animateExitAndFinish() {
+ ControlsAnimations.exitAnimation(parent, { finish() }).start()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialog.kt
deleted file mode 100644
index 537334aeb2f7..000000000000
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsDialog.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.controls.ui
-
-import android.app.Dialog
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.view.View
-import android.view.ViewGroup
-import android.view.WindowManager
-
-import com.android.systemui.Interpolators
-import com.android.systemui.R
-import com.android.systemui.broadcast.BroadcastDispatcher
-import javax.inject.Inject
-
-/**
- * Show the controls space inside a dialog, as from the lock screen.
- */
-class ControlsDialog @Inject constructor(
- thisContext: Context,
- val broadcastDispatcher: BroadcastDispatcher
-) : Dialog(thisContext, R.style.Theme_SystemUI_Dialog_Control_LockScreen) {
-
- private val receiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- val action = intent.getAction()
- if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
- dismiss()
- }
- }
- }
-
- init {
- window.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG)
- window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
- or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
-
- setContentView(R.layout.controls_in_dialog)
-
- requireViewById<ViewGroup>(R.id.control_detail_root).apply {
- setOnClickListener { dismiss() }
- (getParent() as View).setOnClickListener { dismiss() }
- }
- }
-
- fun show(
- controller: ControlsUiController
- ): ControlsDialog {
- super.show()
-
- val vg = requireViewById<ViewGroup>(com.android.systemui.R.id.global_actions_controls)
- vg.alpha = 0f
- controller.show(vg, { dismiss() }, false /* startedFromGlobalActions */)
-
- vg.animate()
- .alpha(1f)
- .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
- .setDuration(300)
-
- val filter = IntentFilter()
- filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
- broadcastDispatcher.registerReceiver(receiver, filter)
-
- return this
- }
-
- override fun dismiss() {
- broadcastDispatcher.unregisterReceiver(receiver)
-
- if (!isShowing()) return
-
- super.dismiss()
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
index 20bdf609357e..f86948ee8957 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
@@ -17,6 +17,7 @@
package com.android.systemui.controls.ui
import android.content.ComponentName
+import android.content.Context
import android.service.controls.Control
import android.service.controls.actions.ControlAction
import android.view.ViewGroup
@@ -30,7 +31,7 @@ interface ControlsUiController {
public const val BACK_TO_GLOBAL_ACTIONS = "back_to_global_actions"
}
- fun show(parent: ViewGroup, onDismiss: Runnable, startedFromGlobalActions: Boolean)
+ fun show(parent: ViewGroup, onDismiss: Runnable, activityContext: Context?)
fun hide()
/**
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index c94d85aa58c4..0f7f48ff951a 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -148,7 +148,7 @@ class ControlsUiControllerImpl @Inject constructor (
override fun show(
parent: ViewGroup,
onDismiss: Runnable,
- startedFromGlobalActions: Boolean
+ activityContext: Context?
) {
Log.d(ControlsUiController.TAG, "show()")
this.parent = parent
@@ -156,7 +156,7 @@ class ControlsUiControllerImpl @Inject constructor (
hidden = false
retainCache = false
- controlActionCoordinator.startedFromGlobalActions = startedFromGlobalActions
+ controlActionCoordinator.activityContext = activityContext
allStructures = controlsController.get().getFavorites()
selectedStructure = loadPreference(allStructures)
@@ -193,7 +193,7 @@ class ControlsUiControllerImpl @Inject constructor (
controlViewsById.clear()
controlsById.clear()
- show(parent, onDismiss, controlActionCoordinator.startedFromGlobalActions)
+ show(parent, onDismiss, controlActionCoordinator.activityContext)
val showAnim = ObjectAnimator.ofFloat(parent, "alpha", 0.0f, 1.0f)
showAnim.setInterpolator(DecelerateInterpolator(1.0f))
showAnim.setDuration(FADE_IN_MILLIS)
@@ -268,7 +268,7 @@ class ControlsUiControllerImpl @Inject constructor (
intent.putExtra(ControlsUiController.EXTRA_ANIMATE, true)
intent.putExtra(
ControlsUiController.BACK_TO_GLOBAL_ACTIONS,
- controlActionCoordinator.startedFromGlobalActions
+ controlActionCoordinator.activityContext == null
)
onDismiss.run()
@@ -392,6 +392,17 @@ class ControlsUiControllerImpl @Inject constructor (
val inflater = LayoutInflater.from(context)
inflater.inflate(R.layout.controls_with_favorites, parent, true)
+ if (controlActionCoordinator.activityContext == null) {
+ parent.requireViewById<View>(R.id.controls_spacer).apply {
+ visibility = View.VISIBLE
+ }
+ } else {
+ parent.requireViewById<ImageView>(R.id.controls_close).apply {
+ setOnClickListener { _: View -> onDismiss.run() }
+ visibility = View.VISIBLE
+ }
+ }
+
val maxColumns = findMaxColumns()
val listView = parent.requireViewById(R.id.global_actions_controls_list) as ViewGroup
@@ -502,6 +513,8 @@ class ControlsUiControllerImpl @Inject constructor (
override fun hide() {
hidden = true
+ controlActionCoordinator.activityContext = null
+
closeDialogs(true)
controlsController.get().unsubscribe()
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
index 020694d89fce..9c788df362de 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -22,8 +22,8 @@ import android.app.ActivityTaskManager.INVALID_TASK_ID
import android.app.Dialog
import android.app.PendingIntent
import android.content.ComponentName
+import android.content.Context
import android.content.Intent
-import android.provider.Settings
import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
@@ -35,18 +35,20 @@ import com.android.systemui.R
import com.android.wm.shell.TaskView
/**
- * A dialog that provides an {@link ActivityView}, allowing the application to provide
+ * A dialog that provides an {@link TaskView}, allowing the application to provide
* additional information and actions pertaining to a {@link android.service.controls.Control}.
* The activity being launched is specified by {@link android.service.controls.Control#getAppIntent}.
*/
class DetailDialog(
- val cvh: ControlViewHolder,
- val activityView: TaskView,
- val intent: Intent
-) : Dialog(cvh.context, R.style.Theme_SystemUI_Dialog_Control_DetailPanel) {
-
+ val activityContext: Context?,
+ val taskView: TaskView,
+ val intent: Intent,
+ val cvh: ControlViewHolder
+) : Dialog(
+ activityContext ?: cvh.context,
+ R.style.Theme_SystemUI_Dialog_Control_DetailPanel
+) {
companion object {
- private const val PANEL_TOP_OFFSET = "systemui.controls_panel_top_offset"
/*
* Indicate to the activity that it is being rendered in a bottomsheet, and they
* should optimize the layout for a smaller space.
@@ -71,10 +73,19 @@ class DetailDialog(
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
launchIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
- activityView.startActivity(
- PendingIntent.getActivity(context, 0, launchIntent,
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE),
- null, ActivityOptions.makeBasic())
+ val options = activityContext?.let {
+ ActivityOptions.makeCustomAnimation(
+ it,
+ 0 /* enterResId */,
+ 0 /* exitResId */
+ )
+ } ?: ActivityOptions.makeBasic()
+ taskView.startActivity(
+ PendingIntent.getActivity(context, 0, launchIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE),
+ null,
+ options
+ )
}
override fun onTaskRemovalStarted(taskId: Int) {
@@ -92,7 +103,10 @@ class DetailDialog(
}
init {
- window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY)
+ if (activityContext == null) {
+ window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY)
+ }
+
// To pass touches to the task inside TaskView.
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY)
@@ -100,7 +114,7 @@ class DetailDialog(
setContentView(R.layout.controls_detail_dialog)
requireViewById<ViewGroup>(R.id.controls_activity_view).apply {
- addView(activityView)
+ addView(taskView)
}
requireViewById<ImageView>(R.id.control_detail_close).apply {
@@ -120,48 +134,34 @@ class DetailDialog(
// consume all insets to achieve slide under effect
window.getDecorView().setOnApplyWindowInsetsListener {
- _: View, insets: WindowInsets ->
- activityView.apply {
+ v: View, insets: WindowInsets ->
+ taskView.apply {
val l = getPaddingLeft()
val t = getPaddingTop()
val r = getPaddingRight()
setPadding(l, t, r, insets.getInsets(Type.systemBars()).bottom)
}
- WindowInsets.CONSUMED
- }
-
- requireViewById<ViewGroup>(R.id.control_detail_root).apply {
- // use flag only temporarily for testing
- val resolver = cvh.context.contentResolver
- val defaultOffsetInPx = cvh.context.resources
- .getDimensionPixelSize(R.dimen.controls_activity_view_top_offset)
- val offsetInPx = Settings.Secure.getInt(resolver, PANEL_TOP_OFFSET, defaultOffsetInPx)
-
- val lp = getLayoutParams() as ViewGroup.MarginLayoutParams
- lp.topMargin = offsetInPx
- setLayoutParams(lp)
+ val l = v.getPaddingLeft()
+ val b = v.getPaddingBottom()
+ val r = v.getPaddingRight()
+ v.setPadding(l, insets.getInsets(Type.systemBars()).top, r, b)
- setOnClickListener { dismiss() }
- (getParent() as View).setOnClickListener { dismiss() }
+ WindowInsets.CONSUMED
}
if (ScreenDecorationsUtils.supportsRoundedCornersOnWindows(context.getResources())) {
val cornerRadius = context.resources
.getDimensionPixelSize(R.dimen.controls_activity_view_corner_radius)
- activityView.setCornerRadius(cornerRadius.toFloat())
+ taskView.setCornerRadius(cornerRadius.toFloat())
}
- }
-
- override fun show() {
- activityView.setListener(cvh.uiExecutor, stateCallback)
- super.show()
+ taskView.setListener(cvh.uiExecutor, stateCallback)
}
override fun dismiss() {
if (!isShowing()) return
- activityView.release()
+ taskView.release()
super.dismiss()
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index c26cc4466c6d..d8ade2bdd21f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -225,8 +225,8 @@ public class DozeLog implements Dumpable {
* Appends wake-display event to the logs.
* @param wake if we're waking up or sleeping.
*/
- public void traceWakeDisplay(boolean wake) {
- mLogger.logWakeDisplay(wake);
+ public void traceWakeDisplay(boolean wake, @Reason int reason) {
+ mLogger.logWakeDisplay(wake, reason);
}
/**
@@ -380,6 +380,7 @@ public class DozeLog implements Dumpable {
case REASON_SENSOR_WAKE_UP: return "wakeup";
case REASON_SENSOR_TAP: return "tap";
case REASON_SENSOR_UDFPS_LONG_PRESS: return "udfps";
+ case REASON_SENSOR_QUICK_PICKUP: return "quickPickup";
default: throw new IllegalArgumentException("invalid reason: " + pulseReason);
}
}
@@ -389,7 +390,7 @@ public class DozeLog implements Dumpable {
PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP,
PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP,
PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, REASON_SENSOR_TAP,
- REASON_SENSOR_UDFPS_LONG_PRESS})
+ REASON_SENSOR_UDFPS_LONG_PRESS, REASON_SENSOR_QUICK_PICKUP})
public @interface Reason {}
public static final int PULSE_REASON_NONE = -1;
public static final int PULSE_REASON_INTENT = 0;
@@ -403,6 +404,7 @@ public class DozeLog implements Dumpable {
public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8;
public static final int REASON_SENSOR_TAP = 9;
public static final int REASON_SENSOR_UDFPS_LONG_PRESS = 10;
+ public static final int REASON_SENSOR_QUICK_PICKUP = 11;
- public static final int TOTAL_REASONS = 11;
+ public static final int TOTAL_REASONS = 12;
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
index fddefae6f5b6..9bc74be9b9c3 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
@@ -16,6 +16,7 @@
package com.android.systemui.doze
+import android.view.Display
import com.android.systemui.doze.DozeLog.Reason
import com.android.systemui.doze.DozeLog.reasonToString
import com.android.systemui.log.LogBuffer
@@ -161,17 +162,18 @@ class DozeLogger @Inject constructor(
fun logDisplayStateChanged(displayState: Int) {
buffer.log(TAG, INFO, {
- int1 = displayState
+ str1 = Display.stateToString(displayState)
}, {
- "Display state changed to $int1"
+ "Display state changed to $str1"
})
}
- fun logWakeDisplay(isAwake: Boolean) {
+ fun logWakeDisplay(isAwake: Boolean, @Reason reason: Int) {
buffer.log(TAG, DEBUG, {
bool1 = isAwake
+ int1 = reason
}, {
- "Display wakefulness changed, isAwake=$bool1"
+ "Display wakefulness changed, isAwake=$bool1, reason=${reasonToString(int1)}"
})
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index c542e5b07d9b..52c9f164a16e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -113,6 +113,8 @@ public class DozeSensors {
mCallback = callback;
mProximitySensor = proximitySensor;
+ boolean udfpsEnrolled =
+ authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser());
boolean alwaysOn = mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT);
mSensors = new TriggerSensor[] {
new TriggerSensor(
@@ -159,7 +161,7 @@ public class DozeSensors {
findSensorWithType(config.udfpsLongPressSensorType()),
"doze_pulse_on_auth",
true /* settingDef */,
- authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser()),
+ udfpsEnrolled,
DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS,
true /* reports touch coordinates */,
true /* touchscreen */,
@@ -181,6 +183,15 @@ public class DozeSensors {
false /* touchscreen */,
mConfig.getWakeLockScreenDebounce(),
dozeLog),
+ new TriggerSensor(
+ findSensorWithType(config.quickPickupSensorType()),
+ Settings.Secure.DOZE_QUICK_PICKUP_GESTURE,
+ false /* setting default */,
+ config.quickPickupSensorEnabled(KeyguardUpdateMonitor.getCurrentUser())
+ && udfpsEnrolled,
+ DozeLog.REASON_SENSOR_QUICK_PICKUP,
+ false /* touchCoords */,
+ false /* touchscreen */, dozeLog),
};
setProxListening(false); // Don't immediately start listening when we register.
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index c617f3d751d0..04b46705226f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -42,10 +42,13 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.doze.dagger.DozeScope;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.util.Assert;
+import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.settings.SecureSettings;
@@ -76,6 +79,7 @@ public class DozeTriggers implements DozeMachine.Part {
* Assuming that the screen should start on.
*/
private static boolean sWakeDisplaySensorState = true;
+ private Runnable mQuickPickupDozeCancellable;
private static final int PROXIMITY_TIMEOUT_DELAY_MS = 500;
@@ -96,6 +100,8 @@ public class DozeTriggers implements DozeMachine.Part {
private final ProximitySensor.ProximityCheck mProxCheck;
private final BroadcastDispatcher mBroadcastDispatcher;
private final AuthController mAuthController;
+ private final DelayableExecutor mMainExecutor;
+ private final DelayableExecutor mBgExecutor;
private long mNotificationPulseTime;
private boolean mPulsePending;
@@ -135,7 +141,10 @@ public class DozeTriggers implements DozeMachine.Part {
DOZING_UPDATE_SENSOR_TAP(441),
@UiEvent(doc = "Dozing updated because on display auth was triggered from AOD.")
- DOZING_UPDATE_AUTH_TRIGGERED(657);
+ DOZING_UPDATE_AUTH_TRIGGERED(657),
+
+ @UiEvent(doc = "Dozing updated because quick pickup sensor woke up.")
+ DOZING_UPDATE_QUICK_PICKUP(708);
private final int mId;
@@ -160,6 +169,7 @@ public class DozeTriggers implements DozeMachine.Part {
case 8: return DOZING_UPDATE_SENSOR_WAKE_LOCKSCREEN;
case 9: return DOZING_UPDATE_SENSOR_TAP;
case 10: return DOZING_UPDATE_AUTH_TRIGGERED;
+ case 11: return DOZING_UPDATE_QUICK_PICKUP;
default: return null;
}
}
@@ -172,7 +182,8 @@ public class DozeTriggers implements DozeMachine.Part {
WakeLock wakeLock, DockManager dockManager,
ProximitySensor proximitySensor, ProximitySensor.ProximityCheck proxCheck,
DozeLog dozeLog, BroadcastDispatcher broadcastDispatcher,
- SecureSettings secureSettings, AuthController authController) {
+ SecureSettings secureSettings, AuthController authController,
+ @Main DelayableExecutor mainExecutor, @Background DelayableExecutor bgExecutor) {
mContext = context;
mDozeHost = dozeHost;
mConfig = config;
@@ -189,6 +200,8 @@ public class DozeTriggers implements DozeMachine.Part {
mDozeLog = dozeLog;
mBroadcastDispatcher = broadcastDispatcher;
mAuthController = authController;
+ mMainExecutor = mainExecutor;
+ mBgExecutor = bgExecutor;
}
@Override
@@ -262,18 +275,22 @@ public class DozeTriggers implements DozeMachine.Part {
boolean isTap = pulseReason == DozeLog.REASON_SENSOR_TAP;
boolean isPickup = pulseReason == DozeLog.REASON_SENSOR_PICKUP;
boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS;
- boolean isWakeDisplay = pulseReason == DozeLog.REASON_SENSOR_WAKE_UP;
- boolean isWakeLockScreen = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
+ boolean isWakeOnPresence = pulseReason == DozeLog.REASON_SENSOR_WAKE_UP;
+ boolean isWakeOnReach = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
boolean isUdfpsLongPress = pulseReason == DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS;
- boolean wakeEvent = rawValues != null && rawValues.length > 0 && rawValues[0] != 0;
-
- if (isWakeDisplay) {
- onWakeScreen(wakeEvent, mMachine.isExecutingTransition() ? null : mMachine.getState());
+ boolean isQuickPickup = pulseReason == DozeLog.REASON_SENSOR_QUICK_PICKUP;
+ boolean isWakeDisplayEvent = isQuickPickup || ((isWakeOnPresence || isWakeOnReach)
+ && rawValues != null && rawValues.length > 0 && rawValues[0] != 0);
+
+ if (isWakeOnPresence || isQuickPickup) {
+ onWakeScreen(isQuickPickup || isWakeDisplayEvent,
+ mMachine.isExecutingTransition() ? null : mMachine.getState(),
+ pulseReason);
} else if (isLongPress) {
requestPulse(pulseReason, true /* alreadyPerformedProxCheck */,
null /* onPulseSuppressedListener */);
- } else if (isWakeLockScreen) {
- if (wakeEvent) {
+ } else if (isWakeOnReach) {
+ if (isWakeDisplayEvent) {
requestPulse(pulseReason, true /* alreadyPerformedProxCheck */,
null /* onPulseSuppressedListener */);
}
@@ -370,13 +387,17 @@ public class DozeTriggers implements DozeMachine.Part {
* @param state The current state, or null if the state could not be determined due to enqueued
* transitions.
*/
- private void onWakeScreen(boolean wake, @Nullable DozeMachine.State state) {
- mDozeLog.traceWakeDisplay(wake);
- sWakeDisplaySensorState = wake;
+ private void onWakeScreen(boolean wake, @Nullable DozeMachine.State state, int reason) {
+ mDozeLog.traceWakeDisplay(wake, reason);
+ final boolean isWakeOnPresence = reason == DozeLog.REASON_SENSOR_WAKE_UP;
+ final boolean isQuickPickup = reason == DozeLog.REASON_SENSOR_QUICK_PICKUP;
+ if (isWakeOnPresence) {
+ sWakeDisplaySensorState = wake;
+ }
if (wake) {
proximityCheckThenCall((result) -> {
- if (result != null && result) {
+ if (result != null && result) {
// In pocket, drop event.
return;
}
@@ -385,26 +406,51 @@ public class DozeTriggers implements DozeMachine.Part {
// Logs AOD open due to sensor wake up.
mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
.setType(MetricsEvent.TYPE_OPEN)
- .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP));
+ .setSubtype(reason));
+
+ if (isQuickPickup) {
+ // schedule runnable to go back to DOZE
+ onQuickPickup();
+ }
+ } else if (state == DozeMachine.State.DOZE_AOD && isQuickPickup) {
+ // elongate time in DOZE_AOD, schedule new runnable to go back to DOZE
+ onQuickPickup();
}
- }, true /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP);
+ }, isQuickPickup /* alreadyPerformedProxCheck */, reason);
} else {
boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
+ boolean pulse = (state == DozeMachine.State.DOZE_REQUEST_PULSE)
+ || (state == DozeMachine.State.DOZE_PULSING)
+ || (state == DozeMachine.State.DOZE_PULSING_BRIGHT);
+ boolean docked = (state == DozeMachine.State.DOZE_AOD_DOCKED);
if (!pausing && !paused) {
+ if (isQuickPickup && (pulse || docked)) {
+ return;
+ }
mMachine.requestState(DozeMachine.State.DOZE);
// Logs AOD close due to sensor wake up.
mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
.setType(MetricsEvent.TYPE_CLOSE)
- .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP));
+ .setSubtype(reason));
}
}
}
+ private void onQuickPickup() {
+ cancelQuickPickupDelayableDoze();
+ mQuickPickupDozeCancellable = mMainExecutor.executeDelayed(() -> {
+ onWakeScreen(false,
+ mMachine.isExecutingTransition() ? null : mMachine.getState(),
+ DozeLog.REASON_SENSOR_QUICK_PICKUP);
+ }, mDozeParameters.getQuickPickupAodDuration());
+ }
+
@Override
public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
switch (newState) {
case INITIALIZED:
+ sWakeDisplaySensorState = true;
mBroadcastReceiver.register(mBroadcastDispatcher);
mDozeHost.addCallback(mHostCallback);
mDockManager.addListener(mDockEventListener);
@@ -417,7 +463,7 @@ public class DozeTriggers implements DozeMachine.Part {
mWantSensors = true;
mWantTouchScreenSensors = true;
if (newState == DozeMachine.State.DOZE_AOD && !sWakeDisplaySensorState) {
- onWakeScreen(false, newState);
+ onWakeScreen(false, newState, DozeLog.REASON_SENSOR_WAKE_UP);
}
break;
case DOZE_AOD_PAUSED:
@@ -437,6 +483,7 @@ public class DozeTriggers implements DozeMachine.Part {
mDozeSensors.requestTemporaryDisable();
break;
case FINISH:
+ cancelQuickPickupDelayableDoze();
mBroadcastReceiver.unregister(mBroadcastDispatcher);
mDozeHost.removeCallback(mHostCallback);
mDockManager.removeListener(mDockEventListener);
@@ -460,6 +507,17 @@ public class DozeTriggers implements DozeMachine.Part {
mDozeSensors.setListening(mWantSensors, mWantTouchScreenSensors);
}
+ /**
+ * Cancels last scheduled Runnable that transitions to STATE_DOZE (blank screen) after
+ * going into STATE_AOD (AOD screen) from the quick pickup gesture.
+ */
+ private void cancelQuickPickupDelayableDoze() {
+ if (mQuickPickupDozeCancellable != null) {
+ mQuickPickupDozeCancellable.run();
+ mQuickPickupDozeCancellable = null;
+ }
+ }
+
private void checkTriggersAtInit() {
if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR
|| mDozeHost.isBlockingDoze()
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index d85b10167697..461a7303c184 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -79,7 +79,6 @@ import android.transition.AutoTransition;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.util.ArraySet;
-import android.util.FeatureFlagUtils;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.IWindowManager;
@@ -114,7 +113,6 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.EmergencyAffordanceManager;
-import com.android.internal.util.ScreenRecordHelper;
import com.android.internal.util.ScreenshotHelper;
import com.android.internal.view.RotationPolicy;
import com.android.internal.widget.LockPatternUtils;
@@ -242,7 +240,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private final boolean mShowSilentToggle;
private final EmergencyAffordanceManager mEmergencyAffordanceManager;
private final ScreenshotHelper mScreenshotHelper;
- private final ScreenRecordHelper mScreenRecordHelper;
private final ActivityStarter mActivityStarter;
private final SysuiColorExtractor mSysuiColorExtractor;
private final IStatusBarService mStatusBarService;
@@ -378,7 +375,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mEmergencyAffordanceManager = new EmergencyAffordanceManager(context);
mScreenshotHelper = new ScreenshotHelper(context);
- mScreenRecordHelper = new ScreenRecordHelper(context);
mConfigurationController.addCallback(this);
@@ -979,7 +975,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
@VisibleForTesting
- class ScreenshotAction extends SinglePressAction implements LongPressAction {
+ class ScreenshotAction extends SinglePressAction {
final String KEY_SYSTEM_NAV_2BUTTONS = "system_nav_2buttons";
public ScreenshotAction() {
@@ -1024,18 +1020,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return NAV_BAR_MODE_2BUTTON == mContext.getResources().getInteger(
com.android.internal.R.integer.config_navBarInteractionMode);
}
-
-
- @Override
- public boolean onLongPress() {
- if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SCREENRECORD_LONG_PRESS)) {
- mUiEventLogger.log(GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS);
- mScreenRecordHelper.launchRecordPrompt();
- } else {
- onPress();
- }
- return true;
- }
}
@VisibleForTesting
@@ -2236,7 +2220,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private void showControls(ControlsUiController controller) {
mControlsUiController = controller;
mControlsUiController.show(mControlsView, this::dismissForControlsActivity,
- true /* startedFromGlobalActions */);
+ null /* activityContext */);
}
private boolean isWalletViewAvailable() {
@@ -2465,7 +2449,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
});
if (mControlsUiController != null) {
mControlsUiController.show(mControlsView, this::dismissForControlsActivity,
- true /* startedFromGlobalActions */);
+ null /* activityContext */);
}
mBackgroundDrawable.setAlpha(0);
@@ -2641,7 +2625,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mGlobalActionsLayout.updateList();
if (mControlsUiController != null) {
mControlsUiController.show(mControlsView, this::dismissForControlsActivity,
- true /* startedFromGlobalActions */);
+ null /* activityContext */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 088743cd0f94..9e3be69c414e 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -609,20 +609,21 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
if (mVocab != null) {
app = mVocab.getOrDefault(mPackageName, -1);
}
- // Check if we are within the tightest bounds beyond which
- // we would not need to run the ML model.
- boolean withinRange = x < mMLEnableWidth + mLeftInset
- || x >= (mDisplaySize.x - mMLEnableWidth - mRightInset);
- if (!withinRange) {
+
+ // Denotes whether we should proceed with the gesture. Even if it is false, we may want to
+ // log it assuming it is not invalid due to exclusion.
+ boolean withinRange = x < mEdgeWidthLeft + mLeftInset
+ || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset);
+ if (withinRange) {
int results = -1;
- if (mUseMLModel && (results = getBackGesturePredictionsCategory(x, y, app)) != -1) {
- withinRange = results == 1;
- } else {
- // Denotes whether we should proceed with the gesture.
- // Even if it is false, we may want to log it assuming
- // it is not invalid due to exclusion.
- withinRange = x < mEdgeWidthLeft + mLeftInset
- || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset);
+
+ // Check if we are within the tightest bounds beyond which we would not need to run the
+ // ML model
+ boolean withinMinRange = x < mMLEnableWidth + mLeftInset
+ || x >= (mDisplaySize.x - mMLEnableWidth - mRightInset);
+ if (!withinMinRange && mUseMLModel
+ && (results = getBackGesturePredictionsCategory(x, y, app)) != -1) {
+ withinRange = (results == 1);
}
}
@@ -726,7 +727,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa
mGestureLog.removeFirst();
}
mGestureLog.addLast(String.format(
- "Gesture [%d,alw=%B,%B, %B,%B,disp=%s,wl=%d,il=%d,wr=%d,ir=%d,excl=%s]",
+ "Gesture [%d,alw=%B,%B,%B,%B,disp=%s,wl=%d,il=%d,wr=%d,ir=%d,excl=%s]",
System.currentTimeMillis(), mAllowGesture, mIsOnLeftEdge, mIsBackGestureAllowed,
QuickStepContract.isBackGestureDisabled(mSysUiFlags), mDisplaySize,
mEdgeWidthLeft, mLeftInset, mEdgeWidthRight, mRightInset, mExcludeRegion));
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
index a69ec278be91..378e49deb699 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
@@ -35,6 +35,7 @@ import android.view.ViewGroup;
import com.android.systemui.R;
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
+import com.android.systemui.people.widget.PeopleTileKey;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import java.util.List;
@@ -117,7 +118,7 @@ public class PeopleSpaceActivity extends Activity {
String pkg = tile.getPackageName();
String status =
PeopleSpaceUtils.getLastInteractionString(mContext,
- tile.getLastInteractionTimestamp(), true);
+ tile.getLastInteractionTimestamp());
tileView.setStatus(status);
tileView.setName(tile.getUserName().toString());
@@ -138,7 +139,9 @@ public class PeopleSpaceActivity extends Activity {
+ mAppWidgetId);
}
}
- mPeopleSpaceWidgetManager.addNewWidget(tile, mAppWidgetId);
+ PeopleTileKey key = new PeopleTileKey(
+ tile.getId(), tile.getUserHandle().getIdentifier(), tile.getPackageName());
+ mPeopleSpaceWidgetManager.addNewWidget(mAppWidgetId, key);
finishActivity();
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
index 502c95c47d03..aa45178b6439 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
@@ -52,9 +52,7 @@ import android.icu.text.MeasureFormat;
import android.icu.util.Measure;
import android.icu.util.MeasureUnit;
import android.net.Uri;
-import android.os.Bundle;
import android.os.Parcelable;
-import android.os.ServiceManager;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.service.notification.ConversationChannelWrapper;
@@ -71,10 +69,11 @@ import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.ArrayUtils;
import com.android.settingslib.utils.ThreadUtils;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.people.widget.AppWidgetOptionsHelper;
import com.android.systemui.people.widget.LaunchConversationActivity;
import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
+import com.android.systemui.people.widget.PeopleTileKey;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -106,7 +105,6 @@ public class PeopleSpaceUtils {
private static final int DAYS_IN_A_WEEK = 7;
private static final int MIN_HOUR = 1;
private static final int ONE_DAY = 1;
- public static final String OPTIONS_PEOPLE_SPACE_TILE = "options_people_space_tile";
public static final String PACKAGE_NAME = "package_name";
public static final String USER_ID = "user_id";
public static final String SHORTCUT_ID = "shortcut_id";
@@ -115,6 +113,9 @@ public class PeopleSpaceUtils {
public static final int INVALID_WIDGET_ID = -1;
public static final int INVALID_USER_ID = -1;
+ public static final PeopleTileKey EMPTY_KEY =
+ new PeopleTileKey(EMPTY_STRING, INVALID_USER_ID, EMPTY_STRING);
+
private static final Pattern DOUBLE_EXCLAMATION_PATTERN = Pattern.compile("[!][!]+");
private static final Pattern DOUBLE_QUESTION_PATTERN = Pattern.compile("[?][?]+");
private static final Pattern ANY_DOUBLE_MARK_PATTERN = Pattern.compile("[!?][!?]+");
@@ -200,67 +201,76 @@ public class PeopleSpaceUtils {
AppWidgetManager appWidgetManager, IPeopleManager peopleManager) {
Map<Integer, PeopleSpaceTile> widgetIdToTile = new HashMap<>();
for (int appWidgetId : appWidgetIds) {
- PeopleSpaceTile tile = getPeopleSpaceTile(peopleManager, appWidgetManager, context,
- appWidgetId);
+ PeopleSpaceTile tile = getPeopleSpaceTile(
+ context, appWidgetId, appWidgetManager, peopleManager);
if (tile == null) {
if (DEBUG) Log.d(TAG, "Matching conversation not found for shortcut ID");
//TODO: Delete app widget id when crash is fixed (b/172932636)
continue;
}
-
- if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + ", " + tile.getUserName());
- RemoteViews views = createRemoteViews(context, tile, appWidgetId);
-
- // Tell the AppWidgetManager to perform an update on the current app widget.
- appWidgetManager.updateAppWidget(appWidgetId, views);
-
+ updateAppWidgetOptionsAndView(appWidgetManager, context, appWidgetId, tile);
widgetIdToTile.put(appWidgetId, tile);
}
getBirthdaysOnBackgroundThread(context, appWidgetManager, widgetIdToTile, appWidgetIds);
}
+ /**
+ * Returns a {@link PeopleSpaceTile} based on the {@code appWidgetId}. If the PeopleSpaceTile
+ * isn't cached, store it in AppWidgetOptions.
+ */
@Nullable
- public static PeopleSpaceTile getPeopleSpaceTile(IPeopleManager peopleManager,
- AppWidgetManager appWidgetManager,
- Context context, int appWidgetId) {
- try {
- // Migrate storage for existing users.
- SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(appWidgetId),
- Context.MODE_PRIVATE);
- String pkg = widgetSp.getString(PACKAGE_NAME, EMPTY_STRING);
- int userId = widgetSp.getInt(USER_ID, INVALID_USER_ID);
- String shortcutId = widgetSp.getString(SHORTCUT_ID, EMPTY_STRING);
- if (!validKey(shortcutId, pkg, userId)) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
- shortcutId = sp.getString(String.valueOf(appWidgetId), null);
- if (shortcutId == null) {
- Log.e(TAG, "Cannot restore widget");
- return null;
- }
- migrateExistingUsersToNewStorage(context, shortcutId, appWidgetId);
- pkg = widgetSp.getString(PACKAGE_NAME, EMPTY_STRING);
- userId = widgetSp.getInt(USER_ID, INVALID_USER_ID);
- }
+ public static PeopleSpaceTile getPeopleSpaceTile(Context context, int appWidgetId,
+ AppWidgetManager appWidgetManager, IPeopleManager peopleManager) {
+ // First, check if tile is cached in AppWidgetOptions.
+ PeopleSpaceTile tile = AppWidgetOptionsHelper.getPeopleTile(appWidgetManager, appWidgetId);
+ if (tile != null) {
+ if (DEBUG) Log.d(TAG, "People Tile is cached for widget: " + appWidgetId);
+ return tile;
+ }
- // Check if tile is cached.
- Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
- PeopleSpaceTile tile = options.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
- if (tile != null) {
- return tile;
- }
+ // If not, we get the PeopleTileKey from SharedPreferences, retrieve the Conversation from
+ // persisted storage, and cache it in AppWidgetOptions.
+ SharedPreferences widgetSp = context.getSharedPreferences(
+ String.valueOf(appWidgetId),
+ Context.MODE_PRIVATE);
+ PeopleTileKey sharedPreferencesKey = new PeopleTileKey(
+ widgetSp.getString(SHORTCUT_ID, EMPTY_STRING),
+ widgetSp.getInt(USER_ID, INVALID_USER_ID),
+ widgetSp.getString(PACKAGE_NAME, EMPTY_STRING));
- // If tile is null, we need to retrieve from persisted storage.
- if (DEBUG) {
- Log.d(TAG,
- "Retrieving from storage after reboots: " + shortcutId + " user: " + userId
- + " pkg: " + pkg);
- }
+ if (!sharedPreferencesKey.isValid()) {
+ Log.e(TAG, "Cannot find shortcut info for widgetId: " + appWidgetId);
+ return null;
+ }
+
+ if (DEBUG) Log.d(TAG, "PeopleTile key is present in sharedPreferences: " + appWidgetId);
+ // If tile is null, we need to retrieve from persisted storage.
+ return getPeopleTileFromPersistentStorage(context, sharedPreferencesKey, peopleManager);
+ }
+
+ /**
+ * Returns a {@link PeopleSpaceTile} based on {@link ConversationChannel} returned by
+ * {@link IPeopleManager}.
+ */
+ public static PeopleSpaceTile getPeopleTileFromPersistentStorage(Context context,
+ PeopleTileKey peopleTileKey, IPeopleManager peopleManager) {
+ try {
+ if (DEBUG) Log.d(TAG, "Retrieving Tile from storage: " + peopleTileKey.toString());
LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
- ConversationChannel channel = peopleManager.getConversation(pkg, userId, shortcutId);
+ if (launcherApps == null) {
+ Log.d(TAG, "LauncherApps is null");
+ return null;
+ }
+
+ ConversationChannel channel = peopleManager.getConversation(
+ peopleTileKey.getPackageName(),
+ peopleTileKey.getUserId(),
+ peopleTileKey.getShortcutId());
if (channel == null) {
Log.d(TAG, "Could not retrieve conversation from storage");
return null;
}
+
return new PeopleSpaceTile.Builder(channel, launcherApps).build();
} catch (Exception e) {
Log.e(TAG, "Failed to retrieve conversation for tile: " + e);
@@ -269,79 +279,46 @@ public class PeopleSpaceUtils {
}
/** Returns stored widgets for the conversation specified. */
- public static Set<String> getStoredWidgetIds(SharedPreferences sp, String shortcutId,
- String packageName, int userId) {
- if (shortcutId == null || packageName == null) {
+ public static Set<String> getStoredWidgetIds(SharedPreferences sp, PeopleTileKey key) {
+ if (!key.isValid()) {
return new HashSet<>();
}
- String key = PeopleSpaceUtils.getKey(shortcutId, packageName, userId);
- return new HashSet<>(sp.getStringSet(key, new HashSet<>()));
- }
-
-
- /** Best-effort attempts to migrate existing users to the new storage format. */
- // TODO: Remove after sufficient time. Temporary migration storage for existing users.
- private static void migrateExistingUsersToNewStorage(Context context, String shortcutId,
- int appWidgetId) {
- try {
- List<PeopleSpaceTile> tiles =
- PeopleSpaceUtils.getTiles(context, INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE)),
- IPeopleManager.Stub.asInterface(
- ServiceManager.getService(Context.PEOPLE_SERVICE)),
- context.getSystemService(LauncherApps.class),
- Dependency.get(NotificationEntryManager.class));
- Optional<PeopleSpaceTile> entry = tiles.stream().filter(
- e -> e.getId().equals(shortcutId)).findFirst();
- if (entry.isPresent()) {
- if (DEBUG) Log.d(TAG, "Migrate storage for " + entry.get().getUserName());
- setStorageForTile(context, entry.get(), appWidgetId);
- } else {
- Log.e(TAG, "Could not migrate user. Delete old storage");
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
- SharedPreferences.Editor editor = sp.edit();
- editor.remove(String.valueOf(appWidgetId));
- editor.apply();
- }
- } catch (Exception e) {
- Log.e(TAG, "Could not query conversations");
- }
+ return new HashSet<>(sp.getStringSet(key.toString(), new HashSet<>()));
}
/** Sets all relevant storage for {@code appWidgetId} association to {@code tile}. */
- public static void setStorageForTile(Context context, PeopleSpaceTile tile, int appWidgetId) {
+ public static void setSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
+ int appWidgetId) {
// Write relevant persisted storage.
SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(appWidgetId),
Context.MODE_PRIVATE);
SharedPreferences.Editor widgetEditor = widgetSp.edit();
- widgetEditor.putString(PeopleSpaceUtils.PACKAGE_NAME, tile.getPackageName());
- widgetEditor.putString(PeopleSpaceUtils.SHORTCUT_ID, tile.getId());
- int userId = getUserId(tile);
- widgetEditor.putInt(PeopleSpaceUtils.USER_ID, userId);
+ widgetEditor.putString(PeopleSpaceUtils.PACKAGE_NAME, key.getPackageName());
+ widgetEditor.putString(PeopleSpaceUtils.SHORTCUT_ID, key.getShortcutId());
+ widgetEditor.putInt(PeopleSpaceUtils.USER_ID, key.getUserId());
widgetEditor.apply();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sp.edit();
- editor.putString(String.valueOf(appWidgetId), tile.getId());
- String key = PeopleSpaceUtils.getKey(tile.getId(), tile.getPackageName(), userId);
+ editor.putString(String.valueOf(appWidgetId), key.getShortcutId());
+
// Don't overwrite existing widgets with the same key.
- Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
+ Set<String> storedWidgetIds = new HashSet<>(
+ sp.getStringSet(key.toString(), new HashSet<>()));
storedWidgetIds.add(String.valueOf(appWidgetId));
- editor.putStringSet(key, storedWidgetIds);
+ editor.putStringSet(key.toString(), storedWidgetIds);
editor.apply();
-
- // Write cached storage.
- updateAppWidgetOptionsAndView(AppWidgetManager.getInstance(context), context, appWidgetId,
- tile);
}
/** Removes stored data when tile is deleted. */
- public static void removeStorageForTile(Context context, String key, int widgetId) {
+ public static void removeSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
+ int widgetId) {
// Delete widgetId mapping to key.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sp.edit();
- Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
+ Set<String> storedWidgetIds = new HashSet<>(
+ sp.getStringSet(key.toString(), new HashSet<>()));
storedWidgetIds.remove(String.valueOf(widgetId));
- editor.putStringSet(key, storedWidgetIds);
+ editor.putStringSet(key.toString(), storedWidgetIds);
editor.remove(String.valueOf(widgetId));
editor.apply();
@@ -361,12 +338,12 @@ public class PeopleSpaceUtils {
Log.w(TAG, "NotificationEntryManager is null");
return tiles;
}
- Map<String, NotificationEntry> visibleNotifications = notificationEntryManager
+ Map<PeopleTileKey, NotificationEntry> visibleNotifications = notificationEntryManager
.getVisibleNotifications()
.stream()
.filter(entry -> entry.getRanking() != null
&& entry.getRanking().getConversationShortcutInfo() != null)
- .collect(Collectors.toMap(PeopleSpaceUtils::getKey, e -> e));
+ .collect(Collectors.toMap(PeopleTileKey::new, e -> e));
if (DEBUG) {
Log.d(TAG, "Number of visible notifications:" + visibleNotifications.size());
}
@@ -378,16 +355,15 @@ public class PeopleSpaceUtils {
}
static PeopleSpaceTile augmentTileFromVisibleNotifications(Context context,
- PeopleSpaceTile tile, Map<String, NotificationEntry> visibleNotifications) {
- String shortcutId = tile.getId();
- String packageName = tile.getPackageName();
- int userId = getUserId(tile);
- String key = getKey(shortcutId, packageName, userId);
+ PeopleSpaceTile tile, Map<PeopleTileKey, NotificationEntry> visibleNotifications) {
+ PeopleTileKey key = new PeopleTileKey(
+ tile.getId(), getUserId(tile), tile.getPackageName());
+
if (!visibleNotifications.containsKey(key)) {
- if (DEBUG) Log.d(TAG, "No existing notifications for key:" + key);
+ if (DEBUG) Log.d(TAG, "No existing notifications for key:" + key.toString());
return tile;
}
- if (DEBUG) Log.d(TAG, "Augmenting tile from visible notifications, key:" + key);
+ if (DEBUG) Log.d(TAG, "Augmenting tile from visible notifications, key:" + key.toString());
return augmentTileFromNotification(context, tile, visibleNotifications.get(key).getSbn());
}
@@ -423,17 +399,6 @@ public class PeopleSpaceUtils {
.build();
}
- private static void updateAppWidgetOptions(AppWidgetManager appWidgetManager, int appWidgetId,
- PeopleSpaceTile tile) {
- if (tile == null) {
- if (DEBUG) Log.d(TAG, "Requested to store null tile");
- return;
- }
- Bundle newOptions = new Bundle();
- newOptions.putParcelable(OPTIONS_PEOPLE_SPACE_TILE, tile);
- appWidgetManager.updateAppWidgetOptions(appWidgetId, newOptions);
- }
-
/** Creates a {@link RemoteViews} for {@code tile}. */
public static RemoteViews createRemoteViews(Context context,
PeopleSpaceTile tile, int appWidgetId) {
@@ -653,7 +618,7 @@ public class PeopleSpaceUtils {
}
// TODO: Set subtext as Group Sender name once storing the name in PeopleSpaceTile.
views.setTextViewText(R.id.subtext, PeopleSpaceUtils.getLastInteractionString(
- context, tile.getLastInteractionTimestamp(), false));
+ context, tile.getLastInteractionTimestamp()));
return views;
}
@@ -662,7 +627,7 @@ public class PeopleSpaceUtils {
RemoteViews views = new RemoteViews(
context.getPackageName(), R.layout.people_space_large_avatar_tile);
String status = PeopleSpaceUtils.getLastInteractionString(
- context, tile.getLastInteractionTimestamp(), true);
+ context, tile.getLastInteractionTimestamp());
views.setTextViewText(R.id.last_interaction, status);
return views;
}
@@ -808,8 +773,7 @@ public class PeopleSpaceUtils {
}
/** Returns a readable status describing the {@code lastInteraction}. */
- public static String getLastInteractionString(Context context, long lastInteraction,
- boolean includeLastChatted) {
+ public static String getLastInteractionString(Context context, long lastInteraction) {
if (lastInteraction == 0L) {
Log.e(TAG, "Could not get valid last interaction");
return context.getString(R.string.basic_status);
@@ -818,41 +782,20 @@ public class PeopleSpaceUtils {
Duration durationSinceLastInteraction = Duration.ofMillis(now - lastInteraction);
MeasureFormat formatter = MeasureFormat.getInstance(Locale.getDefault(),
MeasureFormat.FormatWidth.WIDE);
- MeasureFormat shortFormatter = MeasureFormat.getInstance(Locale.getDefault(),
- MeasureFormat.FormatWidth.SHORT);
if (durationSinceLastInteraction.toHours() < MIN_HOUR) {
- if (includeLastChatted) {
- return context.getString(R.string.last_interaction_status_less_than,
- formatter.formatMeasures(new Measure(MIN_HOUR, MeasureUnit.HOUR)));
- }
- return context.getString(R.string.timestamp, shortFormatter.formatMeasures(
+ return context.getString(R.string.timestamp, formatter.formatMeasures(
new Measure(durationSinceLastInteraction.toMinutes(), MeasureUnit.MINUTE)));
} else if (durationSinceLastInteraction.toDays() < ONE_DAY) {
- if (includeLastChatted) {
- return context.getString(R.string.last_interaction_status,
- formatter.formatMeasures(
- new Measure(durationSinceLastInteraction.toHours(),
- MeasureUnit.HOUR)));
- }
- return context.getString(R.string.timestamp, shortFormatter.formatMeasures(
+ return context.getString(R.string.timestamp, formatter.formatMeasures(
new Measure(durationSinceLastInteraction.toHours(),
MeasureUnit.HOUR)));
} else if (durationSinceLastInteraction.toDays() < DAYS_IN_A_WEEK) {
- if (includeLastChatted) {
- return context.getString(R.string.last_interaction_status,
- formatter.formatMeasures(
- new Measure(durationSinceLastInteraction.toDays(),
- MeasureUnit.DAY)));
- }
- return context.getString(R.string.timestamp, shortFormatter.formatMeasures(
+ return context.getString(R.string.timestamp, formatter.formatMeasures(
new Measure(durationSinceLastInteraction.toHours(),
MeasureUnit.DAY)));
} else {
return context.getString(durationSinceLastInteraction.toDays() == DAYS_IN_A_WEEK
- ? (includeLastChatted ? R.string.last_interaction_status :
- R.string.timestamp) :
- (includeLastChatted ? R.string.last_interaction_status_over
- : R.string.over_timestamp),
+ ? R.string.timestamp : R.string.over_timestamp,
formatter.formatMeasures(
new Measure(durationSinceLastInteraction.toDays() / DAYS_IN_A_WEEK,
MeasureUnit.WEEK)));
@@ -957,11 +900,15 @@ public class PeopleSpaceUtils {
removeBirthdayStatusIfPresent(appWidgetManager, context, storedTile, appWidgetId);
}
- /** Update app widget options and the current view. */
+ /** Updates tile in app widget options and the current view. */
public static void updateAppWidgetOptionsAndView(AppWidgetManager appWidgetManager,
Context context, int appWidgetId, PeopleSpaceTile tile) {
- updateAppWidgetOptions(appWidgetManager, appWidgetId, tile);
+ AppWidgetOptionsHelper.setPeopleTile(appWidgetManager, appWidgetId, tile);
+
+ if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + ", " + tile.getUserName());
RemoteViews views = createRemoteViews(context, tile, appWidgetId);
+
+ // Tell the AppWidgetManager to perform an update on the current app widget.
appWidgetManager.updateAppWidget(appWidgetId, views);
}
@@ -1006,44 +953,6 @@ public class PeopleSpaceUtils {
return lookupKeysWithBirthdaysToday;
}
- static String getKey(NotificationEntry entry) {
- if (entry.getRanking() == null || entry.getRanking().getConversationShortcutInfo() == null
- || entry.getSbn() == null || entry.getSbn().getUser() == null) {
- return null;
- }
- return getKey(entry.getRanking().getConversationShortcutInfo().getId(),
- entry.getSbn().getPackageName(),
- entry.getSbn().getUser().getIdentifier());
- }
-
- /**
- * Returns the uniquely identifying key for the conversation.
- *
- * <p>{@code userId} will always be a number, so we put user ID as the
- * delimiter between the app-provided strings of shortcut ID and package name.
- *
- * <p>There aren't restrictions on shortcut ID characters, but there are restrictions requiring
- * a {@code packageName} to always start with a letter. This restriction means we are
- * guaranteed to avoid cases like "a/b/0/0/package.name" having two potential keys, as the first
- * case is impossible given the package name restrictions:
- * <ul>
- * <li>"a/b" + "/" + 0 + "/" + "0/packageName"</li>
- * <li>"a/b/0" + "/" + 0 + "/" + "packageName"</li>
- * </ul>
- */
- @Nullable
- public static String getKey(String shortcutId, String packageName, int userId) {
- if (!validKey(shortcutId, packageName, userId)) {
- return null;
- }
- return shortcutId + "/" + userId + "/" + packageName;
- }
-
- /** Returns whether the key is valid. */
- public static boolean validKey(String shortcutId, String packageName, int userId) {
- return !TextUtils.isEmpty(shortcutId) && !TextUtils.isEmpty(packageName) && userId >= 0;
- }
-
/** Returns the userId associated with a {@link PeopleSpaceTile} */
public static int getUserId(PeopleSpaceTile tile) {
return tile.getUserHandle().getIdentifier();
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/AppWidgetOptionsHelper.java b/packages/SystemUI/src/com/android/systemui/people/widget/AppWidgetOptionsHelper.java
new file mode 100644
index 000000000000..df08ee4a42bf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/AppWidgetOptionsHelper.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people.widget;
+
+import static com.android.systemui.people.PeopleSpaceUtils.DEBUG;
+import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_KEY;
+import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
+import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
+import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
+import static com.android.systemui.people.PeopleSpaceUtils.SHORTCUT_ID;
+import static com.android.systemui.people.PeopleSpaceUtils.USER_ID;
+
+import android.app.people.PeopleSpaceTile;
+import android.appwidget.AppWidgetManager;
+import android.os.Bundle;
+import android.util.Log;
+
+/** Helper class encapsulating AppWidgetOptions for People Tile. */
+public class AppWidgetOptionsHelper {
+ private static final String TAG = "AppWidgetOptionsHelper";
+
+ /** Key to store {@link PeopleSpaceTile} in AppWidgetOptions Bundle. */
+ public static final String OPTIONS_PEOPLE_TILE = "options_people_tile";
+
+ /** Sets {@link PeopleSpaceTile} in AppWidgetOptions. */
+ public static void setPeopleTile(AppWidgetManager appWidgetManager, int appWidgetId,
+ PeopleSpaceTile tile) {
+ if (tile == null) {
+ if (DEBUG) Log.d(TAG, "Requested to store null tile");
+ return;
+ }
+ Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
+ options.putParcelable(OPTIONS_PEOPLE_TILE, tile);
+ appWidgetManager.updateAppWidgetOptions(appWidgetId, options);
+ }
+
+ /** Gets {@link PeopleSpaceTile} from AppWidgetOptions. */
+ public static PeopleSpaceTile getPeopleTile(AppWidgetManager appWidgetManager,
+ int appWidgetId) {
+ Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
+ return options != null ? options.getParcelable(OPTIONS_PEOPLE_TILE) : null;
+ }
+
+ /** Sets {@link PeopleTileKey} in AppWidgetOptions. */
+ public static void setPeopleTileKey(AppWidgetManager appWidgetManager, int appWidgetId,
+ PeopleTileKey key) {
+ Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
+ options.putString(SHORTCUT_ID, key.getShortcutId());
+ options.putInt(USER_ID, key.getUserId());
+ options.putString(PACKAGE_NAME, key.getPackageName());
+ appWidgetManager.updateAppWidgetOptions(appWidgetId, options);
+ }
+
+ /** Gets {@link PeopleTileKey} from AppWidgetOptions. */
+ public static PeopleTileKey getPeopleTileKey(AppWidgetManager appWidgetManager,
+ int appWidgetId) {
+ Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
+ if (options == null) {
+ return EMPTY_KEY;
+ }
+ return getPeopleTileKeyFromBundle(options);
+ }
+
+ /** Gets {@link PeopleTileKey} from Bundle {@code options}. */
+ public static PeopleTileKey getPeopleTileKeyFromBundle(Bundle options) {
+ String pkg = options.getString(PACKAGE_NAME, EMPTY_STRING);
+ int userId = options.getInt(USER_ID, INVALID_USER_ID);
+ String shortcutId = options.getString(SHORTCUT_ID, EMPTY_STRING);
+ return new PeopleTileKey(shortcutId, userId, pkg);
+ }
+
+ /** Removes {@link PeopleTileKey} from AppWidgetOptions. */
+ public static void removePeopleTileKey(AppWidgetManager appWidgetManager,
+ int appWidgetId) {
+ setPeopleTileKey(appWidgetManager, appWidgetId, EMPTY_KEY);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 22ee9e89d0a0..7da9a80ca287 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -16,6 +16,7 @@
package com.android.systemui.people.widget;
+import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
import static com.android.systemui.people.PeopleSpaceUtils.SHORTCUT_ID;
@@ -38,6 +39,7 @@ import android.content.SharedPreferences;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
import android.net.Uri;
+import android.os.Bundle;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.preference.PreferenceManager;
@@ -78,8 +80,8 @@ public class PeopleSpaceWidgetManager {
private PeopleManager mPeopleManager;
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
@GuardedBy("mLock")
- public static Map<String, PeopleSpaceWidgetProvider.TileConversationListener> mListeners =
- new HashMap<>();
+ public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
+ mListeners = new HashMap<>();
@Inject
public PeopleSpaceWidgetManager(Context context) {
@@ -122,8 +124,8 @@ public class PeopleSpaceWidgetManager {
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
if (showSingleConversation) {
synchronized (mLock) {
- PeopleSpaceUtils.updateSingleConversationWidgets(mContext, widgetIds,
- mAppWidgetManager, mIPeopleManager);
+ PeopleSpaceUtils.updateSingleConversationWidgets(
+ mContext, widgetIds, mAppWidgetManager, mIPeopleManager);
}
}
} catch (Exception e) {
@@ -157,9 +159,11 @@ public class PeopleSpaceWidgetManager {
return;
}
synchronized (mLock) {
- Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, sbnShortcutId,
- sbn.getPackageName(),
- UserHandle.getUserHandleForUid(sbn.getUid()).getIdentifier());
+ PeopleTileKey key = new PeopleTileKey(
+ sbnShortcutId,
+ UserHandle.getUserHandleForUid(sbn.getUid()).getIdentifier(),
+ sbn.getPackageName());
+ Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, key);
for (String widgetIdString : storedWidgetIds) {
int widgetId = Integer.parseInt(widgetIdString);
if (DEBUG) Log.d(TAG, "Storing notification change, key:" + sbn.getKey());
@@ -177,9 +181,9 @@ public class PeopleSpaceWidgetManager {
public void updateWidgetsWithConversationChanged(ConversationChannel conversation) {
ShortcutInfo info = conversation.getShortcutInfo();
synchronized (mLock) {
- Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, info.getId(),
- info.getPackage(),
- info.getUserId());
+ PeopleTileKey key = new PeopleTileKey(
+ info.getId(), info.getUserId(), info.getPackage());
+ Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, key);
for (String widgetIdString : storedWidgetIds) {
if (DEBUG) {
Log.d(TAG,
@@ -197,9 +201,8 @@ public class PeopleSpaceWidgetManager {
*/
private void updateStorageAndViewWithConversationData(ConversationChannel conversation,
int appWidgetId) {
- PeopleSpaceTile storedTile = getPeopleSpaceTile(mIPeopleManager, mAppWidgetManager,
- mContext,
- appWidgetId);
+ PeopleSpaceTile storedTile = getPeopleSpaceTile(
+ mContext, appWidgetId, mAppWidgetManager, mIPeopleManager);
if (storedTile == null) {
if (DEBUG) Log.d(TAG, "Could not find stored tile to add conversation to");
return;
@@ -232,9 +235,8 @@ public class PeopleSpaceWidgetManager {
StatusBarNotification sbn,
PeopleSpaceUtils.NotificationAction notificationAction,
int appWidgetId) {
- PeopleSpaceTile storedTile = getPeopleSpaceTile(mIPeopleManager, mAppWidgetManager,
- mContext,
- appWidgetId);
+ PeopleSpaceTile storedTile = getPeopleSpaceTile(
+ mContext, appWidgetId, mAppWidgetManager, mIPeopleManager);
if (storedTile == null) {
if (DEBUG) Log.d(TAG, "Could not find stored tile to add notification to");
return;
@@ -312,18 +314,39 @@ public class PeopleSpaceWidgetManager {
}
};
- /** Adds {@code tile} mapped to {@code appWidgetId}. */
- public void addNewWidget(PeopleSpaceTile tile, int appWidgetId) {
+ /**
+ * Checks if this widget has been added externally, and this the first time we are learning
+ * about the widget. If so, the widget adder should have populated options with PeopleTileKey
+ * arguments.
+ */
+ public void onAppWidgetOptionsChanged(int appWidgetId, Bundle newOptions) {
+ // Check if this widget has been added externally, and this the first time we are
+ // learning about the widget. If so, the widget adder should have populated options with
+ // PeopleTileKey arguments.
+ if (DEBUG) Log.d(TAG, "onAppWidgetOptionsChanged called for widget: " + appWidgetId);
+ PeopleTileKey optionsKey = AppWidgetOptionsHelper.getPeopleTileKeyFromBundle(newOptions);
+ if (optionsKey.isValid()) {
+ if (DEBUG) {
+ Log.d(TAG, "PeopleTileKey was present in Options, shortcutId: "
+ + optionsKey.getShortcutId());
+ }
+ addNewWidget(appWidgetId, optionsKey);
+ AppWidgetOptionsHelper.removePeopleTileKey(mAppWidgetManager, appWidgetId);
+ }
+ }
+
+ /** Adds{@code tile} mapped to {@code appWidgetId}. */
+ public void addNewWidget(int appWidgetId, PeopleTileKey key) {
mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_ADDED);
synchronized (mLock) {
- if (DEBUG) Log.d(TAG, "Add storage for : " + tile.getUserName());
- PeopleSpaceUtils.setStorageForTile(mContext, tile, appWidgetId);
+ if (DEBUG) Log.d(TAG, "Add storage for : " + key.getShortcutId());
+ PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId);
}
try {
- if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + tile.getId());
- mLauncherApps.cacheShortcuts(tile.getPackageName(),
- Collections.singletonList(tile.getId()),
- tile.getUserHandle(), LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS);
+ if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + key.getShortcutId());
+ mLauncherApps.cacheShortcuts(key.getPackageName(),
+ Collections.singletonList(key.getShortcutId()),
+ UserHandle.of(key.getUserId()), LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS);
} catch (Exception e) {
Log.w(TAG, "Exception caching shortcut:" + e);
}
@@ -335,19 +358,16 @@ public class PeopleSpaceWidgetManager {
public void registerConversationListenerIfNeeded(int widgetId,
PeopleSpaceWidgetProvider.TileConversationListener newListener) {
// Retrieve storage needed for registration.
- String packageName;
- String shortcutId;
- int userId;
- String key;
+ PeopleTileKey key;
synchronized (mLock) {
SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
Context.MODE_PRIVATE);
- packageName = widgetSp.getString(PACKAGE_NAME, null);
- shortcutId = widgetSp.getString(SHORTCUT_ID, null);
- userId = widgetSp.getInt(USER_ID, INVALID_USER_ID);
- key = PeopleSpaceUtils.getKey(shortcutId, packageName, userId);
- if (key == null) {
- if (DEBUG) Log.e(TAG, "Could not register " + widgetId);
+ key = new PeopleTileKey(
+ widgetSp.getString(SHORTCUT_ID, EMPTY_STRING),
+ widgetSp.getInt(USER_ID, INVALID_USER_ID),
+ widgetSp.getString(PACKAGE_NAME, EMPTY_STRING));
+ if (!key.isValid()) {
+ if (DEBUG) Log.w(TAG, "Could not register listener for widget: " + widgetId);
return;
}
}
@@ -359,9 +379,9 @@ public class PeopleSpaceWidgetManager {
if (DEBUG) Log.d(TAG, "Register listener for " + widgetId + " with " + key);
mListeners.put(key, newListener);
}
- mPeopleManager.registerConversationListener(packageName,
- userId,
- shortcutId, newListener,
+ mPeopleManager.registerConversationListener(key.getPackageName(),
+ key.getUserId(),
+ key.getShortcutId(), newListener,
mContext.getMainExecutor());
}
@@ -371,27 +391,24 @@ public class PeopleSpaceWidgetManager {
if (DEBUG) Log.d(TAG, "Widget removed: " + widgetId);
mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_DELETED);
// Retrieve storage needed for widget deletion.
- String packageName;
- String shortcutId;
- int userId;
- String key;
+ PeopleTileKey key;
Set<String> storedWidgetIdsForKey;
synchronized (mLock) {
SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
Context.MODE_PRIVATE);
- packageName = widgetSp.getString(PACKAGE_NAME, null);
- shortcutId = widgetSp.getString(SHORTCUT_ID, null);
- userId = widgetSp.getInt(USER_ID, INVALID_USER_ID);
- key = PeopleSpaceUtils.getKey(shortcutId, packageName, userId);
- if (key == null) {
+ key = new PeopleTileKey(
+ widgetSp.getString(SHORTCUT_ID, null),
+ widgetSp.getInt(USER_ID, INVALID_USER_ID),
+ widgetSp.getString(PACKAGE_NAME, null));
+ if (!key.isValid()) {
if (DEBUG) Log.e(TAG, "Could not delete " + widgetId);
return;
}
storedWidgetIdsForKey = new HashSet<>(
- mSharedPrefs.getStringSet(key, new HashSet<>()));
+ mSharedPrefs.getStringSet(key.toString(), new HashSet<>()));
}
synchronized (mLock) {
- PeopleSpaceUtils.removeStorageForTile(mContext, key, widgetId);
+ PeopleSpaceUtils.removeSharedPreferencesStorageForTile(mContext, key, widgetId);
}
// If another tile with the conversation is still stored, we need to keep the listener.
if (DEBUG) Log.d(TAG, "Stored widget IDs: " + storedWidgetIdsForKey.toString());
@@ -399,13 +416,13 @@ public class PeopleSpaceWidgetManager {
&& storedWidgetIdsForKey.size() == 1) {
if (DEBUG) Log.d(TAG, "Remove caching and listener");
unregisterConversationListener(key, widgetId);
- uncacheConversationShortcut(shortcutId, packageName, userId);
+ uncacheConversationShortcut(key);
}
}
}
/** Unregisters the conversation listener for {@code appWidgetId}. */
- private void unregisterConversationListener(String key, int appWidgetId) {
+ private void unregisterConversationListener(PeopleTileKey key, int appWidgetId) {
PeopleSpaceWidgetProvider.TileConversationListener registeredListener;
synchronized (mListeners) {
registeredListener = mListeners.get(key);
@@ -420,12 +437,12 @@ public class PeopleSpaceWidgetManager {
}
/** Uncaches the conversation shortcut. */
- private void uncacheConversationShortcut(String shortcutId, String packageName, int userId) {
+ private void uncacheConversationShortcut(PeopleTileKey key) {
try {
- if (DEBUG) Log.d(TAG, "Uncaching shortcut for PeopleTile: " + shortcutId);
- mLauncherApps.uncacheShortcuts(packageName,
- Collections.singletonList(shortcutId),
- UserHandle.of(userId),
+ if (DEBUG) Log.d(TAG, "Uncaching shortcut for PeopleTile: " + key.getShortcutId());
+ mLauncherApps.uncacheShortcuts(key.getPackageName(),
+ Collections.singletonList(key.getShortcutId()),
+ UserHandle.of(key.getUserId()),
LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS);
} catch (Exception e) {
Log.d(TAG, "Exception uncaching shortcut:" + e);
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
index cccf7aa13028..3bc5b29bd05d 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
@@ -22,6 +22,7 @@ import android.app.people.PeopleManager;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
+import android.os.Bundle;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -67,18 +68,21 @@ public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
ensurePeopleSpaceWidgetManagerInitialized(context);
peopleSpaceWidgetManager.updateWidgets(appWidgetIds);
for (int appWidgetId : appWidgetIds) {
+ if (DEBUG) Log.d(TAG, "Ensure listener is registered for widget: " + appWidgetId);
PeopleSpaceWidgetProvider.TileConversationListener
newListener = new PeopleSpaceWidgetProvider.TileConversationListener();
peopleSpaceWidgetManager.registerConversationListenerIfNeeded(appWidgetId,
newListener);
}
- return;
}
- private void ensurePeopleSpaceWidgetManagerInitialized(Context context) {
- if (peopleSpaceWidgetManager == null) {
- peopleSpaceWidgetManager = new PeopleSpaceWidgetManager(context);
- }
+ /** Called when widget updates. */
+ @Override
+ public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
+ int appWidgetId, Bundle newOptions) {
+ super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
+ ensurePeopleSpaceWidgetManagerInitialized(context);
+ peopleSpaceWidgetManager.onAppWidgetOptionsChanged(appWidgetId, newOptions);
}
@Override
@@ -88,6 +92,12 @@ public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
peopleSpaceWidgetManager.deleteWidgets(appWidgetIds);
}
+ private void ensurePeopleSpaceWidgetManagerInitialized(Context context) {
+ if (peopleSpaceWidgetManager == null) {
+ peopleSpaceWidgetManager = new PeopleSpaceWidgetManager(context);
+ }
+ }
+
@VisibleForTesting
public void setPeopleSpaceWidgetManager(PeopleSpaceWidgetManager manager) {
peopleSpaceWidgetManager = manager;
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java
index 050352292b38..87b2a15d1c55 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetRemoteViewsFactory.java
@@ -106,7 +106,7 @@ public class PeopleSpaceWidgetRemoteViewsFactory implements RemoteViewsService.R
PeopleSpaceTile tile = mTiles.get(i);
String status = PeopleSpaceUtils.getLastInteractionString(mContext,
- tile.getLastInteractionTimestamp(), true);
+ tile.getLastInteractionTimestamp());
personView.setTextViewText(R.id.status, status);
personView.setTextViewText(R.id.name, tile.getUserName().toString());
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleTileKey.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleTileKey.java
new file mode 100644
index 000000000000..ac42cb08090a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleTileKey.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.people.widget;
+
+import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
+import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
+
+import android.text.TextUtils;
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import java.util.Objects;
+
+/** Class that encapsulates fields identifying a Conversation. */
+public class PeopleTileKey {
+ private String mShortcutId;
+ private int mUserId;
+ private String mPackageName;
+
+ public PeopleTileKey(String shortcutId, int userId, String packageName) {
+ mShortcutId = shortcutId;
+ mUserId = userId;
+ mPackageName = packageName;
+ }
+
+ public PeopleTileKey(NotificationEntry entry) {
+ mShortcutId = entry.getRanking() != null
+ && entry.getRanking().getConversationShortcutInfo() != null
+ ? entry.getRanking().getConversationShortcutInfo().getId()
+ : EMPTY_STRING;
+ mUserId = entry.getSbn().getUser() != null
+ ? entry.getSbn().getUser().getIdentifier() : INVALID_USER_ID;
+ mPackageName = entry.getSbn().getPackageName();
+ }
+
+ public String getShortcutId() {
+ return mShortcutId;
+ }
+
+ public int getUserId() {
+ return mUserId;
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /** Returns whether PeopleTileKey is valid/well-formed. */
+ public boolean isValid() {
+ return !TextUtils.isEmpty(mShortcutId) && !TextUtils.isEmpty(mPackageName) && mUserId >= 0;
+ }
+
+ /**
+ * Returns the uniquely identifying key for the conversation.
+ *
+ * <p>{@code userId} will always be a number, so we put user ID as the
+ * delimiter between the app-provided strings of shortcut ID and package name.
+ *
+ * <p>There aren't restrictions on shortcut ID characters, but there are restrictions requiring
+ * a {@code packageName} to always start with a letter. This restriction means we are
+ * guaranteed to avoid cases like "a/b/0/0/package.name" having two potential keys, as the first
+ * case is impossible given the package name restrictions:
+ * <ul>
+ * <li>"a/b" + "/" + 0 + "/" + "0/packageName"</li>
+ * <li>"a/b/0" + "/" + 0 + "/" + "packageName"</li>
+ * </ul>
+ */
+ @Override
+ public String toString() {
+ if (!isValid()) return null;
+ return mShortcutId + "/" + mUserId + "/" + mPackageName;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof PeopleTileKey)) {
+ return false;
+ }
+ final PeopleTileKey o = (PeopleTileKey) other;
+ return Objects.equals(o.toString(), this.toString());
+ }
+
+ @Override
+ public int hashCode() {
+ return mPackageName.hashCode() + Integer.valueOf(mUserId).hashCode()
+ + mShortcutId.hashCode();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
index 7e20be6826dc..3d8784b29e4c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
@@ -94,7 +94,7 @@ public class QSFooterView extends FrameLayout {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mEdit = findViewById(android.R.id.edit);
+ mEdit = requireViewById(android.R.id.edit);
mPageIndicator = findViewById(R.id.footer_page_indicator);
@@ -104,14 +104,15 @@ public class QSFooterView extends FrameLayout {
mMultiUserSwitch = findViewById(R.id.multi_user_switch);
mMultiUserAvatar = mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
- mActionsContainer = findViewById(R.id.qs_footer_actions_container);
+ mActionsContainer = requireViewById(R.id.qs_footer_actions_container);
mEditContainer = findViewById(R.id.qs_footer_actions_edit_container);
mBuildText = findViewById(R.id.build);
// RenderThread is doing more harm than good when touching the header (to expand quick
// settings), so disable it for this view
- ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true);
-
+ if (mSettingsButton.getBackground() instanceof RippleDrawable) {
+ ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true);
+ }
updateResources();
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
@@ -143,7 +144,7 @@ public class QSFooterView extends FrameLayout {
int defSpace = mContext.getResources().getDimensionPixelOffset(R.dimen.default_gear_space);
mSettingsCogAnimator = new Builder()
- .addFloat(mSettingsContainer, "translationX",
+ .addFloat(mSettingsButton, "translationX",
isLayoutRtl() ? (remaining - defSpace) : -(remaining - defSpace), 0)
.addFloat(mSettingsButton, "rotation", -120, 0)
.build();
@@ -173,12 +174,15 @@ public class QSFooterView extends FrameLayout {
@Nullable
private TouchAnimator createFooterAnimator() {
- return new TouchAnimator.Builder()
+ TouchAnimator.Builder builder = new TouchAnimator.Builder()
.addFloat(mActionsContainer, "alpha", 0, 1)
- .addFloat(mEditContainer, "alpha", 0, 1)
.addFloat(mPageIndicator, "alpha", 0, 1)
- .setStartDelay(0.9f)
- .build();
+ .addFloat(mBuildText, "alpha", 0, 1)
+ .setStartDelay(0.9f);
+ if (mEditContainer != null) {
+ builder.addFloat(mEditContainer, "alpha", 0, 1);
+ }
+ return builder.build();
}
/** */
@@ -273,8 +277,10 @@ public class QSFooterView extends FrameLayout {
mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
isTunerEnabled ? View.VISIBLE : View.INVISIBLE);
final boolean isDemo = UserManager.isDeviceInDemoMode(mContext);
- mMultiUserSwitch.setVisibility(showUserSwitcher() ? View.VISIBLE : View.INVISIBLE);
- mEditContainer.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
+ mMultiUserSwitch.setVisibility(showUserSwitcher() ? View.VISIBLE : View.GONE);
+ if (mEditContainer != null) {
+ mEditContainer.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
+ }
mSettingsButton.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
mBuildText.setVisibility(mExpanded && mShouldShowBuildText ? View.VISIBLE : View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
index 2bea72cc0c7e..f1f4e16206a1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
@@ -153,8 +153,8 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
@Override
protected void onViewAttached() {
- if (mShowPMLiteButton) {
- mPowerMenuLite.setVisibility(View.VISIBLE);
+ if (!mShowPMLiteButton) {
+ mPowerMenuLite.setVisibility(View.GONE);
}
mView.addOnLayoutChangeListener(
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 7657dcead583..ff9b9120c6e1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -32,6 +32,7 @@ import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStub;
import android.widget.LinearLayout;
import com.android.internal.logging.UiEventLogger;
@@ -127,8 +128,21 @@ public class QSPanel extends LinearLayout implements Tunable {
}
+ protected void inflateQSFooter(boolean newFooter) {
+ ViewStub stub = findViewById(R.id.qs_footer_stub);
+ if (stub != null) {
+ stub.setLayoutResource(
+ newFooter ? R.layout.qs_footer_impl_two_lines : R.layout.qs_footer_impl);
+ stub.inflate();
+ mFooter = findViewById(R.id.qs_footer);
+ }
+ }
+
void initialize(boolean sideLabels) {
mSideLabels = sideLabels;
+
+ inflateQSFooter(sideLabels);
+
mRegularTileLayout = createRegularTileLayout();
mTileLayout = mRegularTileLayout;
@@ -344,7 +358,6 @@ public class QSPanel extends LinearLayout implements Tunable {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mFooter = findViewById(R.id.qs_footer);
mDivider = findViewById(R.id.divider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 9b66b59c06df..f51d7ef381ee 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -55,6 +55,11 @@ public class QuickQSPanel extends QSPanel {
applyBottomMargin((View) mRegularTileLayout);
}
+ @Override
+ protected void inflateQSFooter(boolean newFooter) {
+ // No footer
+ }
+
private void applyBottomMargin(View view) {
int margin = getResources().getDimensionPixelSize(R.dimen.qs_header_tile_margin_bottom);
MarginLayoutParams layoutParams = (MarginLayoutParams) view.getLayoutParams();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 6983b38489f6..9e5fe732cd0c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -30,6 +30,7 @@ import com.android.systemui.plugins.qs.QSTileView;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.tiles.AirplaneModeTile;
+import com.android.systemui.qs.tiles.AlarmTile;
import com.android.systemui.qs.tiles.BatterySaverTile;
import com.android.systemui.qs.tiles.BluetoothTile;
import com.android.systemui.qs.tiles.CameraToggleTile;
@@ -91,6 +92,7 @@ public class QSFactoryImpl implements QSFactory {
private final Provider<CameraToggleTile> mCameraToggleTileProvider;
private final Provider<MicrophoneToggleTile> mMicrophoneToggleTileProvider;
private final Provider<DeviceControlsTile> mDeviceControlsTileProvider;
+ private final Provider<AlarmTile> mAlarmTileProvider;
private final Lazy<QSHost> mQsHostLazy;
private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
@@ -126,7 +128,8 @@ public class QSFactoryImpl implements QSFactory {
Provider<ReduceBrightColorsTile> reduceBrightColorsTileProvider,
Provider<CameraToggleTile> cameraToggleTileProvider,
Provider<MicrophoneToggleTile> microphoneToggleTileProvider,
- Provider<DeviceControlsTile> deviceControlsTileProvider) {
+ Provider<DeviceControlsTile> deviceControlsTileProvider,
+ Provider<AlarmTile> alarmTileProvider) {
mQsHostLazy = qsHostLazy;
mCustomTileBuilderProvider = customTileBuilderProvider;
@@ -157,6 +160,7 @@ public class QSFactoryImpl implements QSFactory {
mCameraToggleTileProvider = cameraToggleTileProvider;
mMicrophoneToggleTileProvider = microphoneToggleTileProvider;
mDeviceControlsTileProvider = deviceControlsTileProvider;
+ mAlarmTileProvider = alarmTileProvider;
}
public QSTile createTile(String tileSpec) {
@@ -218,6 +222,8 @@ public class QSFactoryImpl implements QSFactory {
return mMicrophoneToggleTileProvider.get();
case "controls":
return mDeviceControlsTileProvider.get();
+ case "alarm":
+ return mAlarmTileProvider.get();
}
// Custom tiles
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
new file mode 100644
index 000000000000..dede627cd4dc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
@@ -0,0 +1,117 @@
+package com.android.systemui.qs.tiles
+
+import android.app.AlarmManager
+import android.app.AlarmManager.AlarmClockInfo
+import android.content.Intent
+import android.os.Handler
+import android.os.Looper
+import android.provider.AlarmClock
+import android.service.quicksettings.Tile
+import android.text.TextUtils
+import android.text.format.DateFormat
+import androidx.annotation.VisibleForTesting
+import com.android.internal.logging.MetricsLogger
+import com.android.systemui.R
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.FeatureFlags
+import com.android.systemui.statusbar.policy.NextAlarmController
+import java.util.Locale
+import javax.inject.Inject
+
+class AlarmTile @Inject constructor(
+ host: QSHost,
+ @Background backgroundLooper: Looper,
+ @Main mainHandler: Handler,
+ metricsLogger: MetricsLogger,
+ statusBarStateController: StatusBarStateController,
+ activityStarter: ActivityStarter,
+ qsLogger: QSLogger,
+ private val featureFlags: FeatureFlags,
+ private val userTracker: UserTracker,
+ nextAlarmController: NextAlarmController
+) : QSTileImpl<QSTile.State>(
+ host,
+ backgroundLooper,
+ mainHandler,
+ metricsLogger,
+ statusBarStateController,
+ activityStarter,
+ qsLogger
+) {
+
+ private var lastAlarmInfo: AlarmManager.AlarmClockInfo? = null
+ private val icon = ResourceIcon.get(R.drawable.ic_alarm)
+ @VisibleForTesting
+ internal val defaultIntent = Intent(AlarmClock.ACTION_SET_ALARM)
+ private val callback = NextAlarmController.NextAlarmChangeCallback { nextAlarm ->
+ lastAlarmInfo = nextAlarm
+ refreshState()
+ }
+
+ init {
+ nextAlarmController.observe(this, callback)
+ }
+
+ override fun isAvailable(): Boolean {
+ return featureFlags.isAlarmTileAvailable
+ }
+
+ override fun newTileState(): QSTile.State {
+ return QSTile.State().apply {
+ handlesLongClick = false
+ }
+ }
+
+ private fun startDefaultSetAlarm() {
+ mActivityStarter.postStartActivityDismissingKeyguard(defaultIntent, 0)
+ }
+
+ override fun handleClick() {
+ lastAlarmInfo?.showIntent?.let {
+ mActivityStarter.postStartActivityDismissingKeyguard(it)
+ } ?: startDefaultSetAlarm()
+ }
+
+ override fun handleUpdateState(state: QSTile.State, arg: Any?) {
+ state.icon = icon
+ state.label = tileLabel
+ lastAlarmInfo?.let {
+ state.secondaryLabel = formatNextAlarm(it)
+ state.state = Tile.STATE_ACTIVE
+ } ?: run {
+ state.secondaryLabel = mContext.getString(R.string.qs_alarm_tile_no_alarm)
+ state.state = Tile.STATE_INACTIVE
+ }
+ state.contentDescription = TextUtils.concat(state.label, ", ", state.secondaryLabel)
+ }
+
+ override fun getTileLabel(): CharSequence {
+ return mContext.getString(R.string.status_bar_alarm)
+ }
+
+ private fun formatNextAlarm(info: AlarmClockInfo): String {
+ val skeleton = if (use24HourFormat()) "EHm" else "Ehma"
+ val pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton)
+ return DateFormat.format(pattern, info.triggerTime).toString()
+ }
+
+ private fun use24HourFormat(): Boolean {
+ return DateFormat.is24HourFormat(mContext, userTracker.userId)
+ }
+
+ override fun getMetricsCategory(): Int {
+ return 0
+ }
+
+ override fun getLongClickIntent(): Intent? {
+ return null
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
index 3b9f5dc8ea03..257d6a7abda1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
@@ -16,6 +16,7 @@
package com.android.systemui.qs.tiles
+import android.content.ComponentName
import android.content.Intent
import android.os.Handler
import android.os.Looper
@@ -27,7 +28,8 @@ import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE
import com.android.systemui.controls.management.ControlsListingController
-import com.android.systemui.controls.ui.ControlsDialog
+import com.android.systemui.controls.ui.ControlsActivity
+import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
@@ -40,7 +42,6 @@ import com.android.systemui.statusbar.FeatureFlags
import com.android.systemui.util.settings.GlobalSettings
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
-import javax.inject.Provider
class DeviceControlsTile @Inject constructor(
host: QSHost,
@@ -52,7 +53,6 @@ class DeviceControlsTile @Inject constructor(
qsLogger: QSLogger,
private val controlsComponent: ControlsComponent,
private val featureFlags: FeatureFlags,
- private val dialogProvider: Provider<ControlsDialog>,
globalSettings: GlobalSettings
) : QSTileImpl<QSTile.State>(
host,
@@ -72,7 +72,6 @@ class DeviceControlsTile @Inject constructor(
private var hasControlsApps = AtomicBoolean(false)
private val intent = Intent(Settings.ACTION_DEVICE_CONTROLS_SETTINGS)
- private var controlsDialog: ControlsDialog? = null
private val icon = ResourceIcon.get(R.drawable.ic_device_light)
private val listingCallback = object : ControlsListingController.ControlsListingCallback {
@@ -102,27 +101,19 @@ class DeviceControlsTile @Inject constructor(
}
override fun handleDestroy() {
- dismissDialog()
super.handleDestroy()
}
- private fun createDialog() {
- if (controlsDialog?.isShowing != true) {
- controlsDialog = dialogProvider.get()
- }
- }
-
- private fun dismissDialog() {
- controlsDialog?.dismiss()?.also {
- controlsDialog = null
- }
- }
-
override fun handleClick() {
if (state.state == Tile.STATE_ACTIVE) {
mUiHandler.post {
- createDialog()
- controlsDialog?.show(controlsComponent.getControlsUiController().get())
+ mHost.collapsePanels()
+ val i = Intent().apply {
+ component = ComponentName(mContext, ControlsActivity::class.java)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+ putExtra(ControlsUiController.BACK_TO_GLOBAL_ACTIONS, false)
+ }
+ mContext.startActivity(i)
}
}
}
@@ -133,9 +124,6 @@ class DeviceControlsTile @Inject constructor(
state.contentDescription = state.label
state.icon = icon
if (controlsComponent.isEnabled() && hasControlsApps.get()) {
- if (controlsDialog == null) {
- mUiHandler.post(this::createDialog)
- }
if (controlsComponent.getVisibility() == AVAILABLE) {
state.state = Tile.STATE_ACTIVE
state.secondaryLabel = ""
@@ -146,7 +134,6 @@ class DeviceControlsTile @Inject constructor(
state.stateDescription = state.secondaryLabel
} else {
state.state = Tile.STATE_UNAVAILABLE
- dismissDialog()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
index c066619d049a..bb8c36776d57 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
@@ -136,7 +136,7 @@ public class CropView extends View {
case MotionEvent.ACTION_UP:
if (mCurrentDraggingBoundary != CropBoundary.NONE) {
// Commit the delta to the stored crop values.
- commitDeltas();
+ commitDeltas(mCurrentDraggingBoundary);
updateListener(event);
}
}
@@ -184,12 +184,12 @@ public class CropView extends View {
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- commitDeltas();
+ commitDeltas(boundary);
}
@Override
public void onAnimationCancel(Animator animation) {
- commitDeltas();
+ commitDeltas(boundary);
}
});
animator.setFloatValues(0f, 1f);
@@ -228,11 +228,14 @@ public class CropView extends View {
mCropInteractionListener = listener;
}
- private void commitDeltas() {
- mTopCrop += mTopDelta;
- mBottomCrop += mBottomDelta;
- mTopDelta = 0;
- mBottomDelta = 0;
+ private void commitDeltas(CropBoundary boundary) {
+ if (boundary == CropBoundary.TOP) {
+ mTopCrop += mTopDelta;
+ mTopDelta = 0;
+ } else if (boundary == CropBoundary.BOTTOM) {
+ mBottomCrop += mBottomDelta;
+ mBottomDelta = 0;
+ }
}
private void updateListener(MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 4dc846e0e95d..db997053af23 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -339,14 +339,22 @@ public class LongScreenshotActivity extends Activity {
}
@Override
- public void onComplete(ImageTileSet imageTileSet) {
+ public void onComplete(ImageTileSet imageTileSet, int pageSize) {
Log.i(TAG, "Got tiles " + imageTileSet.getWidth() + " x "
+ imageTileSet.getHeight());
mPreview.setImageDrawable(imageTileSet.getDrawable());
updateCropLocation();
mMagnifierView.setDrawable(imageTileSet.getDrawable(),
imageTileSet.getWidth(), imageTileSet.getHeight());
- mCropView.animateBoundaryTo(CropView.CropBoundary.BOTTOM, 0.5f);
+ // Original boundaries go from the image tile set's y=0 to y=pageSize, so
+ // we animate to that as a starting crop position.
+ float topFraction = Math.max(0,
+ -imageTileSet.getTop() / (float) imageTileSet.getHeight());
+ float bottomFraction = Math.min(1f,
+ 1 - (imageTileSet.getBottom() - pageSize)
+ / (float) imageTileSet.getHeight());
+ mCropView.animateBoundaryTo(CropView.CropBoundary.TOP, topFraction);
+ mCropView.animateBoundaryTo(CropView.CropBoundary.BOTTOM, bottomFraction);
mBackgroundExecutor.execute(() -> saveCacheBitmap(imageTileSet));
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
index b62e2c34ed6e..34094cd81120 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
@@ -171,7 +171,7 @@ public class ScrollCaptureController {
if (mImageTileSet.isEmpty()) {
mCaptureCallback.onError();
} else {
- mCaptureCallback.onComplete(mImageTileSet);
+ mCaptureCallback.onComplete(mImageTileSet, session.getPageHeight());
}
}
@@ -179,7 +179,7 @@ public class ScrollCaptureController {
* Callback for image capture completion or error.
*/
public interface ScrollCaptureCallback {
- void onComplete(ImageTileSet imageTileSet);
+ void onComplete(ImageTileSet imageTileSet, int pageHeight);
void onError();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
index 1d59257c9c4f..c8e0d60ce304 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
@@ -90,4 +90,8 @@ public class FeatureFlags {
public boolean isPMLiteEnabled() {
return mFlagReader.isEnabled(R.bool.flag_pm_lite);
}
+
+ public boolean isAlarmTileAvailable() {
+ return mFlagReader.isEnabled(R.bool.flag_alarm_tile);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
index 992015320fa0..e090d0b13205 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java
@@ -31,6 +31,7 @@ import android.widget.TextView;
import com.android.internal.R;
import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.ConversationLayout;
+import com.android.internal.widget.ImageFloatingTextView;
import com.android.internal.widget.NotificationExpandButton;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationContentView;
@@ -430,6 +431,8 @@ public class NotificationGroupingUtil {
public static final int[] MARGIN_ADJUSTED_VIEWS = {
R.id.notification_headerless_view_column,
+ R.id.text,
+ R.id.big_text,
R.id.title,
R.id.notification_main_column,
R.id.notification_header};
@@ -458,6 +461,10 @@ public class NotificationGroupingUtil {
if (target == null) {
return;
}
+ if (target instanceof ImageFloatingTextView) {
+ ((ImageFloatingTextView) target).setHasImage(iconVisible);
+ return;
+ }
final Integer data = (Integer) target.getTag(iconVisible
? com.android.internal.R.id.tag_margin_end_when_icon_visible
: com.android.internal.R.id.tag_margin_end_when_icon_gone);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 3496581b1b8a..e1199077efb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -16,9 +16,6 @@
package com.android.systemui.statusbar;
-import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN_REVERSE;
-import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE;
-
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -34,7 +31,6 @@ import android.view.WindowInsets;
import android.view.accessibility.AccessibilityNodeInfo;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.notification.NotificationUtils;
@@ -55,8 +51,6 @@ import com.android.systemui.statusbar.phone.NotificationIconContainer;
public class NotificationShelf extends ActivatableNotificationView implements
View.OnLayoutChangeListener, StateListener {
- private static final boolean USE_ANIMATIONS_WHEN_OPENING =
- SystemProperties.getBoolean("debug.icon_opening_animations", true);
private static final boolean ICON_ANMATIONS_WHILE_SCROLLING
= SystemProperties.getBoolean("debug.icon_scroll_animations", true);
private static final int TAG_CONTINUOUS_CLIPPING = R.id.continuous_clipping_tag;
@@ -174,18 +168,9 @@ public class NotificationShelf extends ActivatableNotificationView implements
float viewEnd = lastViewState.yTranslation + lastViewState.height;
viewState.copyFrom(lastViewState);
viewState.height = getIntrinsicHeight();
-
viewState.yTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height,
getFullyClosedTranslation());
viewState.zTranslation = ambientState.getBaseZHeight();
- // For the small display size, it's not enough to make the icon not covered by
- // the top cutout so the denominator add the height of cutout.
- // Totally, (getIntrinsicHeight() * 2 + mCutoutHeight) should be smaller then
- // mAmbientState.getTopPadding().
- float openedAmount = (viewState.yTranslation - getFullyClosedTranslation())
- / (getIntrinsicHeight() * 2 + mCutoutHeight);
- openedAmount = Math.min(1.0f, openedAmount);
- viewState.openedAmount = openedAmount;
viewState.clipTopAmount = 0;
viewState.alpha = 1;
viewState.belowSpeedBump = mHostLayoutController.getSpeedBumpIndex() == 0;
@@ -220,11 +205,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
View lastChild = mAmbientState.getLastVisibleBackgroundChild();
mNotGoneIndex = -1;
float interpolationStart = mMaxLayoutHeight - getIntrinsicHeight() * 2;
- float expandAmount = 0.0f;
- if (shelfStart >= interpolationStart) {
- expandAmount = (shelfStart - interpolationStart) / getIntrinsicHeight();
- expandAmount = Math.min(1.0f, expandAmount);
- }
// find the first view that doesn't overlap with the shelf
int notGoneIndex = 0;
int colorOfViewBeforeLast = NO_COLOR;
@@ -239,7 +219,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
boolean scrollingFast = currentScrollVelocity > mScrollFastThreshold
|| (mAmbientState.isExpansionChanging()
&& Math.abs(mAmbientState.getExpandingVelocity()) > mScrollFastThreshold);
- boolean scrolling = currentScrollVelocity > 0;
boolean expandingAnimated = mAmbientState.isExpansionChanging()
&& !mAmbientState.isPanelTracking();
int baseZHeight = mAmbientState.getBaseZHeight();
@@ -249,8 +228,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
ActivatableNotificationView previousAnv = null;
for (int i = 0; i < mHostLayoutController.getChildCount(); i++) {
- ExpandableView child = (ExpandableView) mHostLayoutController.getChildAt(i);
-
+ ExpandableView child = mHostLayoutController.getChildAt(i);
if (!child.needsClippingToShelf() || child.getVisibility() == GONE) {
continue;
}
@@ -268,9 +246,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
int clipTop = updateNotificationClipHeight(child, notificationClipEnd, notGoneIndex);
clipTopAmount = Math.max(clipTop, clipTopAmount);
-
- float inShelfAmount = updateShelfTransformation(child, expandAmount, scrolling,
- scrollingFast, expandingAnimated, isLastChild);
+ final float inShelfAmount = updateShelfTransformation(child, scrollingFast,
+ expandingAnimated, isLastChild);
// If the current row is an ExpandableNotificationRow, update its color, roundedness,
// and icon state.
if (child instanceof ExpandableNotificationRow) {
@@ -498,56 +475,40 @@ public class NotificationShelf extends ActivatableNotificationView implements
/**
* @return the amount how much this notification is in the shelf
*/
- private float updateShelfTransformation(ExpandableView view, float expandAmount,
- boolean scrolling, boolean scrollingFast, boolean expandingAnimated,
- boolean isLastChild) {
- StatusBarIconView icon = view.getShelfIcon();
- NotificationIconContainer.IconState iconState = getIconState(icon);
+ private float updateShelfTransformation(ExpandableView view, boolean scrollingFast,
+ boolean expandingAnimated, boolean isLastChild) {
// Let calculate how much the view is in the shelf
float viewStart = view.getTranslationY();
int fullHeight = view.getActualHeight() + mPaddingBetweenElements;
float iconTransformStart = calculateIconTransformationStart(view);
- float transformDistance = getIntrinsicHeight() * 1.5f;
- transformDistance *= NotificationUtils.interpolate(1.f, 1.5f, expandAmount);
- transformDistance = Math.min(transformDistance, fullHeight);
-
// Let's make sure the transform distance is
// at most to the icon (relevant for conversations)
- transformDistance = Math.min(viewStart + fullHeight - iconTransformStart,
- transformDistance);
+ float transformDistance = Math.min(
+ viewStart + fullHeight - iconTransformStart,
+ getIntrinsicHeight());
if (isLastChild) {
fullHeight = Math.min(fullHeight, view.getMinHeight() - getIntrinsicHeight());
- transformDistance = Math.min(transformDistance, view.getMinHeight()
- - getIntrinsicHeight());
+ transformDistance = Math.min(
+ transformDistance,
+ view.getMinHeight() - getIntrinsicHeight());
}
float viewEnd = viewStart + fullHeight;
- handleCustomTransformHeight(view, expandingAnimated, iconState);
-
- float fullTransitionAmount;
- float iconTransitionAmount;
- float contentTransformationAmount;
+ float fullTransitionAmount = 0.0f;
+ float iconTransitionAmount = 0.0f;
float shelfStart = getTranslationY();
- boolean fullyInOrOut = true;
- if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || view.isInShelf())
+
+ if (viewEnd >= shelfStart
+ && (!mAmbientState.isUnlockHintRunning() || view.isInShelf())
&& (mAmbientState.isShadeExpanded()
|| (!view.isPinned() && !view.isHeadsUpAnimatingAway()))) {
- if (viewStart < shelfStart) {
- if (iconState != null && iconState.hasCustomTransformHeight()) {
- fullHeight = iconState.customTransformHeight;
- transformDistance = iconState.customTransformHeight;
- }
+ if (viewStart < shelfStart) {
float fullAmount = (shelfStart - viewStart) / fullHeight;
fullAmount = Math.min(1.0f, fullAmount);
- float interpolatedAmount = Interpolators.ACCELERATE_DECELERATE.getInterpolation(
- fullAmount);
- interpolatedAmount = NotificationUtils.interpolate(
- interpolatedAmount, fullAmount, expandAmount);
- fullTransitionAmount = 1.0f - interpolatedAmount;
-
+ fullTransitionAmount = 1.0f - fullAmount;
if (isLastChild) {
// Reduce icon transform distance to completely fade in shelf icon
// by the time the notification icon fades out, and vice versa
@@ -558,37 +519,14 @@ public class NotificationShelf extends ActivatableNotificationView implements
}
iconTransitionAmount = MathUtils.constrain(iconTransitionAmount, 0.0f, 1.0f);
iconTransitionAmount = 1.0f - iconTransitionAmount;
- fullyInOrOut = false;
} else {
+ // Fully in shelf.
fullTransitionAmount = 1.0f;
iconTransitionAmount = 1.0f;
}
-
- // Transforming the content
- contentTransformationAmount = (shelfStart - viewStart) / transformDistance;
- contentTransformationAmount = Math.min(1.0f, contentTransformationAmount);
- contentTransformationAmount = 1.0f - contentTransformationAmount;
- } else {
- fullTransitionAmount = 0.0f;
- iconTransitionAmount = 0.0f;
- contentTransformationAmount = 0.0f;
- }
- if (iconState != null && fullyInOrOut && !expandingAnimated && iconState.isLastExpandIcon) {
- iconState.isLastExpandIcon = false;
- iconState.customTransformHeight = NO_VALUE;
}
-
- // Update the content transformation amount
- if (view.isAboveShelf() || view.showingPulsing()
- || (!isLastChild && iconState != null && !iconState.translateContent)) {
- contentTransformationAmount = 0.0f;
- }
- view.setContentTransformationAmount(contentTransformationAmount, isLastChild);
-
- // Update the positioning of the icon
- updateIconPositioning(view, iconTransitionAmount, fullTransitionAmount,
- transformDistance, scrolling, scrollingFast, expandingAnimated, isLastChild);
-
+ updateIconPositioning(view, iconTransitionAmount,
+ scrollingFast, expandingAnimated, isLastChild);
return fullTransitionAmount;
}
@@ -607,87 +545,31 @@ public class NotificationShelf extends ActivatableNotificationView implements
return start;
}
- private void handleCustomTransformHeight(ExpandableView view, boolean expandingAnimated,
- NotificationIconContainer.IconState iconState) {
- if (iconState != null && expandingAnimated && mAmbientState.getScrollY() == 0
- && !mAmbientState.isOnKeyguard() && !iconState.isLastExpandIcon) {
- // We are expanding animated. Because we switch to a linear interpolation in this case,
- // the last icon may be stuck in between the shelf position and the notification
- // position, which looks pretty bad. We therefore optimize this case by applying a
- // shorter transition such that the icon is either fully in the notification or we clamp
- // it into the shelf if it's close enough.
- // We need to persist this, since after the expansion, the behavior should still be the
- // same.
- float position = mAmbientState.getIntrinsicPadding()
- + mHostLayoutController.getPositionInLinearLayout(view);
- int maxShelfStart = mMaxLayoutHeight - getIntrinsicHeight();
- if (position < maxShelfStart && position + view.getIntrinsicHeight() >= maxShelfStart
- && view.getTranslationY() < position) {
- iconState.isLastExpandIcon = true;
- iconState.customTransformHeight = NO_VALUE;
- // Let's check if we're close enough to snap into the shelf
- boolean forceInShelf = mMaxLayoutHeight - getIntrinsicHeight() - position
- < getIntrinsicHeight();
- if (!forceInShelf) {
- // We are overlapping the shelf but not enough, so the icon needs to be
- // repositioned
- iconState.customTransformHeight = (int) (mMaxLayoutHeight
- - getIntrinsicHeight() - position);
- }
- }
- }
- }
-
private void updateIconPositioning(ExpandableView view, float iconTransitionAmount,
- float fullTransitionAmount, float iconTransformDistance, boolean scrolling,
boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) {
StatusBarIconView icon = view.getShelfIcon();
NotificationIconContainer.IconState iconState = getIconState(icon);
if (iconState == null) {
return;
}
- boolean forceInShelf =
- iconState.isLastExpandIcon && !iconState.hasCustomTransformHeight();
boolean clampInShelf = iconTransitionAmount > 0.5f || isTargetClipped(view);
float clampedAmount = clampInShelf ? 1.0f : 0.0f;
if (iconTransitionAmount == clampedAmount) {
- iconState.noAnimations = (scrollingFast || expandingAnimated) && !forceInShelf;
- iconState.useFullTransitionAmount = iconState.noAnimations
- || (!ICON_ANMATIONS_WHILE_SCROLLING && iconTransitionAmount == 0.0f
- && scrolling);
- iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING
- && iconTransitionAmount == 0.0f && !mAmbientState.isExpansionChanging();
- iconState.translateContent = mMaxLayoutHeight - getTranslationY()
- - getIntrinsicHeight() > 0;
- }
- if (!forceInShelf && (scrollingFast || (expandingAnimated
- && iconState.useFullTransitionAmount && !ViewState.isAnimatingY(icon)))) {
+ iconState.noAnimations = (scrollingFast || expandingAnimated) && !isLastChild;
+ }
+ if (!isLastChild
+ && (scrollingFast || (expandingAnimated && !ViewState.isAnimatingY(icon)))) {
iconState.cancelAnimations(icon);
- iconState.useFullTransitionAmount = true;
iconState.noAnimations = true;
}
- if (iconState.hasCustomTransformHeight()) {
- iconState.useFullTransitionAmount = true;
- }
- if (iconState.isLastExpandIcon) {
- iconState.translateContent = false;
- }
float transitionAmount;
if (mAmbientState.isHiddenAtAll() && !view.isInShelf()) {
transitionAmount = mAmbientState.isFullyHidden() ? 1 : 0;
- } else if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING
- || iconState.useFullTransitionAmount
- || iconState.useLinearTransitionAmount) {
- transitionAmount = iconTransitionAmount;
} else {
transitionAmount = iconTransitionAmount;
iconState.needsCannedAnimation = iconState.clampedAppearAmount != clampedAmount
&& !mNoAnimationsInThisFrame;
}
- iconState.iconAppearAmount = !USE_ANIMATIONS_WHEN_OPENING
- || iconState.useFullTransitionAmount
- ? fullTransitionAmount
- : transitionAmount;
iconState.clampedAppearAmount = clampedAmount;
setIconTransformationAmount(view, transitionAmount, isLastChild);
}
@@ -706,8 +588,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
return endOfTarget >= getTranslationY() - mPaddingBetweenElements;
}
- private void setIconTransformationAmount(ExpandableView view,
- float transitionAmount,
+ private void setIconTransformationAmount(ExpandableView view, float transitionAmount,
boolean isLastChild) {
if (!(view instanceof ExpandableNotificationRow)) {
return;
@@ -718,32 +599,30 @@ public class NotificationShelf extends ActivatableNotificationView implements
if (iconState == null) {
return;
}
- iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon);
- boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf();
- if (isAppearing) {
- iconState.hidden = true;
- iconState.iconAppearAmount = 0.0f;
- }
iconState.alpha = transitionAmount;
+ boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf();
+ iconState.hidden = isAppearing
+ || (view instanceof ExpandableNotificationRow
+ && ((ExpandableNotificationRow) view).isLowPriority()
+ && mShelfIcons.hasMaxNumDot())
+ || (transitionAmount == 0.0f && !iconState.isAnimating(icon))
+ || row.isAboveShelf()
+ || row.showingPulsing()
+ || (!row.isInShelf() && isLastChild)
+ || row.getTranslationZ() > mAmbientState.getBaseZHeight();
+ iconState.iconAppearAmount = iconState.hidden? 0f : transitionAmount;
+
// Fade in icons at shelf start
// This is important for conversation icons, which are badged and need x reset
iconState.xTranslation = mShelfIcons.getActualPaddingStart();
- boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf();
+ final boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf();
if (stayingInShelf) {
iconState.iconAppearAmount = 1.0f;
iconState.alpha = 1.0f;
- iconState.scaleX = 1.0f;
- iconState.scaleY = 1.0f;
iconState.hidden = false;
}
- if (row.isAboveShelf()
- || row.showingPulsing()
- || (!row.isInShelf() && (isLastChild && row.areGutsExposed()
- || row.getTranslationZ() > mAmbientState.getBaseZHeight()))) {
- iconState.hidden = true;
- }
int backgroundColor = getBackgroundColorWithoutTint();
int shelfColor = icon.getContrastedStaticDrawableColor(backgroundColor);
if (row.isShowingIcon() && shelfColor != StatusBarIconView.NO_COLOR) {
@@ -819,42 +698,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
return ret;
}
- private void setOpenedAmount(float openedAmount) {
- mNoAnimationsInThisFrame = openedAmount == 1.0f && mOpenedAmount == 0.0f;
- mOpenedAmount = openedAmount;
- if (!mAmbientState.isPanelFullWidth() || mAmbientState.isDozing()) {
- // We don't do a transformation at all, lets just assume we are fully opened
- openedAmount = 1.0f;
- }
- int start = mRelativeOffset;
- if (isLayoutRtl()) {
- start = getWidth() - start - mCollapsedIcons.getWidth();
- }
- int width = (int) NotificationUtils.interpolate(
- start + mCollapsedIcons.getFinalTranslationX(),
- mShelfIcons.getWidth(),
- FAST_OUT_SLOW_IN_REVERSE.getInterpolation(openedAmount));
- mShelfIcons.setActualLayoutWidth(width);
- boolean hasOverflow = mCollapsedIcons.hasOverflow();
- int collapsedPadding = mCollapsedIcons.getPaddingEnd();
- if (!hasOverflow) {
- // we have to ensure that adding the low priority notification won't lead to an
- // overflow
- collapsedPadding -= mCollapsedIcons.getNoOverflowExtraPadding();
- } else {
- // Partial overflow padding will fill enough space to add extra dots
- collapsedPadding -= mCollapsedIcons.getPartialOverflowExtraPadding();
- }
- float padding = NotificationUtils.interpolate(collapsedPadding,
- mShelfIcons.getPaddingEnd(),
- openedAmount);
- mShelfIcons.setActualPaddingEnd(padding);
- float paddingStart = NotificationUtils.interpolate(start,
- mShelfIcons.getPaddingStart(), openedAmount);
- mShelfIcons.setActualPaddingStart(paddingStart);
- mShelfIcons.setOpenedAmount(openedAmount);
- }
-
public void setMaxLayoutHeight(int maxLayoutHeight) {
mMaxLayoutHeight = maxLayoutHeight;
}
@@ -947,7 +790,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
}
private class ShelfState extends ExpandableViewState {
- private float openedAmount;
private boolean hasItemsInStableShelf;
@Override
@@ -957,7 +799,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
}
super.applyToView(view);
- setOpenedAmount(openedAmount);
updateAppearance();
setHasItemsInStableShelf(hasItemsInStableShelf);
mShelfIcons.setAnimationsEnabled(mAnimationsEnabled);
@@ -970,7 +811,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
}
super.animateTo(child, properties);
- setOpenedAmount(openedAmount);
updateAppearance();
setHasItemsInStableShelf(hasItemsInStableShelf);
mShelfIcons.setAnimationsEnabled(mAnimationsEnabled);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index d08f9736adf6..85a1aed68559 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -146,17 +146,19 @@ public class ActivityLaunchAnimator {
private final ExpandableNotificationRow mSourceNotification;
private final ExpandAnimationParameters mParams;
private final Rect mWindowCrop = new Rect();
- private final float mNotificationCornerRadius;
- private float mCornerRadius;
private boolean mIsFullScreenLaunch = true;
private final SyncRtSurfaceTransactionApplier mSyncRtTransactionApplier;
- public AnimationRunner(ExpandableNotificationRow sourceNofitication) {
- mSourceNotification = sourceNofitication;
+ private final float mNotificationStartTopCornerRadius;
+ private final float mNotificationStartBottomCornerRadius;
+
+ AnimationRunner(ExpandableNotificationRow sourceNotification) {
+ mSourceNotification = sourceNotification;
mParams = new ExpandAnimationParameters();
mSyncRtTransactionApplier = new SyncRtSurfaceTransactionApplier(mSourceNotification);
- mNotificationCornerRadius = Math.max(mSourceNotification.getCurrentTopRoundness(),
- mSourceNotification.getCurrentBottomRoundness());
+ mNotificationStartTopCornerRadius = mSourceNotification.getCurrentBackgroundRadiusTop();
+ mNotificationStartBottomCornerRadius =
+ mSourceNotification.getCurrentBackgroundRadiusBottom();
}
@Override
@@ -224,7 +226,10 @@ public class ActivityLaunchAnimator {
+ notificationHeight,
primary.position.y + primary.sourceContainerBounds.bottom,
progress);
- mCornerRadius = MathUtils.lerp(mNotificationCornerRadius,
+ mParams.topCornerRadius = MathUtils.lerp(mNotificationStartTopCornerRadius,
+ mWindowCornerRadius, progress);
+ mParams.bottomCornerRadius = MathUtils.lerp(
+ mNotificationStartBottomCornerRadius,
mWindowCornerRadius, progress);
applyParamsToWindow(primary);
applyParamsToNotification(mParams);
@@ -309,12 +314,13 @@ public class ActivityLaunchAnimator {
Matrix m = new Matrix();
m.postTranslate(0, (float) (mParams.top - app.position.y));
mWindowCrop.set(mParams.left, 0, mParams.right, mParams.getHeight());
+ float cornerRadius = Math.min(mParams.topCornerRadius, mParams.bottomCornerRadius);
SurfaceParams params = new SurfaceParams.Builder(app.leash)
.withAlpha(1f)
.withMatrix(m)
.withWindowCrop(mWindowCrop)
.withLayer(app.prefixOrderIndex)
- .withCornerRadius(mCornerRadius)
+ .withCornerRadius(cornerRadius)
.withVisibility(true)
.build();
mSyncRtTransactionApplier.scheduleApply(params);
@@ -339,6 +345,8 @@ public class ActivityLaunchAnimator {
int bottom;
int startClipTopAmount;
int parentStartClipTopAmount;
+ float topCornerRadius;
+ float bottomCornerRadius;
public ExpandAnimationParameters() {
}
@@ -389,6 +397,14 @@ public class ActivityLaunchAnimator {
public float getStartTranslationZ() {
return startTranslationZ;
}
+
+ public float getTopCornerRadius() {
+ return topCornerRadius;
+ }
+
+ public float getBottomCornerRadius() {
+ return bottomCornerRadius;
+ }
}
public interface Callback {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
index 004cf9968a77..b0d41f155713 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
@@ -218,13 +218,18 @@ class ConversationNotificationManager @Inject constructor(
})
}
+ private fun ConversationState.shouldIncrementUnread(newBuilder: Notification.Builder) =
+ if (notification.flags and Notification.FLAG_ONLY_ALERT_ONCE != 0) {
+ false
+ } else {
+ val oldBuilder = Notification.Builder.recoverBuilder(context, notification)
+ Notification.areStyledNotificationsVisiblyDifferent(oldBuilder, newBuilder)
+ }
+
fun getUnreadCount(entry: NotificationEntry, recoveredBuilder: Notification.Builder): Int =
states.compute(entry.key) { _, state ->
val newCount = state?.run {
- val old = Notification.Builder.recoverBuilder(context, notification)
- val increment = Notification
- .areStyledNotificationsVisiblyDifferent(old, recoveredBuilder)
- if (increment) unreadCount + 1 else unreadCount
+ if (shouldIncrementUnread(recoveredBuilder)) unreadCount + 1 else unreadCount
} ?: 1
ConversationState(newCount, entry.sbn.notification)
}!!.unreadCount
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
index 18806effc545..5a3f48cec290 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/HighPriorityProvider.java
@@ -99,17 +99,11 @@ public class HighPriorityProvider {
private boolean hasHighPriorityCharacteristics(NotificationEntry entry) {
return !hasUserSetImportance(entry)
- && (isImportantOngoing(entry)
- || entry.getSbn().getNotification().hasMediaSession()
+ && (entry.getSbn().getNotification().hasMediaSession()
|| isPeopleNotification(entry)
|| isMessagingStyle(entry));
}
- private boolean isImportantOngoing(NotificationEntry entry) {
- return entry.getSbn().getNotification().isForegroundService()
- && entry.getRanking().getImportance() >= NotificationManager.IMPORTANCE_LOW;
- }
-
private boolean isMessagingStyle(NotificationEntry entry) {
return Notification.MessagingStyle.class.equals(
entry.getSbn().getNotification().getNotificationStyle());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 31d052d75998..18e5ead7fbb8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -883,8 +883,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
}
private void applyBackgroundRoundness(float topRadius, float bottomRadius) {
- mBackgroundDimmed.setRoundness(topRadius, bottomRadius);
- mBackgroundNormal.setRoundness(topRadius, bottomRadius);
+ mBackgroundDimmed.setRadius(topRadius, bottomRadius);
+ mBackgroundNormal.setRadius(topRadius, bottomRadius);
}
@Override
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 0f23b770aacd..046fbd5b616b 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
@@ -166,7 +166,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private int mMaxSmallHeightLarge;
private int mMaxSmallHeightMedia;
private int mMaxExpandedHeight;
- private int mMaxCallHeight;
private int mIncreasedPaddingBetweenElements;
private int mNotificationLaunchHeight;
private boolean mMustStayOnScreen;
@@ -347,6 +346,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private SystemNotificationAsyncTask mSystemNotificationAsyncTask =
new SystemNotificationAsyncTask();
+ private float mTopRoundnessDuringExpandAnimation;
+ private float mBottomRoundnessDuringExpandAnimation;
+
/**
* Returns whether the given {@code statusBarNotification} is a system notification.
* <b>Note</b>, this should be run in the background thread if possible as it makes multiple IPC
@@ -687,7 +689,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
// them a headerless design, then remove this hack.
smallHeight = mMaxSmallHeightLarge;
} else if (isCallLayout) {
- smallHeight = mMaxCallHeight;
+ smallHeight = mMaxExpandedHeight;
} else if (mUseIncreasedCollapsedHeight && layout == mPrivateLayout) {
smallHeight = mMaxSmallHeightLarge;
} else {
@@ -1621,8 +1623,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
R.dimen.notification_min_height_media);
mMaxExpandedHeight = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_max_height);
- mMaxCallHeight = NotificationUtils.getFontScaledHeight(mContext,
- R.dimen.call_notification_full_height);
mMaxHeadsUpHeightBeforeN = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_max_heads_up_height_legacy);
mMaxHeadsUpHeightBeforeP = NotificationUtils.getFontScaledHeight(mContext,
@@ -2012,6 +2012,24 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return false;
}
+ @Override
+ public float getCurrentTopRoundness() {
+ if (mExpandAnimationRunning) {
+ return mTopRoundnessDuringExpandAnimation;
+ }
+
+ return super.getCurrentTopRoundness();
+ }
+
+ @Override
+ public float getCurrentBottomRoundness() {
+ if (mExpandAnimationRunning) {
+ return mBottomRoundnessDuringExpandAnimation;
+ }
+
+ return super.getCurrentBottomRoundness();
+ }
+
public void applyExpandAnimationParams(ExpandAnimationParameters params) {
if (params == null) {
return;
@@ -2027,17 +2045,22 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
int top = params.getTop();
float interpolation = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(params.getProgress());
int startClipTopAmount = params.getStartClipTopAmount();
+ int clipTopAmount = (int) MathUtils.lerp(startClipTopAmount, 0, interpolation);
if (mNotificationParent != null) {
float parentY = mNotificationParent.getTranslationY();
top -= parentY;
mNotificationParent.setTranslationZ(translationZ);
+
+ // When the expanding notification is below its parent, the parent must be clipped
+ // exactly how it was clipped before the animation. When the expanding notification is
+ // on or above its parent (top <= 0), then the parent must be clipped exactly 'top'
+ // pixels to show the expanding notification, while still taking the decreasing
+ // notification clipTopAmount into consideration, so 'top + clipTopAmount'.
int parentStartClipTopAmount = params.getParentStartClipTopAmount();
- if (startClipTopAmount != 0) {
- int clipTopAmount = (int) MathUtils.lerp(parentStartClipTopAmount,
- parentStartClipTopAmount - startClipTopAmount,
- interpolation);
- mNotificationParent.setClipTopAmount(clipTopAmount);
- }
+ int parentClipTopAmount = Math.min(parentStartClipTopAmount,
+ top + clipTopAmount);
+ mNotificationParent.setClipTopAmount(parentClipTopAmount);
+
mNotificationParent.setExtraWidthForClipping(extraWidthForClipping);
float clipBottom = Math.max(params.getBottom(),
parentY + mNotificationParent.getActualHeight()
@@ -2046,12 +2069,15 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
int minimumHeightForClipping = (int) (clipBottom - clipTop);
mNotificationParent.setMinimumHeightForClipping(minimumHeightForClipping);
} else if (startClipTopAmount != 0) {
- int clipTopAmount = (int) MathUtils.lerp(startClipTopAmount, 0, interpolation);
setClipTopAmount(clipTopAmount);
}
setTranslationY(top);
setActualHeight(params.getHeight());
+ mTopRoundnessDuringExpandAnimation = params.getTopCornerRadius() / mOutlineRadius;
+ mBottomRoundnessDuringExpandAnimation = params.getBottomCornerRadius() / mOutlineRadius;
+ invalidateOutline();
+
mBackgroundNormal.setExpandAnimationParams(params);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
index 85f556fa733c..3728388f63b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
@@ -27,7 +27,6 @@ import android.util.AttributeSet;
import android.view.View;
import android.view.ViewOutlineProvider;
-import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -83,8 +82,8 @@ public abstract class ExpandableOutlineView extends ExpandableView {
private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
- if (!mCustomOutline && mCurrentTopRoundness == 0.0f
- && mCurrentBottomRoundness == 0.0f && !mAlwaysRoundBothCorners
+ if (!mCustomOutline && getCurrentTopRoundness() == 0.0f
+ && getCurrentBottomRoundness() == 0.0f && !mAlwaysRoundBothCorners
&& !mTopAmountRounded) {
int translation = mShouldTranslateContents ? (int) getTranslation() : 0;
int left = Math.max(translation, 0);
@@ -135,10 +134,12 @@ public abstract class ExpandableOutlineView extends ExpandableView {
? mOutlineRadius : getCurrentBackgroundRadiusBottom();
if (topRoundness + bottomRoundness > height) {
float overShoot = topRoundness + bottomRoundness - height;
- topRoundness -= overShoot * mCurrentTopRoundness
- / (mCurrentTopRoundness + mCurrentBottomRoundness);
- bottomRoundness -= overShoot * mCurrentBottomRoundness
- / (mCurrentTopRoundness + mCurrentBottomRoundness);
+ float currentTopRoundness = getCurrentTopRoundness();
+ float currentBottomRoundness = getCurrentBottomRoundness();
+ topRoundness -= overShoot * currentTopRoundness
+ / (currentTopRoundness + currentBottomRoundness);
+ bottomRoundness -= overShoot * currentBottomRoundness
+ / (currentTopRoundness + currentBottomRoundness);
}
getRoundedRectPath(left, top, right, bottom, topRoundness, bottomRoundness, mTmpPath);
return mTmpPath;
@@ -267,7 +268,7 @@ public abstract class ExpandableOutlineView extends ExpandableView {
if (mTopAmountRounded) {
return mOutlineRadius;
}
- return mCurrentTopRoundness * mOutlineRadius;
+ return getCurrentTopRoundness() * mOutlineRadius;
}
public float getCurrentTopRoundness() {
@@ -278,8 +279,8 @@ public abstract class ExpandableOutlineView extends ExpandableView {
return mCurrentBottomRoundness;
}
- protected float getCurrentBackgroundRadiusBottom() {
- return mCurrentBottomRoundness * mOutlineRadius;
+ public float getCurrentBackgroundRadiusBottom() {
+ return getCurrentBottomRoundness() * mOutlineRadius;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index ba03d01b20b0..73e080423d40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -69,7 +69,6 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
private float mContentTranslation;
protected boolean mLastInSection;
protected boolean mFirstInSection;
- boolean mIsBeingSwiped;
public ExpandableView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -174,14 +173,6 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
return false;
}
- public void setIsBeingSwiped(boolean swiped) {
- mIsBeingSwiped = swiped;
- }
-
- public boolean isBeingSwiped() {
- return mIsBeingSwiped;
- }
-
public boolean isHeadsUpAnimatingAway() {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 62d596b60a89..95885633a3e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -224,10 +224,9 @@ public class NotificationBackgroundView extends View {
}
/**
- * Sets the current top and bottom roundness amounts for this background, between 0.0 (not
- * rounded) and 1.0 (maximally rounded).
+ * Sets the current top and bottom radius for this background.
*/
- public void setRoundness(float topRoundness, float bottomRoundness) {
+ public void setRadius(float topRoundness, float bottomRoundness) {
if (topRoundness == mCornerRadii[0] && bottomRoundness == mCornerRadii[4]) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
index 4541ebf4c4f2..12e94cbc1ab9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
@@ -34,7 +34,7 @@ class NotificationCallTemplateViewWrapper constructor(
) : NotificationTemplateViewWrapper(ctx, view, row) {
private val minHeightWithActions: Int =
- NotificationUtils.getFontScaledHeight(ctx, R.dimen.call_notification_full_height)
+ NotificationUtils.getFontScaledHeight(ctx, R.dimen.notification_max_height)
private val callLayout: CallLayout = view as CallLayout
private lateinit var conversationIconView: CachingIconView
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index d8ee102064e1..2b194ba15816 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -34,7 +34,6 @@ import android.widget.RemoteViews;
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.NotificationExpandButton;
import com.android.systemui.R;
import com.android.systemui.statusbar.CrossFadeHelper;
@@ -638,10 +637,6 @@ public class NotificationChildrenContainer extends ViewGroup {
childState.location = parentState.location;
childState.inShelf = parentState.inShelf;
yPosition += intrinsicHeight;
- if (child.isExpandAnimationRunning()) {
- launchTransitionCompensation = -ambientState.getExpandAnimationTopChange();
- }
-
}
if (mOverflowNumber != null) {
ExpandableNotificationRow overflowView = mAttachedChildren.get(Math.min(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
index 45f5b3136b9b..b1ac12e84fb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.stack;
import android.content.res.Resources;
import android.util.MathUtils;
+import android.view.View;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
@@ -47,6 +48,10 @@ public class NotificationRoundnessManager {
private ExpandableNotificationRow mTrackedHeadsUp;
private float mAppearFraction;
+ private ExpandableView mSwipedView = null;
+ private ExpandableView mViewBeforeSwipedView = null;
+ private ExpandableView mViewAfterSwipedView = null;
+
@Inject
NotificationRoundnessManager(
KeyguardBypassController keyguardBypassController,
@@ -68,6 +73,11 @@ public class NotificationRoundnessManager {
boolean updateViewWithoutCallback(ExpandableView view,
boolean animate) {
+ if (view == null
+ || view == mViewBeforeSwipedView
+ || view == mViewAfterSwipedView) {
+ return false;
+ }
float topRoundness = getRoundness(view, true /* top */);
float bottomRoundness = getRoundness(view, false /* top */);
boolean topChanged = view.setTopRoundness(topRoundness, animate);
@@ -105,9 +115,60 @@ public class NotificationRoundnessManager {
return false;
}
+ void setViewsAffectedBySwipe(
+ ExpandableView viewBefore,
+ ExpandableView viewSwiped,
+ ExpandableView viewAfter,
+ boolean cornerAnimationsEnabled) {
+ if (!cornerAnimationsEnabled) {
+ return;
+ }
+ final boolean animate = true;
+
+ ExpandableView oldViewBefore = mViewBeforeSwipedView;
+ mViewBeforeSwipedView = viewBefore;
+ if (oldViewBefore != null) {
+ final float bottomRoundness = getRoundness(oldViewBefore, false /* top */);
+ oldViewBefore.setBottomRoundness(bottomRoundness, animate);
+ }
+ if (viewBefore != null) {
+ viewBefore.setBottomRoundness(1f, animate);
+ }
+
+ ExpandableView oldSwipedview = mSwipedView;
+ mSwipedView = viewSwiped;
+ if (oldSwipedview != null) {
+ final float bottomRoundness = getRoundness(oldSwipedview, false /* top */);
+ final float topRoundness = getRoundness(oldSwipedview, true /* top */);
+ oldSwipedview.setTopRoundness(topRoundness, animate);
+ oldSwipedview.setBottomRoundness(bottomRoundness, animate);
+ }
+ if (viewSwiped != null) {
+ viewSwiped.setTopRoundness(1f, animate);
+ viewSwiped.setBottomRoundness(1f, animate);
+ }
+
+ ExpandableView oldViewAfter = mViewAfterSwipedView;
+ mViewAfterSwipedView = viewAfter;
+ if (oldViewAfter != null) {
+ final float topRoundness = getRoundness(oldViewAfter, true /* top */);
+ oldViewAfter.setTopRoundness(topRoundness, animate);
+ }
+ if (viewAfter != null) {
+ viewAfter.setTopRoundness(1f, animate);
+ }
+ }
+
private float getRoundness(ExpandableView view, boolean top) {
+ if (view == null) {
+ return 0f;
+ }
+ if (view == mViewBeforeSwipedView
+ || view == mSwipedView
+ || view == mViewAfterSwipedView) {
+ return 1f;
+ }
if ((view.isPinned()
- || view.isBeingSwiped()
|| (view.isHeadsUpAnimatingAway()) && !mExpanded)) {
return 1.0f;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index 6c8cdf67d974..b06f7d25db16 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -318,9 +318,6 @@ class NotificationSectionsManager @Inject internal constructor(
(child == null || row != null && nextBucket != row.entry.bucket)
if (isSectionBoundary && showHeaders) {
when (nextBucket) {
- BUCKET_HEADS_UP -> incomingState?.targetPosition = i + 1
- BUCKET_PEOPLE -> peopleState?.targetPosition = i + 1
- BUCKET_ALERTING -> alertingState?.targetPosition = i + 1
BUCKET_SILENT -> gentleState?.targetPosition = i + 1
}
}
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 417ff5e9aed0..970efd5cbfe2 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
@@ -1025,8 +1025,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
boolean clip = clipStart > start && clipStart < end
|| clipEnd >= start && clipEnd <= end;
clip &= !(first && mScrollAdapter.isScrolledToTop());
- child.setDistanceToTopRoundness(clip ? Math.max(start - clipStart, 0)
- : ExpandableView.NO_ROUNDNESS);
+ child.setDistanceToTopRoundness(ExpandableView.NO_ROUNDNESS);
first = false;
}
}
@@ -2292,9 +2291,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
ExpandableView child = (ExpandableView) getChildAt(i);
if (child.getVisibility() != View.GONE
&& !(child instanceof StackScrollerDecorView)
- && child != mShelf
- && (mSwipeHelper.getSwipedView() != child
- || !child.getResources().getBoolean(R.bool.flag_notif_updates))) {
+ && child != mShelf) {
children.add(child);
}
}
@@ -4993,28 +4990,48 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mSwipedOutViews.add(v);
}
- void onSwipeBegin(View v) {
- if (v instanceof ExpandableView) {
- ExpandableView ev = (ExpandableView) v;
- ev.setIsBeingSwiped(true);
- mController.getNoticationRoundessManager()
- .updateViewWithoutCallback(ev, true /* animate */);
+ void onSwipeBegin(View viewSwiped) {
+ if (!(viewSwiped instanceof ExpandableNotificationRow)) {
+ return;
}
- requestDisallowInterceptTouchEvent(true);
+ final int indexOfSwipedView = indexOfChild(viewSwiped);
+ if (indexOfSwipedView < 0) {
+ return;
+ }
+ mSectionsManager.updateFirstAndLastViewsForAllSections(
+ mSections, getChildrenWithBackground());
+ View viewBefore = null;
+ if (indexOfSwipedView > 0) {
+ viewBefore = getChildAt(indexOfSwipedView - 1);
+ if (mSectionsManager.beginsSection(viewSwiped, viewBefore)) {
+ viewBefore = null;
+ }
+ }
+ View viewAfter = null;
+ if (indexOfSwipedView < getChildCount()) {
+ viewAfter = getChildAt(indexOfSwipedView + 1);
+ if (mSectionsManager.beginsSection(viewAfter, viewSwiped)) {
+ viewAfter = null;
+ }
+ }
+ mController.getNoticationRoundessManager()
+ .setViewsAffectedBySwipe((ExpandableView) viewBefore,
+ (ExpandableView) viewSwiped,
+ (ExpandableView) viewAfter,
+ getResources().getBoolean(R.bool.flag_notif_updates));
+
updateFirstAndLastBackgroundViews();
+ requestDisallowInterceptTouchEvent(true);
updateContinuousShadowDrawing();
updateContinuousBackgroundDrawing();
requestChildrenUpdate();
}
- void onSwipeEnd(View v) {
- if (v instanceof ExpandableView) {
- ExpandableView ev = (ExpandableView) v;
- ev.setIsBeingSwiped(false);
- mController.getNoticationRoundessManager()
- .updateViewWithoutCallback(ev, true /* animate */);
- }
+ void onSwipeEnd() {
updateFirstAndLastBackgroundViews();
+ mController.getNoticationRoundessManager()
+ .setViewsAffectedBySwipe(null, null, null,
+ getResources().getBoolean(R.bool.flag_notif_updates));
}
void setTopHeadsUpEntry(NotificationEntry topEntry) {
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 399702869d70..7baad1cc265e 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
@@ -399,7 +399,7 @@ public class NotificationStackScrollLayoutController {
if (mView.getDismissAllInProgress()) {
return;
}
- mView.onSwipeEnd(view);
+ mView.onSwipeEnd();
if (view instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) view;
if (row.isHeadsUp()) {
@@ -459,7 +459,7 @@ public class NotificationStackScrollLayoutController {
@Override
public void onChildSnappedBack(View animView, float targetLeft) {
- mView.onSwipeEnd(animView);
+ mView.onSwipeEnd();
if (animView instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) animView;
if (row.isPinned() && !canChildBeDismissed(row)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 5d2203b57991..d7a98bdf2715 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -28,14 +28,12 @@ import android.view.ViewGroup;
import com.android.systemui.R;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.NotificationShelf;
-import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.FooterView;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
/**
@@ -156,7 +154,7 @@ public class StackScrollAlgorithm {
private void updateClipping(StackScrollAlgorithmState algorithmState,
AmbientState ambientState) {
float drawStart = !ambientState.isOnKeyguard() ? ambientState.getTopPadding()
- + ambientState.getStackTranslation() + ambientState.getExpandAnimationTopChange()
+ + ambientState.getStackTranslation()
: 0;
float clipStart = 0;
int childCount = algorithmState.visibleChildren.size();
@@ -329,9 +327,6 @@ public class StackScrollAlgorithm {
childViewState.location = ExpandableViewState.LOCATION_MAIN_AREA;
float inset = ambientState.getTopPadding() + ambientState.getStackTranslation()
+ ambientState.getSectionPadding();
- if (i <= algorithmState.getIndexOfExpandingNotification()) {
- inset += ambientState.getExpandAnimationTopChange();
- }
if (child.mustStayOnScreen() && childViewState.yTranslation >= 0) {
// Even if we're not scrolled away we're in view and we're also not in the
// shelf. We can relax the constraints and let us scroll off the top!
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 85d8df8e6057..c23f1ad6f9c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -148,6 +148,11 @@ public class DozeParameters implements TunerService.Tunable,
return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
}
+ public int getQuickPickupAodDuration() {
+ return getInt("doze.gesture.quickpickup.duration",
+ R.integer.doze_quick_pickup_aod_duration);
+ }
+
/**
* For how long a wallpaper can be visible in AoD before it fades aways.
* @return duration in millis.
@@ -175,6 +180,10 @@ public class DozeParameters implements TunerService.Tunable,
return mDozeAlwaysOn && !mBatteryController.isAodPowerSave();
}
+ public boolean isQuickPickupEnabled() {
+ return mAmbientDisplayConfiguration.quickPickupSensorEnabled(UserHandle.USER_CURRENT);
+ }
+
/**
* Some screens need to be completely black before changing the display power mode,
* unexpected behavior might happen if this parameter isn't respected.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 9561851ab28b..89b97aef6283 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -155,7 +155,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
private int mCannedAnimationStartIndex = -1;
private int mSpeedBumpIndex = -1;
private int mIconSize;
- private float mOpenedAmount = 0.0f;
private boolean mDisallowNextAnimation;
private boolean mAnimationsEnabled = true;
private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons;
@@ -349,6 +348,10 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
}
}
+ public boolean hasMaxNumDot() {
+ return mNumDots >= MAX_DOTS;
+ }
+
private boolean areAnimationsEnabled(StatusBarIconView icon) {
return mAnimationsEnabled || icon == mIsolatedIcon;
}
@@ -391,7 +394,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
float overflowStart = getMaxOverflowStart();
mVisualOverflowStart = 0;
mFirstVisibleIconState = null;
- boolean hasAmbient = mSpeedBumpIndex != -1 && mSpeedBumpIndex < getChildCount();
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
IconState iconState = mIconStates.get(view);
@@ -410,10 +412,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
float drawingScale = mOnLockScreen && view instanceof StatusBarIconView
? ((StatusBarIconView) view).getIconScaleIncreased()
: 1f;
- if (mOpenedAmount != 0.0f) {
- noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow;
- }
- iconState.visibleState = StatusBarIconView.STATE_ICON;
+ iconState.visibleState = iconState.hidden
+ ? StatusBarIconView.STATE_HIDDEN
+ : StatusBarIconView.STATE_ICON;
boolean isOverflowing =
(translationX > (noOverflowAfter ? layoutEnd - mIconSize
@@ -598,10 +599,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
mSpeedBumpIndex = speedBumpIndex;
}
- public void setOpenedAmount(float expandAmount) {
- mOpenedAmount = expandAmount;
- }
-
public boolean hasOverflow() {
return mNumDots > 0;
}
@@ -706,13 +703,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
public boolean justAdded = true;
private boolean justReplaced;
public boolean needsCannedAnimation;
- public boolean useFullTransitionAmount;
- public boolean useLinearTransitionAmount;
- public boolean translateContent;
public int iconColor = StatusBarIconView.NO_COLOR;
public boolean noAnimations;
- public boolean isLastExpandIcon;
- public int customTransformHeight = NO_VALUE;
private final View mView;
private final Consumer<Property> mCannedAnimationEndListener;
@@ -734,8 +726,15 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
StatusBarIconView icon = (StatusBarIconView) view;
boolean animate = false;
AnimationProperties animationProperties = null;
- boolean animationsAllowed = areAnimationsEnabled(icon) && !mDisallowNextAnimation
- && !noAnimations;
+ final boolean isLowPriorityIconChange =
+ (visibleState == StatusBarIconView.STATE_HIDDEN
+ && icon.getVisibleState() == StatusBarIconView.STATE_DOT)
+ || (visibleState == StatusBarIconView.STATE_DOT
+ && icon.getVisibleState() == StatusBarIconView.STATE_HIDDEN);
+ final boolean animationsAllowed = areAnimationsEnabled(icon)
+ && !mDisallowNextAnimation
+ && !noAnimations
+ && !isLowPriorityIconChange;
if (animationsAllowed) {
if (justAdded || justReplaced) {
super.applyToView(icon);
@@ -822,10 +821,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
needsCannedAnimation = false;
}
- public boolean hasCustomTransformHeight() {
- return isLastExpandIcon && customTransformHeight != NO_VALUE;
- }
-
@Override
public void initFrom(View view) {
super.initFrom(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 19b98953325f..626162dc03ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -439,7 +439,6 @@ public class NotificationPanelViewController extends PanelViewController {
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
private boolean mUserSetupComplete;
private int mQsNotificationTopPadding;
- private float mExpandOffset;
private boolean mHideIconsDuringNotificationLaunch = true;
private int mStackScrollerMeasuringPass;
private ArrayList<Consumer<ExpandableNotificationRow>>
@@ -2444,8 +2443,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
startHeight = -mQs.getQsMinExpansionHeight();
}
- float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount))
- + mExpandOffset;
+ float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount));
return Math.min(0, translation);
}
@@ -3185,16 +3183,16 @@ public class NotificationPanelViewController extends PanelViewController {
}
public void applyExpandAnimationParams(ExpandAnimationParameters params) {
- mExpandOffset = params != null ? params.getTopChange() : 0;
- updateQsExpansion();
- if (params != null) {
- boolean hideIcons = params.getProgress(
- ActivityLaunchAnimator.ANIMATION_DELAY_ICON_FADE_IN, 100) == 0.0f;
- if (hideIcons != mHideIconsDuringNotificationLaunch) {
- mHideIconsDuringNotificationLaunch = hideIcons;
- if (!hideIcons) {
- mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
- }
+ if (params == null) {
+ return;
+ }
+
+ boolean hideIcons = params.getProgress(
+ ActivityLaunchAnimator.ANIMATION_DELAY_ICON_FADE_IN, 100) == 0.0f;
+ if (hideIcons != mHideIconsDuringNotificationLaunch) {
+ mHideIconsDuringNotificationLaunch = hideIcons;
+ if (!hideIcons) {
+ mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index 0c9ed661925c..1cb0be0efc90 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -89,30 +89,22 @@ public class NotificationsQuickSettingsContainer extends ConstraintLayout
@Override
protected void dispatchDraw(Canvas canvas) {
- // Invert the order of the scroll view and user switcher such that the notifications receive
- // touches first but the panel gets drawn above.
mDrawingOrderedChildren.clear();
mLayoutDrawingOrder.clear();
if (mKeyguardStatusBar.getVisibility() == View.VISIBLE) {
mDrawingOrderedChildren.add(mKeyguardStatusBar);
mLayoutDrawingOrder.add(mKeyguardStatusBar);
}
- if (mStackScroller.getVisibility() == View.VISIBLE) {
- mDrawingOrderedChildren.add(mStackScroller);
- mLayoutDrawingOrder.add(mStackScroller);
- }
if (mQsFrame.getVisibility() == View.VISIBLE) {
mDrawingOrderedChildren.add(mQsFrame);
mLayoutDrawingOrder.add(mQsFrame);
}
-
- if (mHasViewsAboveShelf) {
- // StackScroller needs to be on top
- mDrawingOrderedChildren.remove(mStackScroller);
+ if (mStackScroller.getVisibility() == View.VISIBLE) {
mDrawingOrderedChildren.add(mStackScroller);
+ mLayoutDrawingOrder.add(mStackScroller);
}
- // Let's now find the order that the view has when drawing regulary by sorting
+ // Let's now find the order that the view has when drawing regularly by sorting
mLayoutDrawingOrder.sort(mIndexComparator);
super.dispatchDraw(canvas);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 48c97a2fd79c..9b8b7160c95c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -140,11 +140,13 @@ public enum ScrimState {
@Override
public void prepare(ScrimState previousState) {
final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
+ final boolean quickPickupEnabled = mDozeParameters.isQuickPickupEnabled();
final boolean isDocked = mDockManager.isDocked();
mBlankScreen = mDisplayRequiresBlanking;
mFrontTint = Color.BLACK;
- mFrontAlpha = (alwaysOnEnabled || isDocked) ? mAodFrontScrimAlpha : 1f;
+ mFrontAlpha = (alwaysOnEnabled || isDocked || quickPickupEnabled)
+ ? mAodFrontScrimAlpha : 1f;
mBehindTint = Color.BLACK;
mBehindAlpha = ScrimController.TRANSPARENT;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 0807f8aa5607..117921dd860c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -95,6 +95,7 @@ import android.provider.Settings;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
@@ -4071,7 +4072,9 @@ public class StatusBar extends SystemUI implements DemoMode,
private @Nullable Intent getEmergencyActionIntent() {
Intent emergencyIntent = new Intent(EmergencyGesture.ACTION_LAUNCH_EMERGENCY);
PackageManager pm = mContext.getPackageManager();
- ResolveInfo resolveInfo = pm.resolveActivity(emergencyIntent, /*flags=*/0);
+ List<ResolveInfo> emergencyActivities = pm.queryIntentActivities(emergencyIntent,
+ PackageManager.MATCH_SYSTEM_ONLY);
+ ResolveInfo resolveInfo = getTopEmergencySosInfo(emergencyActivities);
if (resolveInfo == null) {
Log.wtf(TAG, "Couldn't find an app to process the emergency intent.");
return null;
@@ -4082,6 +4085,34 @@ public class StatusBar extends SystemUI implements DemoMode,
return emergencyIntent;
}
+ /**
+ * Select and return the "best" ResolveInfo for Emergency SOS Activity.
+ */
+ private @Nullable ResolveInfo getTopEmergencySosInfo(List<ResolveInfo> emergencyActivities) {
+ // No matched activity.
+ if (emergencyActivities == null || emergencyActivities.isEmpty()) {
+ return null;
+ }
+
+ // Of multiple matched Activities, give preference to the pre-set package name.
+ String preferredAppPackageName =
+ mContext.getString(R.string.config_preferredEmergencySosPackage);
+
+ // If there is no preferred app, then return first match.
+ if (TextUtils.isEmpty(preferredAppPackageName)) {
+ return emergencyActivities.get(0);
+ }
+
+ for (ResolveInfo emergencyInfo: emergencyActivities) {
+ // If activity is from the preferred app, use it.
+ if (TextUtils.equals(emergencyInfo.activityInfo.packageName, preferredAppPackageName)) {
+ return emergencyInfo;
+ }
+ }
+ // No matching activity: return first match
+ return emergencyActivities.get(0);
+ }
+
boolean isCameraAllowedByAdmin() {
if (mDevicePolicyManager.getCameraDisabled(null,
mLockscreenUserManager.getCurrentUserId())) {
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 b4c687d36e6c..5083e330f9a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -739,8 +739,13 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
public void onThemeChanged() {
+ boolean wasShowing = mBouncer.isShowing();
+ boolean wasScrimmed = mBouncer.isScrimmed();
+
hideBouncer(true /* destroyView */);
mBouncer.prepare();
+
+ if (wasShowing) showBouncer(wasScrimmed);
}
public void onKeyguardFadedAway() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 34673f2503ce..801ac964777b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -356,9 +356,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
if (isActivityIntent || canBubble) {
mAssistManagerLazy.get().hideAssist();
}
- if (shouldCollapse()) {
- collapseOnMainThread();
- }
NotificationVisibility.NotificationLocation location =
NotificationLogger.getNotificationLocation(entry);
@@ -408,6 +405,12 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mMainThreadHandler.post(
() -> mBubblesManagerOptional.get().expandStackAndSelectBubble(entry));
}
+
+ // expandStackAndSelectBubble won't affect shouldCollapse, so we can collapse directly even
+ // if we are not on the main thread.
+ if (shouldCollapse()) {
+ collapseOnMainThread();
+ }
}
private void startNotificationIntent(
@@ -438,6 +441,9 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
null, null, options);
mMainThreadHandler.post(() -> {
mActivityLaunchAnimator.setLaunchResult(launchResult, isActivityIntent);
+ if (shouldCollapse()) {
+ collapseOnMainThread();
+ }
});
} catch (RemoteException | PendingIntent.CanceledException e) {
// the stack trace isn't very helpful here.
@@ -465,11 +471,11 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mActivityLaunchAnimator.setLaunchResult(launchResult,
true /* isActivityIntent */);
removeHUN(row);
+ if (shouldCollapse()) {
+ mCommandQueue.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+ true /* force */);
+ }
});
- if (shouldCollapse()) {
- mMainThreadHandler.post(() -> mCommandQueue.animateCollapsePanels(
- CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */));
- }
});
return true;
}, null, false /* afterKeyguardGone */);
diff --git a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
index fab1655b1262..fd19528e6d55 100644
--- a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
+++ b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
@@ -19,14 +19,13 @@ package com.android.systemui.toast;
import android.animation.Animator;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.Application;
import android.content.Context;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
@@ -35,6 +34,8 @@ import android.widget.ToastPresenter;
import com.android.internal.R;
import com.android.launcher3.icons.IconFactory;
+import com.android.settingslib.applications.ApplicationsState;
+import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.systemui.plugins.ToastPlugin;
/**
@@ -170,8 +171,13 @@ public class SystemUIToast implements ToastPlugin.Toast {
com.android.systemui.R.layout.text_toast, null);
((TextView) toastView.findViewById(com.android.systemui.R.id.text)).setText(mText);
- ((ImageView) toastView.findViewById(com.android.systemui.R.id.icon))
- .setImageDrawable(getBadgedIcon(mContext, mPackageName, mUserId));
+ Drawable icon = getBadgedIcon(mContext, mPackageName, mUserId);
+ if (icon == null) {
+ toastView.findViewById(com.android.systemui.R.id.icon).setVisibility(View.GONE);
+ } else {
+ ((ImageView) toastView.findViewById(com.android.systemui.R.id.icon))
+ .setImageDrawable(icon);
+ }
} else {
toastView = ToastPresenter.getTextToastView(mContext, mText);
}
@@ -217,18 +223,20 @@ public class SystemUIToast implements ToastPlugin.Toast {
*/
public static Drawable getBadgedIcon(@NonNull Context context, String packageName,
int userId) {
- final PackageManager packageManager = context.getPackageManager();
- try {
- final ApplicationInfo appInfo = packageManager.getApplicationInfoAsUser(
- packageName, PackageManager.GET_META_DATA, userId);
- UserHandle user = UserHandle.getUserHandleForUid(appInfo.uid);
- IconFactory iconFactory = IconFactory.obtain(context);
- Bitmap iconBmp = iconFactory.createBadgedIconBitmap(
- appInfo.loadUnbadgedIcon(packageManager), user, false).icon;
- return new BitmapDrawable(context.getResources(), iconBmp);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e("SystemUIToast", "could not load icon for package=" + packageName + " e=" + e);
+ final ApplicationsState appState =
+ ApplicationsState.getInstance((Application) context.getApplicationContext());
+ final AppEntry appEntry = appState.getEntry(packageName, userId);
+
+ if (!ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(appEntry)) {
return null;
}
+
+ final ApplicationInfo appInfo = appEntry.info;
+ UserHandle user = UserHandle.getUserHandleForUid(appInfo.uid);
+ IconFactory iconFactory = IconFactory.obtain(context);
+ Bitmap iconBmp = iconFactory.createBadgedIconBitmap(
+ appInfo.loadUnbadgedIcon(context.getPackageManager()), user, true).icon;
+ return new BitmapDrawable(context.getResources(), iconBmp);
+
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index eb95d1653e84..b9d8d27b8971 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -793,36 +793,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
@Test
- public void testStartUdfpsServiceOnShadeLocked() {
- // GIVEN
- // - bouncer isn't showing
- // - user has authenticated since boot
- setKeyguardBouncerVisibility(false /* isVisible */);
- when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
-
- // WHEN the status bar state changes to SHADE_LOCKED
- mStatusBarStateListener.onStateChanged(StatusBarState.SHADE_LOCKED);
-
- // THEN we shouldn't listen for udfps
- assertThat(mKeyguardUpdateMonitor.shouldListenForUdfps()).isEqualTo(false);
- }
-
- @Test
- public void testStartUdfpsServiceOnFullscreenUserSwitcher() {
- // GIVEN
- // - bouncer isn't showing
- // - user has authenticated since boot
- setKeyguardBouncerVisibility(false /* isVisible */);
- when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
-
- // WHEN the status bar state changes to FULLSCREEN_USER_SWITCHER
- mStatusBarStateListener.onStateChanged(StatusBarState.FULLSCREEN_USER_SWITCHER);
-
- // THEN we shouldn't listen for udfps
- assertThat(mKeyguardUpdateMonitor.shouldListenForUdfps()).isEqualTo(false);
- }
-
- @Test
public void testStartUdfpsServiceNoAuthenticationSinceLastBoot() {
// GIVEN
// - bouncer isn't showing
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
index 49282ee360e2..7f8be9125316 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
@@ -22,10 +22,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.content.Context;
import android.hardware.biometrics.PromptInfo;
@@ -333,16 +331,50 @@ public class AuthBiometricViewTest extends SysuiTestCase {
}
@Test
- public void testUdfpsBottomSpacerCalculation() {
+ public void testUdfpsBottomSpacerHeightForPortrait() {
final int displayHeightPx = 3000;
final int navbarHeightPx = 10;
final int dialogBottomMarginPx = 20;
+ final int buttonBarHeightPx = 100;
+ final int textIndicatorHeightPx = 200;
- final View buttonBar = mock(View.class);
- when(buttonBar.getMeasuredHeight()).thenReturn(100);
+ final int sensorLocationX = 540;
+ final int sensorLocationY = 1600;
+ final int sensorRadius = 100;
+ final FingerprintSensorPropertiesInternal props = new FingerprintSensorPropertiesInternal(
+ 0 /* sensorId */, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
+ FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
+ true /* resetLockoutRequiresHardwareAuthToken */, sensorLocationX, sensorLocationY,
+ sensorRadius);
+
+ assertEquals(970,
+ AuthBiometricUdfpsView.calculateBottomSpacerHeightForPortrait(
+ props, displayHeightPx, textIndicatorHeightPx, buttonBarHeightPx,
+ dialogBottomMarginPx, navbarHeightPx
+ ));
+ }
- final View textIndicator = mock(View.class);
- when(textIndicator.getMeasuredHeight()).thenReturn(200);
+ @Test
+ public void testUdfpsBottomSpacerHeightForLandscape() {
+ final int titleHeightPx = 320;
+ final int subtitleHeightPx = 240;
+ final int descriptionHeightPx = 200;
+ final int topSpacerHeightPx = 550;
+ final int textIndicatorHeightPx = 190;
+ final int buttonBarHeightPx = 160;
+ final int navbarBottomInsetPx = 75;
+
+ assertEquals(885,
+ AuthBiometricUdfpsView.calculateBottomSpacerHeightForLandscape(
+ titleHeightPx, subtitleHeightPx, descriptionHeightPx, topSpacerHeightPx,
+ textIndicatorHeightPx, buttonBarHeightPx, navbarBottomInsetPx));
+ }
+
+ @Test
+ public void testUdfpsHorizontalSpacerWidthForLandscape() {
+ final int displayWidthPx = 3000;
+ final int dialogMarginPx = 20;
+ final int navbarHorizontalInsetPx = 75;
final int sensorLocationX = 540;
final int sensorLocationY = 1600;
@@ -353,9 +385,9 @@ public class AuthBiometricViewTest extends SysuiTestCase {
true /* resetLockoutRequiresHardwareAuthToken */, sensorLocationX, sensorLocationY,
sensorRadius);
- assertEquals(970, AuthBiometricUdfpsView.calculateBottomSpacerHeight(
- displayHeightPx, navbarHeightPx, dialogBottomMarginPx, buttonBar, textIndicator,
- props));
+ assertEquals(1205,
+ AuthBiometricUdfpsView.calculateHorizontalSpacerWidthForLandscape(
+ props, displayWidthPx, dialogMarginPx, navbarHorizontalInsetPx));
}
private PromptInfo buildPromptInfo(boolean allowDeviceCredential) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
index 472ed7a22fe3..ca0a4aa2b04d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java
@@ -21,7 +21,6 @@ import static com.android.systemui.classifier.Classifier.UNLOCK;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
-import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.utils.leaks.FakeBatteryController;
import com.android.systemui.utils.leaks.LeakCheckedTest;
@@ -45,8 +44,7 @@ public class ClassifierTest extends LeakCheckedTest {
displayMetrics.widthPixels = 1000;
displayMetrics.heightPixels = 1000;
mFakeBatteryController = new FakeBatteryController(getLeakCheck());
- mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController,
- new FakeSystemClock());
+ mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController);
mDataProvider.setInteractionType(UNLOCK);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java
index 17c2700c5bda..4e1742497d90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java
@@ -19,7 +19,6 @@ package com.android.systemui.classifier;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.anyList;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
@@ -35,8 +34,6 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
-import java.util.Deque;
-import java.util.LinkedList;
import java.util.List;
@SmallTest
@@ -47,7 +44,7 @@ public class DoubleTapClassifierTest extends ClassifierTest {
private static final long DOUBLE_TAP_TIMEOUT_MS = 100;
private List<MotionEvent> mMotionEvents = new ArrayList<>();
- private final Deque<List<MotionEvent>> mHistoricalMotionEvents = new LinkedList<>();
+ private List<MotionEvent> mPriorMotionEvents = new ArrayList<>();
@Mock
private FalsingDataProvider mDataProvider;
@@ -64,7 +61,7 @@ public class DoubleTapClassifierTest extends ClassifierTest {
MockitoAnnotations.initMocks(this);
mClassifier = new DoubleTapClassifier(mDataProvider, mSingleTapClassifier, TOUCH_SLOP,
DOUBLE_TAP_TIMEOUT_MS);
- doReturn(mHistoricalMotionEvents).when(mDataProvider).getHistoricalMotionEvents();
+ when(mDataProvider.getPriorMotionEvents()).thenReturn(mPriorMotionEvents);
}
@After
@@ -177,9 +174,8 @@ public class DoubleTapClassifierTest extends ClassifierTest {
}
private void archiveMotionEvents() {
- mHistoricalMotionEvents.addFirst(mMotionEvents);
- doReturn(mHistoricalMotionEvents).when(mDataProvider).getHistoricalMotionEvents();
+ mPriorMotionEvents = mMotionEvents;
+ when(mDataProvider.getPriorMotionEvents()).thenReturn(mPriorMotionEvents);
mMotionEvents = new ArrayList<>();
-
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index be0cc97a2f0f..ebdda67a90d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -26,7 +26,6 @@ import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
-import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.utils.leaks.FakeBatteryController;
import org.junit.After;
@@ -52,8 +51,7 @@ public class FalsingDataProviderTest extends ClassifierTest {
displayMetrics.ydpi = 100;
displayMetrics.widthPixels = 1000;
displayMetrics.heightPixels = 1000;
- mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController,
- new FakeSystemClock());
+ mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController);
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java
index 6e312594a2e4..901196f8bbba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java
@@ -89,20 +89,4 @@ public class TimeLimitedMotionEventBufferTest extends SysuiTestCase {
assertThat(mBuffer.get(0), is(eventC));
assertThat(mBuffer.get(1), is(eventD));
}
-
- @Test
- public void testFullyExpired() {
- MotionEvent eventA = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
- MotionEvent eventB = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 0, 0, 0);
- MotionEvent eventC = MotionEvent.obtain(0, 2, MotionEvent.ACTION_MOVE, 0, 0, 0);
- MotionEvent eventD = MotionEvent.obtain(0, 3, MotionEvent.ACTION_UP, 0, 0, 0);
-
- mBuffer.add(eventA);
- mBuffer.add(eventB);
- mBuffer.add(eventC);
- mBuffer.add(eventD);
-
- assertThat(mBuffer.isFullyExpired(2), is(false));
- assertThat(mBuffer.isFullyExpired(6), is(true));
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
index 9fd9b470a83b..1aeb0d8a5361 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
@@ -60,6 +60,7 @@ public class DozeConfigurationUtil {
when(config.tapSensorType()).thenReturn(null);
when(config.longPressSensorType()).thenReturn(null);
when(config.udfpsLongPressSensorType()).thenReturn(null);
+ when(config.quickPickupSensorType()).thenReturn(null);
when(config.tapGestureEnabled(anyInt())).thenReturn(true);
when(config.tapSensorAvailable()).thenReturn(true);
@@ -67,6 +68,7 @@ public class DozeConfigurationUtil {
when(config.dozePickupSensorAvailable()).thenReturn(false);
when(config.wakeScreenGestureAvailable()).thenReturn(false);
+ when(config.quickPickupSensorEnabled(anyInt())).thenReturn(false);
doneHolder[0] = true;
return config;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 27187a85c040..1817fdfd4cdc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -104,7 +104,7 @@ public class DozeTriggersTest extends SysuiTestCase {
mTriggers = new DozeTriggers(mContext, mHost, mAlarmManager, config, parameters,
asyncSensorManager, wakeLock, mDockManager, mProximitySensor,
mProximityCheck, mock(DozeLog.class), mBroadcastDispatcher, new FakeSettings(),
- mAuthController);
+ mAuthController, mExecutor, mExecutor);
mTriggers.setDozeMachine(mMachine);
waitForSensorManager();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
index 1062fae52e7a..eedf09936b4d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
@@ -46,16 +46,12 @@ import android.service.dreams.IDreamManager;
import android.telephony.TelephonyManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
-import android.util.FeatureFlagUtils;
import android.view.IWindowManager;
import android.view.View;
import android.view.WindowManagerPolicyConstants;
import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.logging.MetricsLogger;
@@ -251,22 +247,6 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
}
@Test
- public void testShouldLogScreenshotLongPress() {
- FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SCREENRECORD_LONG_PRESS, true);
- GlobalActionsDialog.ScreenshotAction screenshotAction =
- mGlobalActionsDialog.makeScreenshotActionForTesting();
- screenshotAction.onLongPress();
- verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS);
-
- // Dismiss ScreenRecordDialog opened by the long press above.
- final UiObject2 cancelButton = getUiDevice().wait(
- Until.findObject(By.text(CANCEL_BUTTON)), UI_TIMEOUT_MILLIS);
- if (cancelButton != null) {
- cancelButton.click();
- }
- }
-
- @Test
public void testShouldShowScreenshot() {
mContext.getOrCreateTestableResources().addOverride(
com.android.internal.R.integer.config_navBarInteractionMode,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
index 2a4b41cbfe32..3fed07472c35 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
@@ -22,8 +22,9 @@ import static android.app.people.ConversationStatus.ACTIVITY_GAME;
import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY;
import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE;
-import static com.android.systemui.people.PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE;
import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
+import static com.android.systemui.people.PeopleSpaceUtils.getPeopleTileFromPersistentStorage;
+import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_PEOPLE_TILE;
import static com.google.common.truth.Truth.assertThat;
@@ -76,6 +77,7 @@ import android.widget.TextView;
import com.android.internal.appwidget.IAppWidgetService;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.people.widget.PeopleTileKey;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.SbnBuilder;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -232,7 +234,7 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
Bundle options = new Bundle();
- options.putParcelable(OPTIONS_PEOPLE_SPACE_TILE, PERSON_TILE);
+ options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT)))
@@ -500,7 +502,7 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
.build();
PeopleSpaceTile actual = PeopleSpaceUtils
.augmentTileFromVisibleNotifications(mContext, tile,
- Map.of(PeopleSpaceUtils.getKey(mNotificationEntry1), mNotificationEntry1));
+ Map.of(new PeopleTileKey(mNotificationEntry1), mNotificationEntry1));
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_2);
}
@@ -515,7 +517,7 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
.build();
PeopleSpaceTile actual = PeopleSpaceUtils
.augmentTileFromVisibleNotifications(mContext, tile,
- Map.of(PeopleSpaceUtils.getKey(mNotificationEntry1), mNotificationEntry1));
+ Map.of(new PeopleTileKey(mNotificationEntry1), mNotificationEntry1));
assertThat(actual.getNotificationContent()).isEqualTo(null);
}
@@ -818,6 +820,23 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
assertEquals(statusContent.getText(), NOTIFICATION_CONTENT);
}
+ @Test
+ public void testGetPeopleTileFromPersistentStorageExistingConversation()
+ throws Exception {
+ when(mPeopleManager.getConversation(PACKAGE_NAME, 0, SHORTCUT_ID_1)).thenReturn(
+ getConversationChannelWithoutTimestamp(SHORTCUT_ID_1));
+ PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID_1, 0, PACKAGE_NAME);
+ PeopleSpaceTile tile = getPeopleTileFromPersistentStorage(mContext, key, mPeopleManager);
+ assertThat(tile.getId()).isEqualTo(key.getShortcutId());
+ }
+
+ @Test
+ public void testGetPeopleTileFromPersistentStorageNoConversation() {
+ PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID_2, 0, PACKAGE_NAME);
+ PeopleSpaceTile tile = getPeopleTileFromPersistentStorage(mContext, key, mPeopleManager);
+ assertThat(tile).isNull();
+ }
+
private ConversationChannelWrapper getConversationChannelWrapper(String shortcutId,
boolean importantConversation, long lastInteractionTimestamp) throws Exception {
ConversationChannelWrapper convo = new ConversationChannelWrapper();
@@ -843,4 +862,13 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
eq(shortcutId))).thenReturn(lastInteractionTimestamp);
return convo;
}
+
+ private ConversationChannel getConversationChannelWithoutTimestamp(String shortcutId)
+ throws Exception {
+ ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
+ "name").build();
+ ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
+ 0L, false);
+ return convo;
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index f60fa099feaa..aef75beb3d56 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -23,10 +23,11 @@ import static android.app.people.ConversationStatus.ACTIVITY_ANNIVERSARY;
import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
import static android.app.people.ConversationStatus.ACTIVITY_GAME;
+import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
-import static com.android.systemui.people.PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE;
import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
import static com.android.systemui.people.PeopleSpaceUtils.USER_ID;
+import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_PEOPLE_TILE;
import static com.google.common.truth.Truth.assertThat;
@@ -104,13 +105,14 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
private static final int WIDGET_ID_WITH_SHORTCUT = 1;
private static final int SECOND_WIDGET_ID_WITH_SHORTCUT = 3;
private static final int WIDGET_ID_WITHOUT_SHORTCUT = 2;
+ private static final int WIDGET_ID_WITH_KEY_IN_OPTIONS = 4;
private static final String SHORTCUT_ID = "101";
private static final String OTHER_SHORTCUT_ID = "102";
private static final String NOTIFICATION_KEY = "0|com.android.systemui.tests|0|null|0";
private static final String NOTIFICATION_CONTENT = "message text";
private static final Uri URI = Uri.parse("fake_uri");
private static final Icon ICON = Icon.createWithResource("package", R.drawable.ic_android);
- private static final String KEY = PeopleSpaceUtils.getKey(SHORTCUT_ID, TEST_PACKAGE_A, 0);
+ private static final PeopleTileKey KEY = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
private static final Person PERSON = new Person.Builder()
.setName("name")
.setKey("abc")
@@ -172,10 +174,11 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
+ clearStorage();
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
Bundle options = new Bundle();
- options.putParcelable(PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE, PERSON_TILE);
+ options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT)))
.thenReturn(options);
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
@@ -395,7 +398,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
mBundleArgumentCaptor.capture());
Bundle bundle = mBundleArgumentCaptor.getValue();
- PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
assertThat(tile.getStatuses()).containsExactly(status);
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
any());
@@ -439,7 +442,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
mBundleArgumentCaptor.capture());
Bundle bundle = mBundleArgumentCaptor.getValue();
- PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
assertThat(tile.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
assertThat(tile.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
@@ -473,7 +476,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
throws Exception {
addSecondWidgetForPersonTile();
- PeopleSpaceUtils.removeStorageForTile(mContext, KEY, SECOND_WIDGET_ID_WITH_SHORTCUT);
+ PeopleSpaceUtils.removeSharedPreferencesStorageForTile(
+ mContext, KEY, SECOND_WIDGET_ID_WITH_SHORTCUT);
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
.setSbn(createNotification(
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false))
@@ -510,7 +514,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
mBundleArgumentCaptor.capture());
Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
- PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
assertThat(tile.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
assertThat(tile.getNotificationContent())
.isEqualTo(mContext.getString(R.string.missed_call));
@@ -536,7 +540,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
mBundleArgumentCaptor.capture());
Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
- PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
assertThat(tile.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
assertThat(tile.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
@@ -547,6 +551,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
public void testUpdateNotificationRemovedIfExistingTile() throws Exception {
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+ setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
StatusBarNotification sbn = createNotification(
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false);
@@ -560,11 +565,11 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
verify(mAppWidgetManager, times(2)).updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
mBundleArgumentCaptor.capture());
Bundle bundle = mBundleArgumentCaptor.getValue();
- PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
assertThat(tile.getNotificationKey()).isEqualTo(null);
assertThat(tile.getNotificationContent()).isEqualTo(null);
assertThat(tile.getNotificationDataUri()).isEqualTo(null);
- verify(mAppWidgetManager, times(2)).updateAppWidget(anyInt(),
+ verify(mAppWidgetManager, times(2)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
any());
}
@@ -585,7 +590,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
assertThat(widgetSp.getString(SHORTCUT_ID, null)).isNull();
assertThat(widgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(INVALID_USER_ID);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
- assertThat(sp.getStringSet(KEY, new HashSet<>())).containsExactly(
+ assertThat(sp.getStringSet(KEY.toString(), new HashSet<>())).containsExactly(
String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT));
// Check listener & shortcut caching remain for other widget.
verify(mPeopleManager, never()).unregisterConversationListener(any());
@@ -603,7 +608,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
assertThat(secondWidgetSp.getString(PACKAGE_NAME, null)).isNull();
assertThat(secondWidgetSp.getString(SHORTCUT_ID, null)).isNull();
assertThat(secondWidgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(INVALID_USER_ID);
- assertThat(sp.getStringSet(KEY, new HashSet<>())).isEmpty();
+ assertThat(sp.getStringSet(KEY.toString(), new HashSet<>())).isEmpty();
// Check listener is removed and shortcut is uncached.
verify(mPeopleManager, times(1)).unregisterConversationListener(any());
verify(mLauncherApps, times(1)).uncacheShortcuts(eq(TEST_PACKAGE_A),
@@ -611,13 +616,96 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
}
+ @Test
+ public void testUpdateWidgetsWithEmptyOptionsAddsPeopleTileToOptions() throws Exception {
+ int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT};
+ when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+ when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT)))
+ .thenReturn(new Bundle());
+
+ mManager.updateWidgets(widgetIdsArray);
+ mClock.advanceTime(MIN_LINGER_DURATION);
+
+ // If we had to fetch Tile from persistent storage, we want to make sure we write it to
+ // options.
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = mBundleArgumentCaptor.getValue();
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.getId()).isEqualTo(SHORTCUT_ID);
+ verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ any());
+ }
+
+ @Test
+ public void testOnAppWidgetOptionsChangedNoWidgetAdded() {
+ Bundle newOptions = new Bundle();
+ newOptions.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
+ mManager.onAppWidgetOptionsChanged(SECOND_WIDGET_ID_WITH_SHORTCUT, newOptions);
+
+
+ // Check that options is not modified
+ verify(mAppWidgetManager, never()).updateAppWidgetOptions(
+ eq(SECOND_WIDGET_ID_WITH_SHORTCUT), any());
+ // Check listener is not added and shortcut is not cached.
+ verify(mPeopleManager, never()).registerConversationListener(any(), anyInt(), any(), any(),
+ any());
+ verify(mLauncherApps, never()).cacheShortcuts(any(), any(), any(), anyInt());
+ // Check no added storage.
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ assertThat(sp.getStringSet(KEY.toString(), new HashSet<>()))
+ .doesNotContain(SECOND_WIDGET_ID_WITH_SHORTCUT);
+ SharedPreferences widgetSp = mContext.getSharedPreferences(
+ String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT),
+ Context.MODE_PRIVATE);
+ assertThat(widgetSp.getString(PACKAGE_NAME, EMPTY_STRING)).isEqualTo(EMPTY_STRING);
+ assertThat(widgetSp.getString(SHORTCUT_ID, EMPTY_STRING)).isEqualTo(EMPTY_STRING);
+ assertThat(widgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(INVALID_USER_ID);
+
+ }
+
+ @Test
+ public void testOnAppWidgetOptionsChangedWidgetAdded() {
+ Bundle newOptions = new Bundle();
+ newOptions.putString(PeopleSpaceUtils.SHORTCUT_ID, SHORTCUT_ID);
+ newOptions.putInt(USER_ID, 0);
+ newOptions.putString(PACKAGE_NAME, TEST_PACKAGE_A);
+ when(mAppWidgetManager.getAppWidgetOptions(eq(SECOND_WIDGET_ID_WITH_SHORTCUT)))
+ .thenReturn(newOptions);
+
+ mManager.onAppWidgetOptionsChanged(SECOND_WIDGET_ID_WITH_SHORTCUT, newOptions);
+
+ verify(mAppWidgetManager, times(1)).updateAppWidgetOptions(
+ eq(SECOND_WIDGET_ID_WITH_SHORTCUT), mBundleArgumentCaptor.capture());
+ Bundle bundle = mBundleArgumentCaptor.getValue();
+ assertThat(bundle.getString(PeopleSpaceUtils.SHORTCUT_ID, EMPTY_STRING))
+ .isEqualTo(EMPTY_STRING);
+ assertThat(bundle.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(INVALID_USER_ID);
+ assertThat(bundle.getString(PACKAGE_NAME, EMPTY_STRING)).isEqualTo(EMPTY_STRING);
+ verify(mLauncherApps, times(1)).cacheShortcuts(eq(TEST_PACKAGE_A),
+ eq(Arrays.asList(SHORTCUT_ID)), eq(UserHandle.of(0)),
+ eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
+
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ assertThat(sp.getStringSet(KEY.toString(), new HashSet<>())).contains(
+ String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT));
+ SharedPreferences widgetSp = mContext.getSharedPreferences(
+ String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT),
+ Context.MODE_PRIVATE);
+ assertThat(widgetSp.getString(PACKAGE_NAME, EMPTY_STRING)).isEqualTo(TEST_PACKAGE_A);
+ assertThat(widgetSp.getString(PeopleSpaceUtils.SHORTCUT_ID, EMPTY_STRING))
+ .isEqualTo(SHORTCUT_ID);
+ assertThat(widgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(0);
+ }
+
/**
* Adds another widget for {@code PERSON_TILE} with widget ID: {@code
* SECOND_WIDGET_ID_WITH_SHORTCUT}.
*/
private void addSecondWidgetForPersonTile() {
Bundle options = new Bundle();
- options.putParcelable(PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE, PERSON_TILE);
+ options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
when(mAppWidgetManager.getAppWidgetOptions(eq(SECOND_WIDGET_ID_WITH_SHORTCUT)))
.thenReturn(options);
// Set the same Person associated on another People Tile widget ID.
@@ -676,6 +764,27 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
.build();
}
+ private void clearStorage() {
+ SharedPreferences widgetSp1 = mContext.getSharedPreferences(
+ String.valueOf(WIDGET_ID_WITH_SHORTCUT),
+ Context.MODE_PRIVATE);
+ widgetSp1.edit().clear().commit();
+ SharedPreferences widgetSp2 = mContext.getSharedPreferences(
+ String.valueOf(WIDGET_ID_WITHOUT_SHORTCUT),
+ Context.MODE_PRIVATE);
+ widgetSp2.edit().clear().commit();
+ SharedPreferences widgetSp3 = mContext.getSharedPreferences(
+ String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT),
+ Context.MODE_PRIVATE);
+ widgetSp3.edit().clear().commit();
+ SharedPreferences widgetSp4 = mContext.getSharedPreferences(
+ String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS),
+ Context.MODE_PRIVATE);
+ widgetSp4.edit().clear().commit();
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ sp.edit().clear().commit();
+ }
+
private void setStorageForTile(String shortcutId, String packageName, int widgetId) {
SharedPreferences widgetSp = mContext.getSharedPreferences(
String.valueOf(widgetId),
@@ -689,7 +798,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = sp.edit();
editor.putString(String.valueOf(widgetId), shortcutId);
- String key = PeopleSpaceUtils.getKey(shortcutId, packageName, 0);
+ String key = new PeopleTileKey(shortcutId, 0, packageName).toString();
Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
storedWidgetIds.add(String.valueOf(widgetId));
editor.putStringSet(key, storedWidgetIds);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
new file mode 100644
index 000000000000..a9d10e9e6872
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
@@ -0,0 +1,147 @@
+package com.android.systemui.qs.tiles
+
+import android.app.AlarmManager
+import android.app.PendingIntent
+import android.os.Handler
+import android.service.quicksettings.Tile
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.FeatureFlags
+import com.android.systemui.statusbar.policy.NextAlarmController
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class AlarmTileTest : SysuiTestCase() {
+
+ @Mock
+ private lateinit var qsHost: QSHost
+ @Mock
+ private lateinit var metricsLogger: MetricsLogger
+ @Mock
+ private lateinit var statusBarStateController: StatusBarStateController
+ @Mock
+ private lateinit var activityStarter: ActivityStarter
+ @Mock
+ private lateinit var qsLogger: QSLogger
+ @Mock
+ private lateinit var featureFlags: FeatureFlags
+ @Mock
+ private lateinit var userTracker: UserTracker
+ @Mock
+ private lateinit var nextAlarmController: NextAlarmController
+ @Mock
+ private lateinit var uiEventLogger: UiEventLogger
+ @Mock
+ private lateinit var pendingIntent: PendingIntent
+ @Captor
+ private lateinit var callbackCaptor: ArgumentCaptor<NextAlarmController.NextAlarmChangeCallback>
+
+ private lateinit var testableLooper: TestableLooper
+ private lateinit var tile: AlarmTile
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ testableLooper = TestableLooper.get(this)
+
+ `when`(qsHost.context).thenReturn(mContext)
+ `when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
+
+ tile = AlarmTile(
+ qsHost,
+ testableLooper.looper,
+ Handler(testableLooper.looper),
+ metricsLogger,
+ statusBarStateController,
+ activityStarter,
+ qsLogger,
+ featureFlags,
+ userTracker,
+ nextAlarmController
+ )
+
+ verify(nextAlarmController).observe(eq(tile), capture(callbackCaptor))
+ tile.refreshState()
+ testableLooper.processAllMessages()
+ }
+
+ @Test
+ fun testNotAvailableFeatureFlag() {
+ `when`(featureFlags.isAlarmTileAvailable).thenReturn(false)
+ assertThat(tile.isAvailable).isFalse()
+ }
+
+ @Test
+ fun testAvailableFeatureFlag() {
+ `when`(featureFlags.isAlarmTileAvailable).thenReturn(true)
+ assertThat(tile.isAvailable).isTrue()
+ }
+
+ @Test
+ fun testDoesntHandleLongClick() {
+ assertThat(tile.state.handlesLongClick).isFalse()
+ }
+
+ @Test
+ fun testInactiveByDefault() {
+ assertThat(tile.state.state).isEqualTo(Tile.STATE_INACTIVE)
+ }
+
+ @Test
+ fun testInactiveAfterNullNextAlarm() {
+ callbackCaptor.value.onNextAlarmChanged(null)
+
+ testableLooper.processAllMessages()
+ assertThat(tile.state.state).isEqualTo(Tile.STATE_INACTIVE)
+ }
+
+ @Test
+ fun testActivityStartedWhenNullNextAlarm() {
+ callbackCaptor.value.onNextAlarmChanged(null)
+ tile.click()
+
+ testableLooper.processAllMessages()
+ verify(activityStarter).postStartActivityDismissingKeyguard(tile.defaultIntent, 0)
+ }
+
+ @Test
+ fun testActiveAfterNextAlarm() {
+ val alarmInfo = AlarmManager.AlarmClockInfo(1L, pendingIntent)
+ callbackCaptor.value.onNextAlarmChanged(alarmInfo)
+
+ testableLooper.processAllMessages()
+ assertThat(tile.state.state).isEqualTo(Tile.STATE_ACTIVE)
+ }
+
+ @Test
+ fun testActivityStartedWhenNextAlarm() {
+ val alarmInfo = AlarmManager.AlarmClockInfo(1L, pendingIntent)
+ callbackCaptor.value.onNextAlarmChanged(alarmInfo)
+ tile.click()
+
+ testableLooper.processAllMessages()
+ verify(activityStarter).postStartActivityDismissingKeyguard(pendingIntent)
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index ccd9548b269f..9363b24817e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -17,6 +17,8 @@
package com.android.systemui.qs.tiles
import android.os.Handler
+import android.content.Context
+import android.content.Intent
import android.provider.Settings
import android.service.quicksettings.Tile
import android.testing.AndroidTestingRunner
@@ -30,7 +32,6 @@ import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.controls.management.ControlsListingController
-import com.android.systemui.controls.ui.ControlsDialog
import com.android.systemui.controls.ui.ControlsUiController
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -50,7 +51,9 @@ import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.`when`
+import org.mockito.Mockito.doNothing
import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import java.util.Optional
@@ -80,8 +83,6 @@ class DeviceControlsTileTest : SysuiTestCase() {
private lateinit var controlsController: ControlsController
@Mock
private lateinit var featureFlags: FeatureFlags
- @Mock
- private lateinit var controlsDialog: ControlsDialog
private lateinit var globalSettings: GlobalSettings
@Mock
private lateinit var serviceInfo: ControlsServiceInfo
@@ -95,6 +96,7 @@ class DeviceControlsTileTest : SysuiTestCase() {
private lateinit var tile: DeviceControlsTile
private lateinit var secureSettings: SecureSettings
+ private lateinit var spiedContext: Context
private var featureEnabled = true
@Before
@@ -103,7 +105,9 @@ class DeviceControlsTileTest : SysuiTestCase() {
testableLooper = TestableLooper.get(this)
secureSettings = FakeSettings()
- `when`(qsHost.context).thenReturn(mContext)
+ spiedContext = spy(mContext)
+ doNothing().`when`(spiedContext).startActivity(any(Intent::class.java))
+ `when`(qsHost.context).thenReturn(spiedContext)
`when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
`when`(controlsController.available).thenReturn(true)
`when`(controlsComponent.isEnabled()).thenReturn(true)
@@ -276,7 +280,7 @@ class DeviceControlsTileTest : SysuiTestCase() {
tile.click()
testableLooper.processAllMessages()
- verify(controlsDialog, never()).show(any(ControlsUiController::class.java))
+ verify(spiedContext, never()).startActivity(any(Intent::class.java))
}
@Test
@@ -293,7 +297,7 @@ class DeviceControlsTileTest : SysuiTestCase() {
tile.click()
testableLooper.processAllMessages()
- verify(controlsDialog).show(controlsUiController)
+ verify(spiedContext).startActivity(any(Intent::class.java))
}
@Test
@@ -311,25 +315,7 @@ class DeviceControlsTileTest : SysuiTestCase() {
tile.click()
testableLooper.processAllMessages()
- verify(controlsDialog, never()).show(any(ControlsUiController::class.java))
- }
-
- @Test
- fun testDialogDismissedOnDestroy() {
- verify(controlsListingController).observe(
- any(LifecycleOwner::class.java),
- capture(listingCallbackCaptor)
- )
-
- listingCallbackCaptor.value.onServicesUpdated(listOf(serviceInfo))
- testableLooper.processAllMessages()
-
- tile.click()
- testableLooper.processAllMessages()
-
- tile.destroy()
- testableLooper.processAllMessages()
- verify(controlsDialog).dismiss()
+ verify(spiedContext, never()).startActivity(any(Intent::class.java))
}
private fun createTile(): DeviceControlsTile {
@@ -343,7 +329,6 @@ class DeviceControlsTileTest : SysuiTestCase() {
qsLogger,
controlsComponent,
featureFlags,
- { controlsDialog },
globalSettings
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
index 14877eec9a83..30708a7cb2fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/HighPriorityProviderTest.java
@@ -127,25 +127,7 @@ public class HighPriorityProviderTest extends SysuiTestCase {
.getPeopleNotificationType(entry))
.thenReturn(TYPE_NON_PERSON);
- // THEN it has high priority
- assertTrue(mHighPriorityProvider.isHighPriority(entry));
- }
-
- @Test
- public void minImportanceForeground() {
- // GIVEN notification is low importance and is associated with a foreground service
- final Notification notification = mock(Notification.class);
- when(notification.isForegroundService()).thenReturn(true);
-
- final NotificationEntry entry = new NotificationEntryBuilder()
- .setNotification(notification)
- .setImportance(IMPORTANCE_MIN)
- .build();
- when(mPeopleNotificationIdentifier
- .getPeopleNotificationType(entry))
- .thenReturn(TYPE_NON_PERSON);
-
- // THEN it does NOT have high priority
+ // THEN it has low priority
assertFalse(mHighPriorityProvider.isHighPriority(entry));
}
@@ -155,7 +137,6 @@ public class HighPriorityProviderTest extends SysuiTestCase {
// to less than IMPORTANCE_DEFAULT (ie: IMPORTANCE_LOW or IMPORTANCE_MIN)
final Notification notification = new Notification.Builder(mContext, "test")
.setStyle(new Notification.MessagingStyle(""))
- .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
.build();
final NotificationChannel channel = new NotificationChannel("a", "a",
IMPORTANCE_LOW);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index 8cd71031a8f8..c1d2ea88a1b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -322,23 +322,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
}
@Test
- public void testPeopleFiltering_addHeadersFromShowingOnlyGentle() {
- enablePeopleFiltering();
-
- setStackState(
- GENTLE_HEADER,
- PERSON,
- ALERTING,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 2);
- verify(mNssl).addView(mSectionsManager.getAlertingHeaderView(), 1);
- verify(mNssl).addView(mSectionsManager.getPeopleHeaderView(), 0);
- }
-
- @Test
- public void testPeopleFiltering_addAllHeaders() {
+ public void testPeopleFiltering_onlyAddSilentHeader() {
enablePeopleFiltering();
setStackState(
@@ -348,26 +332,6 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
mSectionsManager.updateSectionBoundaries();
verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 2);
- verify(mNssl).addView(mSectionsManager.getAlertingHeaderView(), 1);
- verify(mNssl).addView(mSectionsManager.getPeopleHeaderView(), 0);
- }
-
- @Test
- public void testPeopleFiltering_moveAllHeaders() {
- enablePeopleFiltering();
-
- setStackState(
- PEOPLE_HEADER,
- ALERTING_HEADER,
- GENTLE_HEADER,
- PERSON,
- ALERTING,
- GENTLE);
- mSectionsManager.updateSectionBoundaries();
-
- verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 4);
- verify(mNssl).changeViewPosition(mSectionsManager.getAlertingHeaderView(), 2);
- verify(mNssl).changeViewPosition(mSectionsManager.getPeopleHeaderView(), 0);
}
@Test
@@ -385,9 +349,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON,
ChildType.GENTLE_HEADER,
ChildType.GENTLE
@@ -408,10 +370,8 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
ChildType.HEADS_UP,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON
);
}
@@ -428,7 +388,6 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.PEOPLE_HEADER,
ChildType.PERSON,
ChildType.PERSON
);
@@ -444,9 +403,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
);
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON
);
}
@@ -467,12 +424,9 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
ChildType.FSN,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON,
- ChildType.ALERTING_HEADER,
ChildType.ALERTING,
ChildType.GENTLE_HEADER,
ChildType.GENTLE
@@ -517,7 +471,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
}
@Test
- public void testRemoveIncomingHeader() {
+ public void testRemoveNonSilentHeader() {
enablePeopleFiltering();
enableMediaControls();
@@ -539,9 +493,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
verifyMockStack(
ChildType.MEDIA_CONTROLS,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON,
- ChildType.ALERTING_HEADER,
ChildType.ALERTING,
ChildType.ALERTING,
ChildType.ALERTING,
@@ -569,13 +521,10 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
ChildType.HEADS_UP,
ChildType.HEADS_UP,
- ChildType.PEOPLE_HEADER,
ChildType.PERSON,
- ChildType.ALERTING_HEADER,
ChildType.ALERTING
);
}
@@ -593,7 +542,6 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
- ChildType.ALERTING_HEADER,
ChildType.PERSON,
ChildType.ALERTING,
ChildType.GENTLE_HEADER,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index bdde82289e86..8b5ba3848500 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -174,6 +174,7 @@ public class DozeServiceHostTest extends SysuiTestCase {
DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
DozeLog.PULSE_REASON_DOCKING,
DozeLog.REASON_SENSOR_WAKE_UP,
+ DozeLog.REASON_SENSOR_QUICK_PICKUP,
DozeLog.REASON_SENSOR_TAP));
HashSet<Integer> reasonsThatDontPulse = new HashSet<>(
Arrays.asList(DozeLog.REASON_SENSOR_PICKUP,
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index 238bf0f5a335..d420bd4bdb66 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -52,8 +52,12 @@ import android.view.Surface;
* <p>For more information about creating an application that uses RenderScript, read the
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
-
+@Deprecated
public class Allocation extends BaseObj {
private static final int MAX_NUMBER_IO_INPUT_ALLOC = 16;
diff --git a/rs/java/android/renderscript/AllocationAdapter.java b/rs/java/android/renderscript/AllocationAdapter.java
index 6d7e97ebb0fe..17bc23421894 100644
--- a/rs/java/android/renderscript/AllocationAdapter.java
+++ b/rs/java/android/renderscript/AllocationAdapter.java
@@ -19,7 +19,11 @@ package android.renderscript;
/**
* Only intended for use by generated reflected code.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class AllocationAdapter extends Allocation {
Type mWindow;
diff --git a/rs/java/android/renderscript/BaseObj.java b/rs/java/android/renderscript/BaseObj.java
index 7b5514b8a0d1..ea8535d6d621 100644
--- a/rs/java/android/renderscript/BaseObj.java
+++ b/rs/java/android/renderscript/BaseObj.java
@@ -27,7 +27,11 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
* It is responsible for lifetime management and resource tracking. This class
* should not be used by a user application.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class BaseObj {
BaseObj(long id, RenderScript rs) {
rs.validate();
diff --git a/rs/java/android/renderscript/Byte2.java b/rs/java/android/renderscript/Byte2.java
index 3ad79e400c91..cb5cc473a48e 100644
--- a/rs/java/android/renderscript/Byte2.java
+++ b/rs/java/android/renderscript/Byte2.java
@@ -20,7 +20,11 @@ package android.renderscript;
/**
* Class for exposing the native RenderScript byte2 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Byte2 {
public byte x;
public byte y;
diff --git a/rs/java/android/renderscript/Byte3.java b/rs/java/android/renderscript/Byte3.java
index a138313321d0..aca4e645f102 100644
--- a/rs/java/android/renderscript/Byte3.java
+++ b/rs/java/android/renderscript/Byte3.java
@@ -20,7 +20,11 @@ package android.renderscript;
/**
* Class for exposing the native RenderScript byte3 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Byte3 {
public byte x;
public byte y;
diff --git a/rs/java/android/renderscript/Byte4.java b/rs/java/android/renderscript/Byte4.java
index fa4c13d79714..b30b6ed00d09 100644
--- a/rs/java/android/renderscript/Byte4.java
+++ b/rs/java/android/renderscript/Byte4.java
@@ -20,7 +20,11 @@ package android.renderscript;
/**
* Class for exposing the native RenderScript byte4 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Byte4 {
public byte x;
public byte y;
diff --git a/rs/java/android/renderscript/Double2.java b/rs/java/android/renderscript/Double2.java
index 4c7319d5a4b0..e14228a6f785 100644
--- a/rs/java/android/renderscript/Double2.java
+++ b/rs/java/android/renderscript/Double2.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic double type.
* Provides two double fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Double2 {
public double x;
public double y;
diff --git a/rs/java/android/renderscript/Double3.java b/rs/java/android/renderscript/Double3.java
index b819716017e9..e52c902a27fa 100644
--- a/rs/java/android/renderscript/Double3.java
+++ b/rs/java/android/renderscript/Double3.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic double type.
* Provides three double fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Double3 {
public double x;
public double y;
diff --git a/rs/java/android/renderscript/Double4.java b/rs/java/android/renderscript/Double4.java
index e4829f7426ae..a3e4a94af8f2 100644
--- a/rs/java/android/renderscript/Double4.java
+++ b/rs/java/android/renderscript/Double4.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic double type.
* Provides four double fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Double4 {
public double x;
public double y;
diff --git a/rs/java/android/renderscript/Element.java b/rs/java/android/renderscript/Element.java
index 0941907d35f8..f671953f4704 100644
--- a/rs/java/android/renderscript/Element.java
+++ b/rs/java/android/renderscript/Element.java
@@ -51,7 +51,12 @@ import android.compat.annotation.UnsupportedAppUsage;
* <p>For more information about creating an application that uses RenderScript, read the
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Element extends BaseObj {
int mSize;
Element[] mElements;
diff --git a/rs/java/android/renderscript/FieldPacker.java b/rs/java/android/renderscript/FieldPacker.java
index de1c49730aaa..aaa0fe8d7e95 100644
--- a/rs/java/android/renderscript/FieldPacker.java
+++ b/rs/java/android/renderscript/FieldPacker.java
@@ -26,7 +26,11 @@ import java.util.BitSet;
* reflected code generated by the RS tool chain. It should not
* be called directly.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class FieldPacker {
public FieldPacker(int len) {
mPos = 0;
diff --git a/rs/java/android/renderscript/FileA3D.java b/rs/java/android/renderscript/FileA3D.java
index 7cc2825ae565..f0a9fa718a6f 100644
--- a/rs/java/android/renderscript/FileA3D.java
+++ b/rs/java/android/renderscript/FileA3D.java
@@ -36,6 +36,7 @@ import java.io.InputStream;
* index entries for all the objects stored inside it.
*
**/
+@Deprecated
public class FileA3D extends BaseObj {
/**
diff --git a/rs/java/android/renderscript/Float2.java b/rs/java/android/renderscript/Float2.java
index e9f8ca7737ce..1f6038c9bfca 100644
--- a/rs/java/android/renderscript/Float2.java
+++ b/rs/java/android/renderscript/Float2.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic float type.
* Provides two float fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Float2 {
public float x;
public float y;
diff --git a/rs/java/android/renderscript/Float3.java b/rs/java/android/renderscript/Float3.java
index 555bdf6d6e4e..5f4571643daf 100644
--- a/rs/java/android/renderscript/Float3.java
+++ b/rs/java/android/renderscript/Float3.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic float type.
* Provides three float fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Float3 {
public float x;
public float y;
diff --git a/rs/java/android/renderscript/Float4.java b/rs/java/android/renderscript/Float4.java
index 6541b2ec7264..7f3ba2c5fc33 100644
--- a/rs/java/android/renderscript/Float4.java
+++ b/rs/java/android/renderscript/Float4.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic float type.
* Provides four float fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Float4 {
public float x;
public float y;
diff --git a/rs/java/android/renderscript/Font.java b/rs/java/android/renderscript/Font.java
index e47ec4b31700..6f6f341d78a6 100644
--- a/rs/java/android/renderscript/Font.java
+++ b/rs/java/android/renderscript/Font.java
@@ -45,6 +45,7 @@ import java.util.Map;
* them in the script to suit the user's rendering needs. Font colors work as a state machine.
* Every new call to draw text uses the last color set in the script.</p>
**/
+@Deprecated
public class Font extends BaseObj {
//These help us create a font by family name
diff --git a/rs/java/android/renderscript/Int2.java b/rs/java/android/renderscript/Int2.java
index 120957bcd726..be0639f7137d 100644
--- a/rs/java/android/renderscript/Int2.java
+++ b/rs/java/android/renderscript/Int2.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic int type.
* Provides two int fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Int2 {
public int x;
public int y;
diff --git a/rs/java/android/renderscript/Int3.java b/rs/java/android/renderscript/Int3.java
index 5431b9a75ba7..38a602d6bb4e 100644
--- a/rs/java/android/renderscript/Int3.java
+++ b/rs/java/android/renderscript/Int3.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic int type.
* Provides three int fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Int3 {
public int x;
public int y;
diff --git a/rs/java/android/renderscript/Int4.java b/rs/java/android/renderscript/Int4.java
index 1c0e2e2621aa..52f7bb2c2461 100644
--- a/rs/java/android/renderscript/Int4.java
+++ b/rs/java/android/renderscript/Int4.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic int type.
* Provides four int fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Int4 {
public int x;
public int y;
diff --git a/rs/java/android/renderscript/Long2.java b/rs/java/android/renderscript/Long2.java
index fabf2046a48c..1b3955b04798 100644
--- a/rs/java/android/renderscript/Long2.java
+++ b/rs/java/android/renderscript/Long2.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic long type.
* Provides two long fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Long2 {
public long x;
public long y;
diff --git a/rs/java/android/renderscript/Long3.java b/rs/java/android/renderscript/Long3.java
index 8e243cce647f..8be9c1cf2774 100644
--- a/rs/java/android/renderscript/Long3.java
+++ b/rs/java/android/renderscript/Long3.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic long type.
* Provides three long fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Long3 {
public long x;
public long y;
diff --git a/rs/java/android/renderscript/Long4.java b/rs/java/android/renderscript/Long4.java
index 1a1ad748e462..75db51b1237a 100644
--- a/rs/java/android/renderscript/Long4.java
+++ b/rs/java/android/renderscript/Long4.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic long type.
* Provides four long fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Long4 {
public long x;
public long y;
diff --git a/rs/java/android/renderscript/Matrix2f.java b/rs/java/android/renderscript/Matrix2f.java
index 048262dc7eba..5f5e709d2c99 100644
--- a/rs/java/android/renderscript/Matrix2f.java
+++ b/rs/java/android/renderscript/Matrix2f.java
@@ -20,7 +20,11 @@ package android.renderscript;
/**
* Class for exposing the native RenderScript rs_matrix2x2 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Matrix2f {
/**
diff --git a/rs/java/android/renderscript/Matrix3f.java b/rs/java/android/renderscript/Matrix3f.java
index 9a4af777583c..b620eaf1415d 100644
--- a/rs/java/android/renderscript/Matrix3f.java
+++ b/rs/java/android/renderscript/Matrix3f.java
@@ -20,7 +20,11 @@ package android.renderscript;
/**
* Class for exposing the native RenderScript rs_matrix3x3 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Matrix3f {
/**
diff --git a/rs/java/android/renderscript/Matrix4f.java b/rs/java/android/renderscript/Matrix4f.java
index a9469c979494..cdf06a63c59f 100644
--- a/rs/java/android/renderscript/Matrix4f.java
+++ b/rs/java/android/renderscript/Matrix4f.java
@@ -22,7 +22,11 @@ import android.compat.annotation.UnsupportedAppUsage;
/**
* Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Matrix4f {
/**
diff --git a/rs/java/android/renderscript/Mesh.java b/rs/java/android/renderscript/Mesh.java
index 1a4d1fd5afbb..f2fd5a92afe8 100644
--- a/rs/java/android/renderscript/Mesh.java
+++ b/rs/java/android/renderscript/Mesh.java
@@ -40,6 +40,7 @@ import java.util.Vector;
* index sets or primitive types.
* </p>
**/
+@Deprecated
public class Mesh extends BaseObj {
/**
diff --git a/rs/java/android/renderscript/Program.java b/rs/java/android/renderscript/Program.java
index ff072183e927..3cadc935e67c 100644
--- a/rs/java/android/renderscript/Program.java
+++ b/rs/java/android/renderscript/Program.java
@@ -32,7 +32,11 @@ import java.io.UnsupportedEncodingException;
* Program is a base class for all the objects that modify
* various stages of the graphics pipeline
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Program extends BaseObj {
static final int MAX_INPUT = 8;
static final int MAX_OUTPUT = 8;
diff --git a/rs/java/android/renderscript/ProgramFragment.java b/rs/java/android/renderscript/ProgramFragment.java
index 880531207b4d..e2879d8a0d54 100644
--- a/rs/java/android/renderscript/ProgramFragment.java
+++ b/rs/java/android/renderscript/ProgramFragment.java
@@ -37,6 +37,7 @@ import android.compat.annotation.UnsupportedAppUsage;
* </p>
*
**/
+@Deprecated
public class ProgramFragment extends Program {
ProgramFragment(long id, RenderScript rs) {
super(id, rs);
diff --git a/rs/java/android/renderscript/ProgramFragmentFixedFunction.java b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
index c741ce6e77ed..8dbf6f44f137 100644
--- a/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
+++ b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
@@ -29,6 +29,7 @@ import android.compat.annotation.UnsupportedAppUsage;
* blended with results of up to two texture lookups.</p
*
**/
+@Deprecated
public class ProgramFragmentFixedFunction extends ProgramFragment {
ProgramFragmentFixedFunction(long id, RenderScript rs) {
super(id, rs);
diff --git a/rs/java/android/renderscript/ProgramRaster.java b/rs/java/android/renderscript/ProgramRaster.java
index a21696c82161..8b53828918a8 100644
--- a/rs/java/android/renderscript/ProgramRaster.java
+++ b/rs/java/android/renderscript/ProgramRaster.java
@@ -25,6 +25,7 @@ import android.compat.annotation.UnsupportedAppUsage;
* Program raster is primarily used to specify whether point sprites are enabled and to control
* the culling mode. By default, back faces are culled.
**/
+@Deprecated
public class ProgramRaster extends BaseObj {
/**
diff --git a/rs/java/android/renderscript/ProgramStore.java b/rs/java/android/renderscript/ProgramStore.java
index 1952b8860033..c94d2534dad6 100644
--- a/rs/java/android/renderscript/ProgramStore.java
+++ b/rs/java/android/renderscript/ProgramStore.java
@@ -34,7 +34,11 @@ import android.os.Build;
* framebuffer</li>
* </ul>
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class ProgramStore extends BaseObj {
/**
* Specifies the function used to determine whether a fragment
diff --git a/rs/java/android/renderscript/ProgramVertex.java b/rs/java/android/renderscript/ProgramVertex.java
index 9257234de42c..ecd8a31ed130 100644
--- a/rs/java/android/renderscript/ProgramVertex.java
+++ b/rs/java/android/renderscript/ProgramVertex.java
@@ -34,7 +34,6 @@
* The signatures don't have to be exact or in any strict order. As long as the input name in the shader
* matches a channel name and size available on the mesh, the runtime takes care of connecting the
* two. Unlike OpenGL, there is no need to link the vertex and fragment programs.</p>
- *
**/
package android.renderscript;
@@ -49,6 +48,7 @@ import android.compat.annotation.UnsupportedAppUsage;
* geometric data in a user-defined way.
*
**/
+@Deprecated
public class ProgramVertex extends Program {
ProgramVertex(long id, RenderScript rs) {
diff --git a/rs/java/android/renderscript/ProgramVertexFixedFunction.java b/rs/java/android/renderscript/ProgramVertexFixedFunction.java
index 03c2eaf91242..4cf2f4c8174f 100644
--- a/rs/java/android/renderscript/ProgramVertexFixedFunction.java
+++ b/rs/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -27,6 +27,7 @@ import android.compat.annotation.UnsupportedAppUsage;
* without writing any GLSL code.
*
**/
+@Deprecated
public class ProgramVertexFixedFunction extends ProgramVertex {
ProgramVertexFixedFunction(long id, RenderScript rs) {
diff --git a/rs/java/android/renderscript/RSDriverException.java b/rs/java/android/renderscript/RSDriverException.java
index 9e6507f517ed..3d0f0bfadbd0 100644
--- a/rs/java/android/renderscript/RSDriverException.java
+++ b/rs/java/android/renderscript/RSDriverException.java
@@ -20,7 +20,12 @@ package android.renderscript;
/**
* Base class for all exceptions thrown by the Android
* RenderScript
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class RSDriverException extends RSRuntimeException {
public RSDriverException(String string) {
super(string);
diff --git a/rs/java/android/renderscript/RSIllegalArgumentException.java b/rs/java/android/renderscript/RSIllegalArgumentException.java
index 5c68594f33a2..d0ac5b681f2f 100644
--- a/rs/java/android/renderscript/RSIllegalArgumentException.java
+++ b/rs/java/android/renderscript/RSIllegalArgumentException.java
@@ -20,7 +20,12 @@ package android.renderscript;
/**
* Base class for all exceptions thrown by the Android
* RenderScript
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class RSIllegalArgumentException extends RSRuntimeException {
public RSIllegalArgumentException(String string) {
super(string);
diff --git a/rs/java/android/renderscript/RSInvalidStateException.java b/rs/java/android/renderscript/RSInvalidStateException.java
index c881898dab3d..5eea41997f35 100644
--- a/rs/java/android/renderscript/RSInvalidStateException.java
+++ b/rs/java/android/renderscript/RSInvalidStateException.java
@@ -20,7 +20,12 @@ package android.renderscript;
/**
* Base class for all exceptions thrown by the Android
* RenderScript
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class RSInvalidStateException extends RSRuntimeException {
public RSInvalidStateException(String string) {
super(string);
diff --git a/rs/java/android/renderscript/RSRuntimeException.java b/rs/java/android/renderscript/RSRuntimeException.java
index b4b629e14184..d52a1c10add0 100644
--- a/rs/java/android/renderscript/RSRuntimeException.java
+++ b/rs/java/android/renderscript/RSRuntimeException.java
@@ -20,7 +20,12 @@ package android.renderscript;
/**
* Base class for all exceptions thrown by the Android
* RenderScript
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class RSRuntimeException
extends java.lang.RuntimeException {
public RSRuntimeException(String string) {
diff --git a/rs/java/android/renderscript/RSSurfaceView.java b/rs/java/android/renderscript/RSSurfaceView.java
index 6bdde387b334..05c0112f1bb7 100644
--- a/rs/java/android/renderscript/RSSurfaceView.java
+++ b/rs/java/android/renderscript/RSSurfaceView.java
@@ -33,6 +33,7 @@ import android.view.SurfaceView;
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
*/
+@Deprecated
public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mSurfaceHolder;
private RenderScriptGL mRS;
diff --git a/rs/java/android/renderscript/RSTextureView.java b/rs/java/android/renderscript/RSTextureView.java
index af3258a7090d..ed68fc39ddce 100644
--- a/rs/java/android/renderscript/RSTextureView.java
+++ b/rs/java/android/renderscript/RSTextureView.java
@@ -28,6 +28,7 @@ import android.view.TextureView;
* to draw on.
*
*/
+@Deprecated
public class RSTextureView extends TextureView implements TextureView.SurfaceTextureListener {
private RenderScriptGL mRS;
private SurfaceTexture mSurfaceTexture;
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 806a25a748e2..855cfdcbdf7b 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -44,7 +44,12 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
* <p>For more information about creating an application that uses RenderScript, read the
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class RenderScript {
static final long TRACE_TAG = Trace.TRACE_TAG_RS;
diff --git a/rs/java/android/renderscript/RenderScriptCacheDir.java b/rs/java/android/renderscript/RenderScriptCacheDir.java
index 862d032d6987..cd6e8b14a793 100644
--- a/rs/java/android/renderscript/RenderScriptCacheDir.java
+++ b/rs/java/android/renderscript/RenderScriptCacheDir.java
@@ -23,7 +23,11 @@ import java.io.File;
/**
* Used only for tracking the RenderScript cache directory.
* @hide
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class RenderScriptCacheDir {
/**
* Sets the directory to use as a persistent storage for the
diff --git a/rs/java/android/renderscript/RenderScriptGL.java b/rs/java/android/renderscript/RenderScriptGL.java
index dafaf367364d..d46dbf68291b 100644
--- a/rs/java/android/renderscript/RenderScriptGL.java
+++ b/rs/java/android/renderscript/RenderScriptGL.java
@@ -37,6 +37,7 @@ import android.view.SurfaceHolder;
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
**/
+@Deprecated
public class RenderScriptGL extends RenderScript {
int mWidth;
int mHeight;
diff --git a/rs/java/android/renderscript/Sampler.java b/rs/java/android/renderscript/Sampler.java
index 70e88bc51f79..06f036db3aa5 100644
--- a/rs/java/android/renderscript/Sampler.java
+++ b/rs/java/android/renderscript/Sampler.java
@@ -25,7 +25,12 @@ package android.renderscript;
* android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}; using a Sampler on
* an {@link android.renderscript.Allocation} that was not created with {@link
* android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE} is undefined.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Sampler extends BaseObj {
public enum Value {
NEAREST (0),
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index d1d3a7642382..f32a2f7ef482 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -22,7 +22,12 @@ import android.util.SparseArray;
/**
* The parent class for all executable scripts. This should not be used by
* applications.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Script extends BaseObj {
/**
diff --git a/rs/java/android/renderscript/ScriptC.java b/rs/java/android/renderscript/ScriptC.java
index 00ebe5756589..1866a9983495 100644
--- a/rs/java/android/renderscript/ScriptC.java
+++ b/rs/java/android/renderscript/ScriptC.java
@@ -25,7 +25,12 @@ import java.io.InputStream;
/**
* The superclass for all user-defined scripts. This is only
* intended to be used by the generated derived classes.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class ScriptC extends Script {
private static final String TAG = "ScriptC";
diff --git a/rs/java/android/renderscript/ScriptGroup.java b/rs/java/android/renderscript/ScriptGroup.java
index e0bdbfcdfed5..5cdb9cf3b8be 100644
--- a/rs/java/android/renderscript/ScriptGroup.java
+++ b/rs/java/android/renderscript/ScriptGroup.java
@@ -37,7 +37,12 @@ import java.util.Map;
* Grouping kernels together allows for more efficient execution. For example,
* runtime and compiler optimization can be applied to reduce computation and
* communication overhead, and to make better use of the CPU and the GPU.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptGroup extends BaseObj {
private static final String TAG = "ScriptGroup";
IO mOutputs[];
diff --git a/rs/java/android/renderscript/ScriptIntrinsic.java b/rs/java/android/renderscript/ScriptIntrinsic.java
index 61211a25f8af..8d654221b4a8 100644
--- a/rs/java/android/renderscript/ScriptIntrinsic.java
+++ b/rs/java/android/renderscript/ScriptIntrinsic.java
@@ -23,7 +23,12 @@ package android.renderscript;
* operations.
*
* Not intended for direct use.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public abstract class ScriptIntrinsic extends Script {
ScriptIntrinsic(long id, RenderScript rs) {
super(id, rs);
diff --git a/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java b/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java
index ce149d9a103a..7a2847e3bfcc 100644
--- a/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java
+++ b/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java
@@ -23,7 +23,11 @@ package android.renderscript;
* allocation. The 8 nearest values are sampled and linearly interpolated. The
* result is placed in the output.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsic3DLUT extends ScriptIntrinsic {
private Allocation mLUT;
private Element mElement;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
index 49a71b430ac6..16cc79930b76 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java
@@ -29,7 +29,11 @@ import java.lang.annotation.RetentionPolicy;
*
* For detailed description of BLAS, please refer to http://www.netlib.org/blas/
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicBLAS extends ScriptIntrinsic {
private Allocation mLUT;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBlend.java b/rs/java/android/renderscript/ScriptIntrinsicBlend.java
index fdcd61b04eca..a1c79ef938c4 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBlend.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBlend.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Intrinsic kernels for blending two {@link android.renderscript.Allocation} objects.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class ScriptIntrinsicBlend extends ScriptIntrinsic {
ScriptIntrinsicBlend(long id, RenderScript rs) {
super(id, rs);
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBlur.java b/rs/java/android/renderscript/ScriptIntrinsicBlur.java
index 0891d5142022..68cbc3f3eaad 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBlur.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBlur.java
@@ -20,8 +20,11 @@ package android.renderscript;
* Intrinsic Gausian blur filter. Applies a gaussian blur of the
* specified radius to all elements of an allocation.
*
- *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicBlur extends ScriptIntrinsic {
private final float[] mValues = new float[9];
private Allocation mInput;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java b/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java
index e8a299c28c51..4a05cf54e13f 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java
@@ -36,7 +36,12 @@ package android.renderscript;
* Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
* {@link Element#F32}, {@link Element#F32_2}, {@link
* Element#F32_3}, and {@link Element#F32_4}.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicColorMatrix extends ScriptIntrinsic {
private final Matrix4f mMatrix = new Matrix4f();
private final Float4 mAdd = new Float4();
diff --git a/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java b/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
index 9fe7b2d8f0ef..4b9dff18f62e 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
@@ -19,7 +19,11 @@ package android.renderscript;
/**
* Intrinsic for applying a 3x3 convolve to an allocation.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicConvolve3x3 extends ScriptIntrinsic {
private final float[] mValues = new float[9];
private Allocation mInput;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
index 8518bb27379d..ed93c7eda0a8 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -19,7 +19,11 @@ package android.renderscript;
/**
* Intrinsic for applying a 5x5 convolve to an allocation.
*
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicConvolve5x5 extends ScriptIntrinsic {
private final float[] mValues = new float[25];
private Allocation mInput;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicHistogram.java b/rs/java/android/renderscript/ScriptIntrinsicHistogram.java
index 0e8b36c11952..4a71bc8c41ca 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicHistogram.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicHistogram.java
@@ -19,8 +19,11 @@ package android.renderscript;
/**
* Intrinsic Histogram filter.
*
- *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicHistogram extends ScriptIntrinsic {
private Allocation mOut;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicLUT.java b/rs/java/android/renderscript/ScriptIntrinsicLUT.java
index e90462d11124..7d5b09fb41aa 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicLUT.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicLUT.java
@@ -21,7 +21,12 @@ package android.renderscript;
* channel of the input has an independant lookup table. The
* tables are 256 entries in size and can cover the full value
* range of {@link Element#U8_4}.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public final class ScriptIntrinsicLUT extends ScriptIntrinsic {
private final Matrix4f mMatrix = new Matrix4f();
private Allocation mTables;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicResize.java b/rs/java/android/renderscript/ScriptIntrinsicResize.java
index 45b0a646b924..a87fe95e2225 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicResize.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicResize.java
@@ -18,7 +18,12 @@ package android.renderscript;
/**
* Intrinsic for performing a resize of a 2D allocation.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public final class ScriptIntrinsicResize extends ScriptIntrinsic {
private Allocation mInput;
diff --git a/rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java b/rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
index e64c91103c8f..a94f9167d953 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
@@ -23,7 +23,12 @@ package android.renderscript;
* The input allocation should be supplied in a supported YUV format
* as a YUV element Allocation. The output is RGBA; the alpha channel
* will be set to 255.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public final class ScriptIntrinsicYuvToRGB extends ScriptIntrinsic {
private Allocation mInput;
diff --git a/rs/java/android/renderscript/Short2.java b/rs/java/android/renderscript/Short2.java
index 24809f739159..4565eb4c11d4 100644
--- a/rs/java/android/renderscript/Short2.java
+++ b/rs/java/android/renderscript/Short2.java
@@ -22,7 +22,12 @@ package android.renderscript;
*
* Vector version of the basic short type.
* Provides two short fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Short2 {
public short x;
public short y;
diff --git a/rs/java/android/renderscript/Short3.java b/rs/java/android/renderscript/Short3.java
index 661db0a89f3d..3d70f078e483 100644
--- a/rs/java/android/renderscript/Short3.java
+++ b/rs/java/android/renderscript/Short3.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic short type.
* Provides three short fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Short3 {
public short x;
public short y;
diff --git a/rs/java/android/renderscript/Short4.java b/rs/java/android/renderscript/Short4.java
index a2d74f2ccf94..c90d64876e32 100644
--- a/rs/java/android/renderscript/Short4.java
+++ b/rs/java/android/renderscript/Short4.java
@@ -19,7 +19,12 @@ package android.renderscript;
/**
* Vector version of the basic short type.
* Provides four short fields packed.
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
*/
+@Deprecated
public class Short4 {
public short x;
public short y;
diff --git a/rs/java/android/renderscript/Type.java b/rs/java/android/renderscript/Type.java
index dc2378596d00..021fd06b3535 100644
--- a/rs/java/android/renderscript/Type.java
+++ b/rs/java/android/renderscript/Type.java
@@ -42,7 +42,12 @@ package android.renderscript;
* <p>For more information about creating an application that uses RenderScript, read the
* <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
+ *
+ * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
+ * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
+ * guide</a> for the proposed alternatives.
**/
+@Deprecated
public class Type extends BaseObj {
int mDimX;
int mDimY;
diff --git a/rs/jni/Android.mk b/rs/jni/Android.mk
index e41073bcdb76..0caba421dca8 100644
--- a/rs/jni/Android.mk
+++ b/rs/jni/Android.mk
@@ -25,7 +25,7 @@ LOCAL_C_INCLUDES += \
frameworks/rs
LOCAL_CFLAGS += -Wno-unused-parameter
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code -Wno-deprecated-declarations
LOCAL_MODULE:= librs_jni
LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
diff --git a/services/api/Android.bp b/services/api/Android.bp
index e69de29bb2d1..b8ca5488c5cd 100644
--- a/services/api/Android.bp
+++ b/services/api/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_visibility: ["//visibility:private"],
+}
+
+filegroup {
+ name: "non-updatable-system-server-current.txt",
+ srcs: ["non-updatable-current.txt"],
+ visibility: ["//frameworks/base/api"],
+}
+
+filegroup {
+ name: "non-updatable-system-server-removed.txt",
+ srcs: ["non-updatable-removed.txt"],
+ visibility: ["//frameworks/base/api"],
+} \ No newline at end of file
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 52237c934797..4b5684511757 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -766,6 +766,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
.get(association.getPackageName());
if (serviceConnector != null) {
serviceConnector.unbind();
+ restartBleScan();
}
}
}
@@ -1067,11 +1068,19 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
}
void onDeviceDisconnected(String address) {
- Slog.d(LOG_TAG, "onDeviceConnected(address = " + address + ")");
+ Slog.d(LOG_TAG, "onDeviceDisconnected(address = " + address + ")");
mCurrentlyConnectedDevices.remove(address);
- onDeviceDisappeared(address);
+ Date lastSeen = mDevicesLastNearby.get(address);
+ if (isDeviceDisappeared(lastSeen)) {
+ onDeviceDisappeared(address);
+ }
+ }
+
+ private boolean isDeviceDisappeared(Date lastSeen) {
+ return lastSeen == null || System.currentTimeMillis() - lastSeen.getTime()
+ >= DEVICE_DISAPPEARED_UNBIND_TIMEOUT_MS;
}
private ServiceConnector<ICompanionDeviceService> getDeviceListenerServiceConnector(
@@ -1172,8 +1181,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
String address = mDevicesLastNearby.keyAt(i);
Date lastNearby = mDevicesLastNearby.valueAt(i);
- if (System.currentTimeMillis() - lastNearby.getTime()
- >= DEVICE_DISAPPEARED_UNBIND_TIMEOUT_MS) {
+ if (isDeviceDisappeared(lastNearby)) {
for (Association association : getAllAssociations(address)) {
if (association.isNotifyOnDeviceNearby()) {
getDeviceListenerServiceConnector(association).unbind();
diff --git a/services/core/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java
index d83e2fd2090d..b7c5fba69c8a 100644
--- a/services/core/java/com/android/server/BootReceiver.java
+++ b/services/core/java/com/android/server/BootReceiver.java
@@ -128,6 +128,9 @@ public class BootReceiver extends BroadcastReceiver {
// Location of ftrace pipe for notifications from kernel memory tools like KFENCE and KASAN.
private static final String ERROR_REPORT_TRACE_PIPE =
"/sys/kernel/tracing/instances/bootreceiver/trace_pipe";
+ // Stop after sending this many reports. See http://b/182159975.
+ private static final int MAX_ERROR_REPORTS = 8;
+ private static int sSentReports = 0;
// Avoid reporing the same bug from processDmesg() twice.
private static String sLastReportedBug = null;
@@ -301,7 +304,7 @@ public class BootReceiver extends BroadcastReceiver {
* - repeat the above steps till the last report is found.
*/
private void processDmesg(Context ctx) throws IOException {
-
+ if (sSentReports == MAX_ERROR_REPORTS) return;
/*
* Only SYSTEM_KASAN_ERROR_REPORT and SYSTEM_KFENCE_ERROR_REPORT are supported at the
* moment.
@@ -352,7 +355,7 @@ public class BootReceiver extends BroadcastReceiver {
}
// Avoid sending the same bug report twice.
- if (bugTitle == sLastReportedBug) return;
+ if (bugTitle.equals(sLastReportedBug)) return;
final String reportTag = "SYSTEM_" + tool + "_ERROR_REPORT";
final DropBoxManager db = ctx.getSystemService(DropBoxManager.class);
@@ -361,6 +364,7 @@ public class BootReceiver extends BroadcastReceiver {
addTextToDropBox(db, reportTag, reportText, "/dev/kmsg", LOG_SIZE);
sLastReportedBug = bugTitle;
+ sSentReports++;
}
private void removeOldUpdatePackages(Context context) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 9a5e4ca0068a..78853c777254 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -175,6 +175,7 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.sysprop.NetworkProperties;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -189,7 +190,6 @@ import com.android.connectivity.aidl.INetworkAgent;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IBatteryStats;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.LocationPermissionChecker;
@@ -201,7 +201,6 @@ import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
import com.android.net.module.util.NetworkCapabilitiesUtils;
import com.android.net.module.util.PermissionUtils;
-import com.android.server.am.BatteryStatsService;
import com.android.server.connectivity.AutodestructReference;
import com.android.server.connectivity.DnsManager;
import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
@@ -217,7 +216,6 @@ import com.android.server.connectivity.PermissionMonitor;
import com.android.server.connectivity.ProxyTracker;
import com.android.server.connectivity.QosCallbackTracker;
import com.android.server.net.NetworkPolicyManagerInternal;
-import com.android.server.utils.PriorityDump;
import libcore.io.IoUtils;
@@ -884,27 +882,59 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
+ final LocalPriorityDump mPriorityDumper = new LocalPriorityDump();
/**
* Helper class which parses out priority arguments and dumps sections according to their
* priority. If priority arguments are omitted, function calls the legacy dump command.
*/
- private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
- @Override
- public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
- doDump(fd, pw, new String[] {DIAG_ARG}, asProto);
- doDump(fd, pw, new String[] {SHORT_ARG}, asProto);
+ private class LocalPriorityDump {
+ private static final String PRIORITY_ARG = "--dump-priority";
+ private static final String PRIORITY_ARG_HIGH = "HIGH";
+ private static final String PRIORITY_ARG_NORMAL = "NORMAL";
+
+ LocalPriorityDump() {}
+
+ private void dumpHigh(FileDescriptor fd, PrintWriter pw) {
+ doDump(fd, pw, new String[] {DIAG_ARG});
+ doDump(fd, pw, new String[] {SHORT_ARG});
}
- @Override
- public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
- doDump(fd, pw, args, asProto);
+ private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
+ doDump(fd, pw, args);
}
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
- doDump(fd, pw, args, asProto);
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (args == null) {
+ dumpNormal(fd, pw, args);
+ return;
+ }
+
+ String priority = null;
+ for (int argIndex = 0; argIndex < args.length; argIndex++) {
+ if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) {
+ argIndex++;
+ priority = args[argIndex];
+ }
+ }
+
+ if (PRIORITY_ARG_HIGH.equals(priority)) {
+ dumpHigh(fd, pw);
+ } else if (PRIORITY_ARG_NORMAL.equals(priority)) {
+ dumpNormal(fd, pw, args);
+ } else {
+ // ConnectivityService publishes binder service using publishBinderService() with
+ // no priority assigned will be treated as NORMAL priority. Dumpsys does not send
+ // "--dump-priority" arguments to the service. Thus, dump both NORMAL and HIGH to
+ // align the legacy design.
+ // TODO: Integrate into signal dump.
+ dumpNormal(fd, pw, args);
+ pw.println();
+ pw.println("DUMP OF SERVICE HIGH connectivity");
+ pw.println();
+ dumpHigh(fd, pw);
+ }
}
- };
+ }
/**
* Keeps track of the number of requests made under different uids.
@@ -1035,19 +1065,19 @@ public class ConnectivityService extends IConnectivityManager.Stub
return new MultinetworkPolicyTracker(c, h, r);
}
- public IBatteryStats getBatteryStatsService() {
- return BatteryStatsService.getService();
- }
-
/**
* @see BatteryStatsManager
*/
public void reportNetworkInterfaceForTransports(Context context, String iface,
int[] transportTypes) {
- final BatteryStatsManager batteryStats =
+ final BatteryStatsManager batteryStats =
context.getSystemService(BatteryStatsManager.class);
batteryStats.reportNetworkInterfaceForTransports(iface, transportTypes);
}
+
+ public boolean getCellular464XlatEnabled() {
+ return NetworkProperties.isCellular464XlatEnabled().orElse(true);
+ }
}
public ConnectivityService(Context context) {
@@ -1246,8 +1276,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
new NetworkInfo(TYPE_NONE, 0, "", ""),
new LinkProperties(), new NetworkCapabilities(), 0, mContext,
null, new NetworkAgentConfig(), this, null,
- null, 0, INVALID_UID,
- mQosCallbackTracker);
+ null, 0, INVALID_UID, mQosCallbackTracker, mDeps);
}
private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
@@ -1489,11 +1518,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
// but only exists if an app asks about them or requests them. Ensure the requesting app
// gets the type it asks for.
filtered.setType(type);
- final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)
- ? DetailedState.BLOCKED
- : filtered.getDetailedState();
- filtered.setDetailedState(getLegacyLockdownState(state),
- "" /* reason */, null /* extraInfo */);
+ if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) {
+ filtered.setDetailedState(DetailedState.BLOCKED, null /* reason */,
+ null /* extraInfo */);
+ }
+ filterForLegacyLockdown(filtered);
return filtered;
}
@@ -1569,8 +1598,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, false)
? DetailedState.BLOCKED
: DetailedState.DISCONNECTED;
- info.setDetailedState(getLegacyLockdownState(state),
- "" /* reason */, null /* extraInfo */);
+ info.setDetailedState(state, null /* reason */, null /* extraInfo */);
+ filterForLegacyLockdown(info);
return info;
}
@@ -2364,9 +2393,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
}
- // Public because it's used by mLockdownTracker.
- public void sendConnectedBroadcast(NetworkInfo info) {
- PermissionUtils.enforceNetworkStackPermission(mContext);
+ private void sendConnectedBroadcast(NetworkInfo info) {
sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
}
@@ -2603,7 +2630,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
@Nullable String[] args) {
- PriorityDump.dump(mPriorityDumper, fd, writer, args);
+ mPriorityDumper.dump(fd, writer, args);
}
private boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
@@ -2618,10 +2645,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- private void doDump(FileDescriptor fd, PrintWriter writer, String[] args, boolean asProto) {
+ private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
if (!checkDumpPermission(mContext, TAG, pw)) return;
- if (asProto) return;
if (CollectionUtils.contains(args, DIAG_ARG)) {
dumpNetworkDiagnostics(pw);
@@ -3614,11 +3640,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
// pendingIntent => NetworkRequestInfo map.
// This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) {
- Intent intent = pendingIntent.getIntent();
for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) {
PendingIntent existingPendingIntent = entry.getValue().mPendingIntent;
if (existingPendingIntent != null &&
- existingPendingIntent.getIntent().filterEquals(intent)) {
+ existingPendingIntent.intentFilterEquals(pendingIntent)) {
return entry.getValue();
}
}
@@ -3661,6 +3686,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
}
+ // If this NRI has a satisfier already, it is replacing an older request that
+ // has been removed. Track it.
+ final NetworkRequest activeRequest = nri.getActiveRequest();
+ if (null != activeRequest) {
+ // If there is an active request, then for sure there is a satisfier.
+ nri.getSatisfier().addRequest(activeRequest);
+ }
}
rematchAllNetworksAndRequests();
@@ -5006,8 +5038,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// The legacy lockdown VPN always uses the default network.
// If the VPN's underlying network is no longer the current default network, it means that
// the default network has just switched, and the VPN is about to disconnect.
- // Report that the VPN is not connected, so when the state of NetworkInfo objects
- // overwritten by getLegacyLockdownState will be set to CONNECTING and not CONNECTED.
+ // Report that the VPN is not connected, so the state of NetworkInfo objects overwritten
+ // by filterForLegacyLockdown will be set to CONNECTING and not CONNECTED.
final NetworkAgentInfo defaultNetwork = getDefaultNetwork();
if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) {
return null;
@@ -5016,6 +5048,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
return nai;
};
+ // TODO: move all callers to filterForLegacyLockdown and delete this method.
+ // This likely requires making sendLegacyNetworkBroadcast take a NetworkInfo object instead of
+ // just a DetailedState object.
private DetailedState getLegacyLockdownState(DetailedState origState) {
if (origState != DetailedState.CONNECTED) {
return origState;
@@ -5025,6 +5060,23 @@ public class ConnectivityService extends IConnectivityManager.Stub
: DetailedState.CONNECTED;
}
+ private void filterForLegacyLockdown(NetworkInfo ni) {
+ if (!mLockdownEnabled || !ni.isConnected()) return;
+ // The legacy lockdown VPN replaces the state of every network in CONNECTED state with the
+ // state of its VPN. This is to ensure that when an underlying network connects, apps will
+ // not see a CONNECTIVITY_ACTION broadcast for a network in state CONNECTED until the VPN
+ // comes up, at which point there is a new CONNECTIVITY_ACTION broadcast for the underlying
+ // network, this time with a state of CONNECTED.
+ //
+ // Now that the legacy lockdown code lives in ConnectivityService, and no longer has access
+ // to the internal state of the Vpn object, always replace the state with CONNECTING. This
+ // is not too far off the truth, since an always-on VPN, when not connected, is always
+ // trying to reconnect.
+ if (getLegacyLockdownNai() == null) {
+ ni.setDetailedState(DetailedState.CONNECTING, "", null);
+ }
+ }
+
@Override
public void setProvisioningNotificationVisible(boolean visible, int networkType,
String action) {
@@ -5281,14 +5333,26 @@ public class ConnectivityService extends IConnectivityManager.Stub
ensureAllNetworkRequestsHaveType(r);
mRequests = initializeRequests(r);
mNetworkRequestForCallback = nri.getNetworkRequestForCallback();
- // Note here that the satisfier may have corresponded to an old request, that
- // this code doesn't try to take over. While it is a small discrepancy in the
- // structure of these requests, it will be fixed by the next rematch and it's
- // not as bad as having an NRI not storing its real satisfier.
- // Fixing this discrepancy would require figuring out in the copying code what
- // is the new request satisfied by this, which is a bit complex and not very
- // useful as no code is using it until rematch fixes it.
- mSatisfier = nri.mSatisfier;
+ final NetworkAgentInfo satisfier = nri.getSatisfier();
+ if (null != satisfier) {
+ // If the old NRI was satisfied by an NAI, then it may have had an active request.
+ // The active request is necessary to figure out what callbacks to send, in
+ // particular then a network updates its capabilities.
+ // As this code creates a new NRI with a new set of requests, figure out which of
+ // the list of requests should be the active request. It is always the first
+ // request of the list that can be satisfied by the satisfier since the order of
+ // requests is a priority order.
+ // Note even in the presence of a satisfier there may not be an active request,
+ // when the satisfier is the no-service network.
+ NetworkRequest activeRequest = null;
+ for (final NetworkRequest candidate : r) {
+ if (candidate.canBeSatisfiedBy(satisfier.networkCapabilities)) {
+ activeRequest = candidate;
+ break;
+ }
+ }
+ setSatisfier(satisfier, activeRequest);
+ }
mMessenger = nri.mMessenger;
mBinder = nri.mBinder;
mPid = nri.mPid;
@@ -6088,7 +6152,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
final NetworkAgentInfo nai = new NetworkAgentInfo(na,
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
- this, mNetd, mDnsResolver, providerId, uid, mQosCallbackTracker);
+ this, mNetd, mDnsResolver, providerId, uid, mQosCallbackTracker, mDeps);
// Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
processCapabilitiesFromAgent(nai, nc);
@@ -7896,6 +7960,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// and is still connected.
NetworkInfo info = new NetworkInfo(nai.networkInfo);
info.setType(type);
+ filterForLegacyLockdown(info);
if (state != DetailedState.DISCONNECTED) {
info.setDetailedState(state, null, info.getExtraInfo());
sendConnectedBroadcast(info);
diff --git a/services/core/java/com/android/server/ConnectivityServiceInitializer.java b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
index b9922087109f..2465479aadd8 100644
--- a/services/core/java/com/android/server/ConnectivityServiceInitializer.java
+++ b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
@@ -16,9 +16,6 @@
package com.android.server;
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
-
import android.content.Context;
import android.util.Log;
@@ -42,6 +39,6 @@ public final class ConnectivityServiceInitializer extends SystemService {
public void onStart() {
Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE);
publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity,
- /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
+ /* allowIsolated= */ false);
}
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 27b648e53a38..740a1c16a486 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -4553,6 +4553,13 @@ class StorageManagerService extends IStorageManager.Stub
private final List<StorageManagerInternal.ResetListener> mResetListeners =
new ArrayList<>();
+ @Override
+ public boolean isFuseMounted(int userId) {
+ synchronized (mLock) {
+ return mFuseMountedUser.contains(userId);
+ }
+ }
+
/**
* Check if fuse is running in target user, if it's running then setup its storage dirs.
* Return true if storage dirs are mounted.
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 978bd643f9b7..a9904ba0de91 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -964,14 +964,21 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
remove(r.binder);
}
}
- if (events.contains(TelephonyCallback.EVENT_CALL_STATE_CHANGED)) {
+ if (events.contains(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)) {
try {
- r.callback.onCallStateChanged(mCallState[phoneId],
+ r.callback.onLegacyCallStateChanged(mCallState[phoneId],
getCallIncomingNumber(r, phoneId));
} catch (RemoteException ex) {
remove(r.binder);
}
}
+ if (events.contains(TelephonyCallback.EVENT_CALL_STATE_CHANGED)) {
+ try {
+ r.callback.onCallStateChanged(mCallState[phoneId]);
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
if (events.contains(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED)) {
try {
r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
@@ -1306,13 +1313,24 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
for (Record r : mRecords) {
- if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)
+ if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)
&& (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
try {
// Ensure the listener has read call log permission; if they do not return
// an empty phone number.
+ // This is ONLY for legacy onCallStateChanged in PhoneStateListener.
String phoneNumberOrEmpty = r.canReadCallLog() ? phoneNumber : "";
- r.callback.onCallStateChanged(state, phoneNumberOrEmpty);
+ r.callback.onLegacyCallStateChanged(state, phoneNumberOrEmpty);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+
+ if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)
+ && (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
+ try {
+ // The new callback does NOT provide the phone number.
+ r.callback.onCallStateChanged(state);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
@@ -1341,12 +1359,25 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
mCallState[phoneId] = state;
mCallIncomingNumber[phoneId] = incomingNumber;
for (Record r : mRecords) {
- if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)
+ if (r.matchTelephonyCallbackEvent(
+ TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)
&& (r.subId == subId)
&& (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
try {
+ // Only the legacy PhoneStateListener receives the phone number.
String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId);
- r.callback.onCallStateChanged(state, incomingNumberOrEmpty);
+ r.callback.onLegacyCallStateChanged(state, incomingNumberOrEmpty);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)
+ && (r.subId == subId)
+ && (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
+ try {
+ // The phone number is not included in the new call state changed
+ // listener.
+ r.callback.onCallStateChanged(state);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index 55408ea61566..ee610671ff23 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -33,8 +33,8 @@ import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkProvider;
import android.net.RouteInfo;
-import android.net.StringNetworkSpecifier;
import android.net.TestNetworkInterface;
+import android.net.TestNetworkSpecifier;
import android.net.util.NetdService;
import android.os.Binder;
import android.os.Handler;
@@ -242,7 +242,7 @@ class TestNetworkService extends ITestNetworkManager.Stub {
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
- nc.setNetworkSpecifier(new StringNetworkSpecifier(iface));
+ nc.setNetworkSpecifier(new TestNetworkSpecifier(iface));
nc.setAdministratorUids(administratorUids);
if (!isMetered) {
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index f768db1d0821..68c4a7336745 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -20,7 +20,6 @@ import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND;
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
import static android.app.ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
-import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT;
import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -75,7 +74,6 @@ import android.app.ActivityManagerInternal;
import android.app.ActivityThread;
import android.app.AppGlobals;
import android.app.AppOpsManager;
-import android.app.BroadcastOptions;
import android.app.ForegroundServiceStartNotAllowedException;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
@@ -1217,7 +1215,18 @@ public final class ActiveServices {
void killMisbehavingService(ServiceRecord r,
int appUid, int appPid, String localPackageName) {
synchronized (mAm) {
- stopServiceLocked(r, false);
+ if (!r.destroying) {
+ // This service is still alive, stop it.
+ stopServiceLocked(r, false);
+ } else {
+ // Check if there is another instance of it being started in parallel,
+ // if so, stop that too to avoid spamming the system.
+ final ServiceMap smap = getServiceMapLocked(r.userId);
+ final ServiceRecord found = smap.mServicesByInstanceName.remove(r.instanceName);
+ if (found != null) {
+ stopServiceLocked(found, false);
+ }
+ }
mAm.crashApplication(appUid, appPid, localPackageName, -1,
"Bad notification for startForeground", true /*force*/);
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 38330fe770fb..ed8d696f98c4 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2315,11 +2315,12 @@ public final class ProcessList {
StorageManagerInternal storageManagerInternal = LocalServices.getService(
StorageManagerInternal.class);
if (needsStorageDataIsolation(storageManagerInternal, app)) {
- bindMountAppStorageDirs = true;
- if (pkgDataInfoMap == null ||
- !storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),
- app.processName)) {
- // Cannot prepare Android/app and Android/obb directory or inode == 0,
+ // We will run prepareStorageDirs() after we trigger zygote fork, so it won't
+ // slow down app starting speed as those dirs might not be cached.
+ if (pkgDataInfoMap != null && storageManagerInternal.isFuseMounted(userId)) {
+ bindMountAppStorageDirs = true;
+ } else {
+ // Fuse is not mounted or inode == 0,
// so we won't mount it in zygote, but resume the mount after unlocking device.
app.setBindMountPending(true);
bindMountAppStorageDirs = false;
@@ -2367,6 +2368,13 @@ public final class ProcessList {
allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
}
+ // This runs after Process.start() as this method may block app process starting time
+ // if dir is not cached. Running this method after Process.start() can make it
+ // cache the dir asynchronously, so zygote can use it without waiting for it.
+ if (bindMountAppStorageDirs) {
+ storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),
+ app.processName);
+ }
checkSlow(startTime, "startProcess: returned from zygote!");
return startResult;
} finally {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index caf2510e5b1c..ec2020f94969 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -122,7 +122,6 @@ import java.util.List;
import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Consumer;
/**
* Helper class for {@link ActivityManagerService} responsible for multi-user functionality.
@@ -518,18 +517,12 @@ class UserController implements Handler.Callback {
if (!mInjector.getUserManager().isPreCreated(userId)) {
mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
userId, 0));
- Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
- intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
- intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
- | Intent.FLAG_RECEIVER_OFFLOAD
- | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- mInjector.broadcastIntent(intent, null, resultTo, 0, null, null,
- new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
- AppOpsManager.OP_NONE,
- getTemporaryAppAllowlistBroadcastOptions(REASON_LOCKED_BOOT_COMPLETED)
- .toBundle(), true,
- false, MY_PID, SYSTEM_UID,
- Binder.getCallingUid(), Binder.getCallingPid(), userId);
+ // In case of headless system user mode, do not send boot complete broadcast for
+ // system user as it is sent by sendBootCompleted call.
+ if (!(UserManager.isHeadlessSystemUserMode() && uss.mHandle.isSystem())) {
+ // ACTION_LOCKED_BOOT_COMPLETED
+ sendLockedBootCompletedBroadcast(resultTo, userId);
+ }
}
}
@@ -552,6 +545,21 @@ class UserController implements Handler.Callback {
}
}
+ private void sendLockedBootCompletedBroadcast(IIntentReceiver receiver, @UserIdInt int userId) {
+ final Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+ intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
+ | Intent.FLAG_RECEIVER_OFFLOAD
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ mInjector.broadcastIntent(intent, null, receiver, 0, null, null,
+ new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
+ AppOpsManager.OP_NONE,
+ getTemporaryAppAllowlistBroadcastOptions(REASON_LOCKED_BOOT_COMPLETED)
+ .toBundle(), true,
+ false, MY_PID, SYSTEM_UID,
+ Binder.getCallingUid(), Binder.getCallingPid(), userId);
+ }
+
/**
* Step from {@link UserState#STATE_RUNNING_LOCKED} to
* {@link UserState#STATE_RUNNING_UNLOCKING}.
@@ -2167,26 +2175,22 @@ class UserController implements Handler.Callback {
}
void sendBootCompleted(IIntentReceiver resultTo) {
- final boolean systemUserFinishedBooting;
-
// Get a copy of mStartedUsers to use outside of lock
SparseArray<UserState> startedUsers;
synchronized (mLock) {
- systemUserFinishedBooting = mCurrentUserId != UserHandle.USER_SYSTEM;
startedUsers = mStartedUsers.clone();
}
for (int i = 0; i < startedUsers.size(); i++) {
UserState uss = startedUsers.valueAt(i);
- if (systemUserFinishedBooting && uss.mHandle.isSystem()) {
- // On Automotive, at this point the system user has already been started and
- // unlocked, and some of the tasks we do here have already been done. So skip those
- // in that case.
- // TODO(b/132262830): this workdound shouldn't be necessary once we move the
- // headless-user start logic to UserManager-land
- Slog.d(TAG, "sendBootCompleted(): skipping on non-current system user");
- continue;
+ if (!UserManager.isHeadlessSystemUserMode()) {
+ finishUserBoot(uss, resultTo);
+ } else if (uss.mHandle.isSystem()) {
+ // In case of headless system user mode, send only locked boot complete broadcast
+ // for system user since finishUserBoot call will be made using other code path;
+ // for non-system user, do nothing since finishUserBoot will be called elsewhere.
+ sendLockedBootCompletedBroadcast(resultTo, uss.mHandle.getIdentifier());
+ return;
}
- finishUserBoot(uss, resultTo);
}
}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 4a12ff6932de..6614e06aba8c 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -5276,8 +5276,12 @@ public class AppOpsService extends IAppOpsService.Stub {
pw.println(" Limit output to data associated with the given package name.");
pw.println(" --attributionTag [attributionTag]");
pw.println(" Limit output to data associated with the given attribution tag.");
+ pw.println(" --include-discrete [n]");
+ pw.println(" Include discrete ops limited to n per dimension. Use zero for no limit.");
pw.println(" --watchers");
pw.println(" Only output the watcher sections.");
+ pw.println(" --history");
+ pw.println(" Only output history.");
}
private void dumpStatesLocked(@NonNull PrintWriter pw, @Nullable String filterAttributionTag,
@@ -5412,10 +5416,12 @@ public class AppOpsService extends IAppOpsService.Stub {
boolean dumpWatchers = false;
// TODO ntmyren: Remove the dumpHistory and dumpFilter
boolean dumpHistory = false;
+ boolean includeDiscreteOps = false;
+ int nDiscreteOps = 10;
@HistoricalOpsRequestFilter int dumpFilter = 0;
if (args != null) {
- for (int i=0; i<args.length; i++) {
+ for (int i = 0; i < args.length; i++) {
String arg = args[i];
if ("-h".equals(arg)) {
dumpHelp(pw);
@@ -5473,7 +5479,22 @@ public class AppOpsService extends IAppOpsService.Stub {
}
} else if ("--watchers".equals(arg)) {
dumpWatchers = true;
- } else if (arg.length() > 0 && arg.charAt(0) == '-'){
+ } else if ("--include-discrete".equals(arg)) {
+ i++;
+ if (i >= args.length) {
+ pw.println("No argument for --include-discrete option");
+ return;
+ }
+ try {
+ nDiscreteOps = Integer.valueOf(args[i]);
+ } catch (NumberFormatException e) {
+ pw.println("Wrong parameter: " + args[i]);
+ return;
+ }
+ includeDiscreteOps = true;
+ } else if ("--history".equals(arg)) {
+ dumpHistory = true;
+ } else if (arg.length() > 0 && arg.charAt(0) == '-') {
pw.println("Unknown option: " + arg);
return;
} else {
@@ -5483,6 +5504,8 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}
+ final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ final Date date = new Date();
synchronized (this) {
pw.println("Current AppOps Service state:");
if (!dumpHistory && !dumpWatchers) {
@@ -5492,8 +5515,6 @@ public class AppOpsService extends IAppOpsService.Stub {
final long now = System.currentTimeMillis();
final long nowElapsed = SystemClock.elapsedRealtime();
final long nowUptime = SystemClock.uptimeMillis();
- final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
- final Date date = new Date();
boolean needSep = false;
if (dumpFilter == 0 && dumpMode < 0 && mProfileOwners != null && !dumpWatchers
&& !dumpHistory) {
@@ -5961,6 +5982,11 @@ public class AppOpsService extends IAppOpsService.Stub {
mHistoricalRegistry.dump(" ", pw, dumpUid, dumpPackage, dumpAttributionTag, dumpOp,
dumpFilter);
}
+ if (includeDiscreteOps) {
+ pw.println("Discrete accesses: ");
+ mHistoricalRegistry.dumpDiscreteData(pw, dumpUid, dumpPackage, dumpAttributionTag,
+ dumpFilter, dumpOp, sdf, date, " ", nDiscreteOps);
+ }
}
@Override
diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java
index a99d90883f87..ed62abc7d773 100644
--- a/services/core/java/com/android/server/appop/DiscreteRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java
@@ -23,9 +23,13 @@ import static android.app.AppOpsManager.FILTER_BY_UID;
import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.AppOpsManager.OP_COARSE_LOCATION;
import static android.app.AppOpsManager.OP_FINE_LOCATION;
+import static android.app.AppOpsManager.OP_FLAGS_ALL;
import static android.app.AppOpsManager.OP_FLAG_SELF;
import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
+import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
+import static android.app.AppOpsManager.flagsToString;
+import static android.app.AppOpsManager.getUidStateName;
import static java.lang.Math.max;
@@ -45,15 +49,20 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.XmlUtils;
+import libcore.util.EmptyArray;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Date;
import java.util.List;
/**
@@ -237,6 +246,23 @@ final class DiscreteRegistry {
}
}
+ void dump(@NonNull PrintWriter pw, int uidFilter, @Nullable String packageNameFilter,
+ @Nullable String attributionTagFilter,
+ @AppOpsManager.HistoricalOpsRequestFilter int filter, int dumpOp,
+ @NonNull SimpleDateFormat sdf, @NonNull Date date, @NonNull String prefix,
+ int nDiscreteOps) {
+ DiscreteOps discreteOps = new DiscreteOps();
+ synchronized (mOnDiskLock) {
+ writeAndClearAccessHistory();
+ String[] opNamesFilter = dumpOp == OP_NONE ? EmptyArray.STRING
+ : new String[]{AppOpsManager.opToPublicName(dumpOp)};
+ readDiscreteOpsFromDisk(discreteOps, 0, Instant.now().toEpochMilli(), filter,
+ uidFilter, packageNameFilter, opNamesFilter, attributionTagFilter,
+ OP_FLAGS_ALL);
+ }
+ discreteOps.dump(pw, sdf, date, prefix, nDiscreteOps);
+ }
+
public static boolean isDiscreteOp(int op, int uid, @AppOpsManager.OpFlags int flags) {
if (!isDiscreteOp(op)) {
return false;
@@ -306,6 +332,18 @@ final class DiscreteRegistry {
stream.close();
}
+ private void dump(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf,
+ @NonNull Date date, @NonNull String prefix, int nDiscreteOps) {
+ int nUids = mUids.size();
+ for (int i = 0; i < nUids; i++) {
+ pw.print(prefix);
+ pw.print("Uid: ");
+ pw.print(mUids.keyAt(i));
+ pw.println();
+ mUids.valueAt(i).dump(pw, sdf, date, prefix + " ", nDiscreteOps);
+ }
+ }
+
private DiscreteUidOps getOrCreateDiscreteUidOps(int uid) {
DiscreteUidOps result = mUids.get(uid);
if (result == null) {
@@ -395,6 +433,18 @@ final class DiscreteRegistry {
}
}
+ private void dump(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf,
+ @NonNull Date date, @NonNull String prefix, int nDiscreteOps) {
+ int nPackages = mPackages.size();
+ for (int i = 0; i < nPackages; i++) {
+ pw.print(prefix);
+ pw.print("Package: ");
+ pw.print(mPackages.keyAt(i));
+ pw.println();
+ mPackages.valueAt(i).dump(pw, sdf, date, prefix + " ", nDiscreteOps);
+ }
+ }
+
void deserialize(TypedXmlPullParser parser, long beginTimeMillis,
long endTimeMillis, @AppOpsManager.HistoricalOpsRequestFilter int filter,
@Nullable String packageNameFilter,
@@ -458,6 +508,17 @@ final class DiscreteRegistry {
}
}
+ private void dump(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf,
+ @NonNull Date date, @NonNull String prefix, int nDiscreteOps) {
+ int nOps = mPackageOps.size();
+ for (int i = 0; i < nOps; i++) {
+ pw.print(prefix);
+ pw.print(AppOpsManager.opToName(mPackageOps.keyAt(i)));
+ pw.println();
+ mPackageOps.valueAt(i).dump(pw, sdf, date, prefix + " ", nDiscreteOps);
+ }
+ }
+
void deserialize(TypedXmlPullParser parser, long beginTimeMillis, long endTimeMillis,
@AppOpsManager.HistoricalOpsRequestFilter int filter,
@Nullable String[] opNamesFilter, @Nullable String attributionTagFilter,
@@ -535,6 +596,24 @@ final class DiscreteRegistry {
}
}
+ private void dump(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf,
+ @NonNull Date date, @NonNull String prefix, int nDiscreteOps) {
+ int nAttributions = mAttributedOps.size();
+ for (int i = 0; i < nAttributions; i++) {
+ pw.print(prefix);
+ pw.print("Attribution: ");
+ pw.print(mAttributedOps.keyAt(i));
+ pw.println();
+ List<DiscreteOpEvent> ops = mAttributedOps.valueAt(i);
+ int nOps = ops.size();
+ int first = nDiscreteOps < 1 ? 0 : max(0, nOps - nDiscreteOps);
+ for (int j = first; j < nOps; j++) {
+ ops.get(j).dump(pw, sdf, date, prefix + " ");
+
+ }
+ }
+ }
+
void serialize(TypedXmlSerializer out) throws Exception {
int nAttributions = mAttributedOps.size();
for (int i = 0; i < nAttributions; i++) {
@@ -609,6 +688,24 @@ final class DiscreteRegistry {
mOpFlag = opFlag;
}
+ private void dump(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf,
+ @NonNull Date date, @NonNull String prefix) {
+ pw.print(prefix);
+ pw.print("Access [");
+ pw.print(getUidStateName(mUidState));
+ pw.print("-");
+ pw.print(flagsToString(mOpFlag));
+ pw.print("] at ");
+ date.setTime(mNoteTime);
+ pw.print(sdf.format(date));
+ if (mNoteDuration != -1) {
+ pw.print(" for ");
+ pw.print(mNoteDuration);
+ pw.print(" milliseconds ");
+ }
+ pw.println();
+ }
+
private void serialize(TypedXmlSerializer out) throws Exception {
out.attributeLong(null, ATTR_NOTE_TIME, mNoteTime);
if (mNoteDuration != -1) {
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 0fcf5ee35e11..22d628b8e789 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -349,6 +349,15 @@ final class HistoricalRegistry {
}
}
+ void dumpDiscreteData(@NonNull PrintWriter pw, int uidFilter,
+ @Nullable String packageNameFilter, @Nullable String attributionTagFilter,
+ @HistoricalOpsRequestFilter int filter, int dumpOp,
+ @NonNull SimpleDateFormat sdf, @NonNull Date date, @NonNull String prefix,
+ int nDiscreteOps) {
+ mDiscreteRegistry.dump(pw, uidFilter, packageNameFilter, attributionTagFilter, filter,
+ dumpOp, sdf, date, prefix, nDiscreteOps);
+ }
+
@HistoricalMode int getMode() {
synchronized (mInMemoryLock) {
return mMode;
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 050b28b363d2..285f3185abc2 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -406,26 +406,49 @@ public class AuthService extends SystemService {
mBiometricService.getCurrentModality(
opPackageName, userId, callingUserId, authenticators);
+ final boolean isCredentialAllowed = Utils.isCredentialRequested(authenticators);
+
final String result;
switch (getCredentialBackupModality(modality)) {
case BiometricAuthenticator.TYPE_NONE:
result = null;
break;
+
case BiometricAuthenticator.TYPE_CREDENTIAL:
result = getContext().getString(
R.string.screen_lock_dialog_default_subtitle);
break;
+
case BiometricAuthenticator.TYPE_FINGERPRINT:
- result = getContext().getString(
- R.string.fingerprint_dialog_default_subtitle);
+ if (isCredentialAllowed) {
+ result = getContext().getString(
+ R.string.fingerprint_or_screen_lock_dialog_default_subtitle);
+ } else {
+ result = getContext().getString(
+ R.string.fingerprint_dialog_default_subtitle);
+ }
break;
+
case BiometricAuthenticator.TYPE_FACE:
- result = getContext().getString(R.string.face_dialog_default_subtitle);
+ if (isCredentialAllowed) {
+ result = getContext().getString(
+ R.string.face_or_screen_lock_dialog_default_subtitle);
+ } else {
+ result = getContext().getString(R.string.face_dialog_default_subtitle);
+ }
break;
+
default:
- result = getContext().getString(R.string.biometric_dialog_default_subtitle);
+ if (isCredentialAllowed) {
+ result = getContext().getString(
+ R.string.biometric_or_screen_lock_dialog_default_subtitle);
+ } else {
+ result = getContext().getString(
+ R.string.biometric_dialog_default_subtitle);
+ }
break;
}
+
return result;
} finally {
Binder.restoreCallingIdentity(identity);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java
index b4c9b290cd06..4ca85d000d19 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestHal.java
@@ -139,8 +139,4 @@ public class TestHal extends IFace.Stub {
}
};
}
-
- @Override
- public void reset() {
- }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java
index 8547a689dfb1..0b7f3abc9005 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestHal.java
@@ -140,9 +140,5 @@ public class TestHal extends IFingerprint.Stub {
}
};
}
-
- @Override
- public void reset() {
- }
}
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 7dfecd56eaf5..e0d1375b4069 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -57,9 +57,11 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.view.autofill.AutofillManagerInternal;
import android.widget.Toast;
+import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -273,6 +275,9 @@ public class ClipboardService extends SystemService {
/** Package of the app that set {@link #primaryClip}. */
String mPrimaryClipPackage;
+ /** Uids that have already triggered a toast notification for {@link #primaryClip} */
+ final SparseBooleanArray mNotifiedUids = new SparseBooleanArray();
+
final HashSet<String> activePermissionOwners
= new HashSet<String>();
@@ -648,6 +653,7 @@ public class ClipboardService extends SystemService {
return;
}
clipboard.primaryClip = clip;
+ clipboard.mNotifiedUids.clear();
if (clip != null) {
clipboard.primaryClipUid = uid;
clipboard.mPrimaryClipPackage = sourcePackage;
@@ -938,6 +944,11 @@ public class ClipboardService extends SystemService {
&& mAutofillInternal.isAugmentedAutofillServiceForUser(uid, userId)) {
return;
}
+ // Don't notify if already notified for this uid and clip.
+ if (clipboard.mNotifiedUids.get(uid)) {
+ return;
+ }
+ clipboard.mNotifiedUids.put(uid, true);
// Retrieve the app label of the source of the clip data
CharSequence sourceAppLabel = null;
@@ -955,9 +966,10 @@ public class ClipboardService extends SystemService {
mPm.getApplicationInfoAsUser(callingPackage, 0, userId));
String message;
if (sourceAppLabel != null) {
- message = callingAppLabel + " pasted from " + sourceAppLabel;
+ message = getContext().getString(
+ R.string.pasted_from_app, callingAppLabel, sourceAppLabel);
} else {
- message = callingAppLabel + " pasted from clipboard";
+ message = getContext().getString(R.string.pasted_from_clipboard, callingAppLabel);
}
Slog.i(TAG, message);
Binder.withCleanCallingIdentity(() ->
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index fa80b25f9026..c66a280f2b02 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -16,6 +16,8 @@
package com.android.server.connectivity;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+
import static com.android.net.module.util.CollectionUtils.contains;
import android.annotation.NonNull;
@@ -35,6 +37,7 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.net.module.util.NetworkStackConstants;
+import com.android.server.ConnectivityService;
import java.net.Inet6Address;
import java.util.Objects;
@@ -94,12 +97,15 @@ public class Nat464Xlat {
private Inet6Address mIPv6Address;
private State mState = State.IDLE;
+ private boolean mEnableClatOnCellular;
private boolean mPrefixDiscoveryRunning;
- public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver) {
+ public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver,
+ ConnectivityService.Dependencies deps) {
mDnsResolver = dnsResolver;
mNetd = netd;
mNetwork = nai;
+ mEnableClatOnCellular = deps.getCellular464XlatEnabled();
}
/**
@@ -111,7 +117,7 @@ public class Nat464Xlat {
* @return true if the network requires clat, false otherwise.
*/
@VisibleForTesting
- protected static boolean requiresClat(NetworkAgentInfo nai) {
+ protected boolean requiresClat(NetworkAgentInfo nai) {
// TODO: migrate to NetworkCapabilities.TRANSPORT_*.
final boolean supported = contains(NETWORK_TYPES, nai.networkInfo.getType());
final boolean connected = contains(NETWORK_STATES, nai.networkInfo.getState());
@@ -126,7 +132,9 @@ public class Nat464Xlat {
final boolean skip464xlat = (nai.netAgentConfig() != null)
&& nai.netAgentConfig().skip464xlat;
- return supported && connected && isIpv6OnlyNetwork && !skip464xlat;
+ return supported && connected && isIpv6OnlyNetwork && !skip464xlat
+ && (nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)
+ ? isCellular464XlatEnabled() : true);
}
/**
@@ -137,7 +145,7 @@ public class Nat464Xlat {
* @return true if the network should start clat, false otherwise.
*/
@VisibleForTesting
- protected static boolean shouldStartClat(NetworkAgentInfo nai) {
+ protected boolean shouldStartClat(NetworkAgentInfo nai) {
LinkProperties lp = nai.linkProperties;
return requiresClat(nai) && lp != null && lp.getNat64Prefix() != null;
}
@@ -507,4 +515,9 @@ public class Nat464Xlat {
protected int getNetId() {
return mNetwork.network.getNetId();
}
+
+ @VisibleForTesting
+ protected boolean isCellular464XlatEnabled() {
+ return mEnableClatOnCellular;
+ }
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 1d0e11569c80..803cc9d31c35 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -341,7 +341,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
@NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, int score, Context context,
Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid,
- QosCallbackTracker qosCallbackTracker) {
+ QosCallbackTracker qosCallbackTracker, ConnectivityService.Dependencies deps) {
Objects.requireNonNull(net);
Objects.requireNonNull(info);
Objects.requireNonNull(lp);
@@ -355,7 +355,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
linkProperties = lp;
networkCapabilities = nc;
mScore = score;
- clatd = new Nat464Xlat(this, netd, dnsResolver);
+ clatd = new Nat464Xlat(this, netd, dnsResolver, deps);
mConnService = connService;
mContext = context;
mHandler = handler;
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index d6826be248df..fcfa674dcc4e 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -357,7 +357,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
for (int i = mDisplayGroups.size() - 1; i >= 0; i--) {
final int groupId = mDisplayGroups.keyAt(i);
final DisplayGroup group = mDisplayGroups.valueAt(i);
- final boolean wasPreviouslyUpdated = mUpdatedDisplayGroups.indexOfKey(groupId) < 0;
+ final boolean wasPreviouslyUpdated = mUpdatedDisplayGroups.indexOfKey(groupId) > -1;
final int changeCount = group.getChangeCountLocked();
if (group.isEmptyLocked()) {
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index d2baaf2228a1..0ba191c0762f 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -91,6 +91,10 @@ final class WifiDisplayAdapter extends DisplayAdapter {
private boolean mPendingStatusChangeBroadcast;
+ private static final String[] RECEIVER_PERMISSIONS_FOR_BROADCAST = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ };
+
// Called with SyncRoot lock held.
public WifiDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener,
@@ -432,7 +436,8 @@ final class WifiDisplayAdapter extends DisplayAdapter {
}
// Send protected broadcast about wifi display status to registered receivers.
- getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
+ getContext().createContextAsUser(UserHandle.ALL, 0)
+ .sendBroadcastWithMultiplePermissions(intent, RECEIVER_PERMISSIONS_FOR_BROADCAST);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
index 900ec905609f..06adce81d8a1 100644
--- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
@@ -37,11 +37,11 @@ import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.graphics.fonts.IFontManager;
+import com.android.internal.security.VerityUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.SystemService;
-import com.android.server.security.VerityUtils;
import java.io.File;
import java.io.FileDescriptor;
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index 02b09b15b464..73ecbe0432b7 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -20,6 +20,7 @@ import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
import android.hardware.hdmi.IHdmiControlCallback;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
/**
* Feature action that performs one touch play against TV/Display device. This action is initiated
@@ -40,13 +41,15 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
// standby mode, and do not accept the command until their power status becomes 'ON'.
// For a workaround, we send <Give Device Power Status> commands periodically to make sure
// the device switches its status to 'ON'. Then we send additional <Active Source>.
- private static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1;
+ @VisibleForTesting
+ static final int STATE_WAITING_FOR_REPORT_POWER_STATUS = 1;
// The maximum number of times we send <Give Device Power Status> before we give up.
// We wait up to RESPONSE_TIMEOUT_MS * LOOP_COUNTER_MAX = 20 seconds.
private static final int LOOP_COUNTER_MAX = 10;
private final int mTargetAddress;
+ private final boolean mIsCec20;
private int mPowerStatusCounter = 0;
@@ -65,8 +68,19 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
private OneTouchPlayAction(HdmiCecLocalDevice localDevice, int targetAddress,
IHdmiControlCallback callback) {
+ this(localDevice, targetAddress, callback,
+ localDevice.getDeviceInfo().getCecVersion()
+ >= HdmiControlManager.HDMI_CEC_VERSION_2_0
+ && localDevice.mService.getHdmiCecNetwork().getCecDeviceInfo(
+ targetAddress).getCecVersion() >= HdmiControlManager.HDMI_CEC_VERSION_2_0);
+ }
+
+ @VisibleForTesting
+ OneTouchPlayAction(HdmiCecLocalDevice localDevice, int targetAddress,
+ IHdmiControlCallback callback, boolean isCec20) {
super(localDevice, callback);
mTargetAddress = targetAddress;
+ mIsCec20 = isCec20;
}
@Override
@@ -74,6 +88,9 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
// Because only source device can create this action, it's safe to cast.
mSource = source();
sendCommand(HdmiCecMessageBuilder.buildTextViewOn(getSourceAddress(), mTargetAddress));
+ boolean targetOnBefore = localDevice().mService.getHdmiCecNetwork()
+ .getCecDeviceInfo(mTargetAddress).getDevicePowerStatus()
+ == HdmiControlManager.POWER_STATUS_ON;
broadcastActiveSource();
// If the device is not an audio system itself, request the connected audio system to
// turn on.
@@ -81,7 +98,20 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
sendCommand(HdmiCecMessageBuilder.buildSystemAudioModeRequest(getSourceAddress(),
Constants.ADDR_AUDIO_SYSTEM, getSourcePath(), true));
}
- queryDevicePowerStatus();
+ int targetPowerStatus = localDevice().mService.getHdmiCecNetwork()
+ .getCecDeviceInfo(mTargetAddress).getDevicePowerStatus();
+ if (!mIsCec20 || targetPowerStatus == HdmiControlManager.POWER_STATUS_UNKNOWN) {
+ queryDevicePowerStatus();
+ } else if (targetPowerStatus == HdmiControlManager.POWER_STATUS_ON) {
+ if (!targetOnBefore) {
+ // Suppress 2nd <Active Source> message if the target device was already on when
+ // the 1st one was sent.
+ broadcastActiveSource();
+ }
+ finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
+ return true;
+ }
+ mState = STATE_WAITING_FOR_REPORT_POWER_STATUS;
addTimer(mState, HdmiConfig.TIMEOUT_MS);
return true;
}
@@ -101,7 +131,6 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
}
private void queryDevicePowerStatus() {
- mState = STATE_WAITING_FOR_REPORT_POWER_STATUS;
sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(),
mTargetAddress));
}
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
index f7e871d0b645..56e538b1abfa 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
@@ -17,6 +17,8 @@
package com.android.server.hdmi;
import android.hardware.tv.cec.V1_0.SendMessageResult;
+
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
/**
@@ -30,6 +32,14 @@ final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {
// <Give System Audio Mode Status> to AV Receiver.
private static final int STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS = 1;
+ @VisibleForTesting
+ static final int RETRIES_ON_TIMEOUT = 1;
+
+ // On some audio devices the <System Audio Mode Status> message can be delayed as the device
+ // is just waking up. Retry the <Give System Audio Mode Status> message to ensure we properly
+ // initialize system audio.
+ private int mRetriesOnTimeOut = RETRIES_ON_TIMEOUT;
+
SystemAudioAutoInitiationAction(HdmiCecLocalDevice source, int avrAddress) {
super(source);
mAvrAddress = avrAddress;
@@ -100,6 +110,13 @@ final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {
switch (mState) {
case STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS:
+ if (mRetriesOnTimeOut > 0) {
+ mRetriesOnTimeOut--;
+ addTimer(mState, HdmiConfig.TIMEOUT_MS);
+ sendGiveSystemAudioModeStatus();
+ return;
+ }
+
handleSystemAudioModeStatusTimeout();
break;
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index edb5d97f1a5a..7dc9a0b2a364 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -586,18 +586,13 @@ public class InputManagerService extends IInputManager.Stub
private void setDisplayViewportsInternal(List<DisplayViewport> viewports) {
final DisplayViewport[] vArray = new DisplayViewport[viewports.size()];
if (ENABLE_PER_WINDOW_INPUT_ROTATION) {
- // Remove all viewport operations. They will be built-into the window transforms.
+ // Remove display projection information from DisplayViewport, leaving only the
+ // orientation. The display projection will be built-into the window transforms.
for (int i = viewports.size() - 1; i >= 0; --i) {
final DisplayViewport v = vArray[i] = viewports.get(i).makeCopy();
- // deviceWidth/Height are apparently in "rotated" space, so flip them if needed.
- if (v.orientation % 2 != 0) {
- final int dw = v.deviceWidth;
- v.deviceWidth = v.deviceHeight;
- v.deviceHeight = dw;
- }
+ // Note: the deviceWidth/Height are in rotated with the orientation.
v.logicalFrame.set(0, 0, v.deviceWidth, v.deviceHeight);
v.physicalFrame.set(0, 0, v.deviceWidth, v.deviceHeight);
- v.orientation = 0;
}
} else {
for (int i = viewports.size() - 1; i >= 0; --i) {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 8285e32ed8db..a89cb5554825 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2621,8 +2621,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
if (DEBUG) Slog.v(TAG, "Initiating attach with token: " + mCurToken);
// Dispatch display id for InputMethodService to update context display.
- executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO(
- MSG_INITIALIZE_IME, mCurTokenDisplayId, mCurMethod, mCurToken));
+ executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOOO(
+ MSG_INITIALIZE_IME, mCurTokenDisplayId, mCurMethod, mCurToken,
+ mMethodMap.get(mCurMethodId).getConfigChanges()));
scheduleNotifyImeUidToAudioService(mCurMethodUid);
if (mCurClient != null) {
clearClientSessionLocked(mCurClient);
@@ -4478,7 +4479,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
final IBinder token = (IBinder) args.arg2;
((IInputMethod) args.arg1).initializeInternal(token, msg.arg1,
- new InputMethodPrivilegedOperationsImpl(this, token));
+ new InputMethodPrivilegedOperationsImpl(this, token),
+ (int) args.arg3);
} catch (RemoteException e) {
}
args.recycle();
diff --git a/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java b/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
index dbd8dd9eff3b..aa3e5795b684 100644
--- a/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
+++ b/services/core/java/com/android/server/location/injector/SystemEmergencyHelper.java
@@ -82,7 +82,7 @@ public class SystemEmergencyHelper extends EmergencyHelper {
TelephonyCallback.CallStateListener{
@Override
- public void onCallStateChanged(int state, String incomingNumber) {
+ public void onCallStateChanged(int state) {
if (state == TelephonyManager.CALL_STATE_IDLE) {
if (mIsInEmergencyCall) {
mEmergencyCallEndRealtimeMs = SystemClock.elapsedRealtime();
diff --git a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
index 82b0f9c05b6b..6d250ecb9fa4 100644
--- a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
+++ b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
@@ -135,7 +135,11 @@ public class BiometricDeferredQueue {
}
sensorIds.remove(sensorId);
- faceManager.revokeChallenge(sensorId);
+ // Challenge is only required for IBiometricsFace@1.0 (and not IFace AIDL). The
+ // IBiometricsFace@1.0 HAL does not require userId to revokeChallenge, so passing
+ // in 0 is OK.
+ final int userId = 0;
+ faceManager.revokeChallenge(sensorId, userId, challenge);
if (sensorIds.isEmpty()) {
Slog.d(TAG, "Done requesting resetLockout for all face sensors");
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 48382a946d4b..6e99cba6ea91 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -64,6 +64,8 @@ class RebootEscrowManager {
@VisibleForTesting
public static final String REBOOT_ESCROW_ARMED_KEY = "reboot_escrow_armed_count";
+ static final String REBOOT_ESCROW_KEY_ARMED_TIMESTAMP = "reboot_escrow_key_stored_timestamp";
+
/**
* Number of boots until we consider the escrow data to be stale for the purposes of metrics.
* <p>
@@ -144,8 +146,7 @@ class RebootEscrowManager {
private RebootEscrowProviderInterface createRebootEscrowProvider() {
RebootEscrowProviderInterface rebootEscrowProvider;
- if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA,
- "server_based_ror_enabled", false)) {
+ if (serverBasedResumeOnReboot()) {
Slog.i(TAG, "Using server based resume on reboot");
rebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(mContext, mStorage);
} else {
@@ -166,6 +167,11 @@ class RebootEscrowManager {
handler.postDelayed(runnable, delayMillis);
}
+ public boolean serverBasedResumeOnReboot() {
+ return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA,
+ "server_based_ror_enabled", false);
+ }
+
public Context getContext() {
return mContext;
}
@@ -204,10 +210,12 @@ class RebootEscrowManager {
DEFAULT_LOAD_ESCROW_DATA_RETRY_INTERVAL_SECONDS);
}
- public void reportMetric(boolean success) {
- // TODO(b/179105110) design error code; and report the true value for other fields.
- FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, 0, 1, 1,
- -1, 0, -1);
+ public void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
+ int escrowDurationInSeconds, int vbmetaDigestStatus,
+ int durationSinceBootCompleteInSeconds) {
+ FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, success,
+ errorCode, serviceType, attemptCount, escrowDurationInSeconds,
+ vbmetaDigestStatus, durationSinceBootCompleteInSeconds);
}
public RebootEscrowEventLog getEventLog() {
@@ -230,7 +238,7 @@ class RebootEscrowManager {
mKeyStoreManager = injector.getKeyStoreManager();
}
- private void onGetRebootEscrowKeyFailed(List<UserInfo> users) {
+ private void onGetRebootEscrowKeyFailed(List<UserInfo> users, int attemptCount) {
Slog.w(TAG, "Had reboot escrow data for users, but no key; removing escrow storage.");
for (UserInfo user : users) {
mStorage.removeRebootEscrow(user.id);
@@ -238,7 +246,7 @@ class RebootEscrowManager {
// Clear the old key in keystore.
mKeyStoreManager.clearKeyStoreEncryptionKey();
- onEscrowRestoreComplete(false);
+ onEscrowRestoreComplete(false, attemptCount);
}
void loadRebootEscrowDataIfAvailable(Handler retryHandler) {
@@ -251,6 +259,8 @@ class RebootEscrowManager {
}
if (rebootEscrowUsers.isEmpty()) {
+ Slog.i(TAG, "No reboot escrow data found for users,"
+ + " skipping loading escrow data");
return;
}
@@ -274,7 +284,7 @@ class RebootEscrowManager {
}
Slog.w(TAG, "Failed to load reboot escrow data after " + attemptNumber + " attempts");
- onGetRebootEscrowKeyFailed(users);
+ onGetRebootEscrowKeyFailed(users, attemptNumber);
}
void loadRebootEscrowDataWithRetry(Handler retryHandler, int attemptNumber,
@@ -297,7 +307,7 @@ class RebootEscrowManager {
}
if (escrowKey == null) {
- onGetRebootEscrowKeyFailed(users);
+ onGetRebootEscrowKeyFailed(users, attemptNumber + 1);
return;
}
@@ -311,16 +321,35 @@ class RebootEscrowManager {
// Clear the old key in keystore. A new key will be generated by new RoR requests.
mKeyStoreManager.clearKeyStoreEncryptionKey();
- onEscrowRestoreComplete(allUsersUnlocked);
+ onEscrowRestoreComplete(allUsersUnlocked, attemptNumber + 1);
+ }
+
+ private void reportMetricOnRestoreComplete(boolean success, int attemptCount) {
+ int serviceType = mInjector.serverBasedResumeOnReboot()
+ ? FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED__TYPE__SERVER_BASED
+ : FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED__TYPE__HAL;
+
+ long armedTimestamp = mStorage.getLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, -1,
+ USER_SYSTEM);
+ mStorage.removeKey(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, USER_SYSTEM);
+ int escrowDurationInSeconds = armedTimestamp != -1
+ ? (int) (System.currentTimeMillis() - armedTimestamp) / 1000 : -1;
+
+ // TODO(b/179105110) design error code; and report the true value for other fields.
+ int vbmetaDigestStatus = FrameworkStatsLog
+ .REBOOT_ESCROW_RECOVERY_REPORTED__VBMETA_DIGEST_STATUS__MATCH_EXPECTED_SLOT;
+
+ mInjector.reportMetric(success, 0 /* error code */, serviceType, attemptCount,
+ escrowDurationInSeconds, vbmetaDigestStatus, -1);
}
- private void onEscrowRestoreComplete(boolean success) {
+ private void onEscrowRestoreComplete(boolean success, int attemptCount) {
int previousBootCount = mStorage.getInt(REBOOT_ESCROW_ARMED_KEY, -1, USER_SYSTEM);
mStorage.removeKey(REBOOT_ESCROW_ARMED_KEY, USER_SYSTEM);
int bootCountDelta = mInjector.getBootCount() - previousBootCount;
if (success || (previousBootCount != -1 && bootCountDelta <= BOOT_COUNT_TOLERANCE)) {
- mInjector.reportMetric(success);
+ reportMetricOnRestoreComplete(success, attemptCount);
}
}
@@ -476,6 +505,8 @@ class RebootEscrowManager {
boolean armedRebootEscrow = rebootEscrowProvider.storeRebootEscrowKey(escrowKey, kk);
if (armedRebootEscrow) {
mStorage.setInt(REBOOT_ESCROW_ARMED_KEY, mInjector.getBootCount(), USER_SYSTEM);
+ mStorage.setLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, System.currentTimeMillis(),
+ USER_SYSTEM);
mEventLog.addEntry(RebootEscrowEvent.SET_ARMED_STATUS);
}
diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING
index c1cba5f7f22d..4a216ca90f9b 100644
--- a/services/core/java/com/android/server/locksettings/TEST_MAPPING
+++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING
@@ -10,6 +10,17 @@
"exclude-annotation": "android.platform.test.annotations.FlakyTest"
}
]
+ },
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.locksettings."
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ }
+ ]
}
]
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java
index 35571f1f2728..e75aae1f99aa 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformDecryptionKey.java
@@ -16,7 +16,7 @@
package com.android.server.locksettings.recoverablekeystore;
-import android.security.keystore.AndroidKeyStoreSecretKey;
+import javax.crypto.SecretKey;
/**
* Used to unwrap recoverable keys before syncing them with remote storage.
@@ -30,7 +30,7 @@ import android.security.keystore.AndroidKeyStoreSecretKey;
public class PlatformDecryptionKey {
private final int mGenerationId;
- private final AndroidKeyStoreSecretKey mKey;
+ private final SecretKey mKey;
/**
* A new instance.
@@ -40,7 +40,7 @@ public class PlatformDecryptionKey {
*
* @hide
*/
- public PlatformDecryptionKey(int generationId, AndroidKeyStoreSecretKey key) {
+ public PlatformDecryptionKey(int generationId, SecretKey key) {
mGenerationId = generationId;
mKey = key;
}
@@ -59,7 +59,7 @@ public class PlatformDecryptionKey {
*
* @hide
*/
- public AndroidKeyStoreSecretKey getKey() {
+ public SecretKey getKey() {
return mKey;
}
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java
index 38f5b45ea190..ee334462f7be 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformEncryptionKey.java
@@ -16,7 +16,7 @@
package com.android.server.locksettings.recoverablekeystore;
-import android.security.keystore.AndroidKeyStoreSecretKey;
+import javax.crypto.SecretKey;
/**
* Private key stored in AndroidKeyStore. Used to wrap recoverable keys before writing them to disk.
@@ -33,7 +33,7 @@ import android.security.keystore.AndroidKeyStoreSecretKey;
public class PlatformEncryptionKey {
private final int mGenerationId;
- private final AndroidKeyStoreSecretKey mKey;
+ private final SecretKey mKey;
/**
* A new instance.
@@ -41,7 +41,7 @@ public class PlatformEncryptionKey {
* @param generationId The generation ID of the key.
* @param key The secret key handle. Can be used to encrypt WITHOUT requiring screen unlock.
*/
- public PlatformEncryptionKey(int generationId, AndroidKeyStoreSecretKey key) {
+ public PlatformEncryptionKey(int generationId, SecretKey key) {
mGenerationId = generationId;
mKey = key;
}
@@ -56,7 +56,7 @@ public class PlatformEncryptionKey {
/**
* Returns the actual key, which can only be used to encrypt.
*/
- public AndroidKeyStoreSecretKey getKey() {
+ public SecretKey getKey() {
return mKey;
}
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
index f448a6ef8c0b..f32af5434c43 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
@@ -21,7 +21,6 @@ import android.content.Context;
import android.os.RemoteException;
import android.os.UserHandle;
import android.security.GateKeeper;
-import android.security.keystore.AndroidKeyStoreSecretKey;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
@@ -237,7 +236,7 @@ public class PlatformKeyManager {
if (!isKeyLoaded(userId, generationId)) {
throw new UnrecoverableKeyException("KeyStore doesn't contain key " + alias);
}
- AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
+ SecretKey key = (SecretKey) mKeyStore.getKey(
alias, /*password=*/ null);
return new PlatformEncryptionKey(generationId, key);
}
@@ -289,7 +288,7 @@ public class PlatformKeyManager {
if (!isKeyLoaded(userId, generationId)) {
throw new UnrecoverableKeyException("KeyStore doesn't contain key " + alias);
}
- AndroidKeyStoreSecretKey key = (AndroidKeyStoreSecretKey) mKeyStore.getKey(
+ SecretKey key = (SecretKey) mKeyStore.getKey(
alias, /*password=*/ null);
return new PlatformDecryptionKey(generationId, key);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6f39fea5dd95..0cc9f9e150c6 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -134,7 +134,6 @@ import android.app.AlarmManager;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.AutomaticZenRule;
-import android.app.BroadcastOptions;
import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.ITransientNotification;
@@ -6082,6 +6081,17 @@ public class NotificationManagerService extends SystemService {
}
}
+ // Ensure CallStyle has all the correct actions
+ if ("android.app.Notification$CallStyle".equals(
+ notification.extras.getString(Notification.EXTRA_TEMPLATE))) {
+ Notification.Builder builder =
+ Notification.Builder.recoverBuilder(getContext(), notification);
+ Notification.CallStyle style = (Notification.CallStyle) builder.getStyle();
+ List<Notification.Action> actions = style.getActionsListWithSystemActions();
+ notification.actions = new Notification.Action[actions.size()];
+ actions.toArray(notification.actions);
+ }
+
// Remote views? Are they too big?
checkRemoteViews(pkg, tag, id, notification);
}
diff --git a/services/core/java/com/android/server/pm/ApkChecksums.java b/services/core/java/com/android/server/pm/ApkChecksums.java
index 66ea55401cef..afce23fe7647 100644
--- a/services/core/java/com/android/server/pm/ApkChecksums.java
+++ b/services/core/java/com/android/server/pm/ApkChecksums.java
@@ -59,8 +59,8 @@ import android.util.apk.SignatureNotFoundException;
import android.util.apk.VerityBuilder;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.security.VerityUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;
-import com.android.server.security.VerityUtils;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index d3a56c6f67c0..044e186140a4 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -70,6 +70,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IInterface;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -114,6 +115,7 @@ public class LauncherAppsService extends SystemService {
@Override
public void onStart() {
publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl);
+ mLauncherAppsImpl.registerLoadingProgressForIncrementalApps();
}
static class BroadcastCookie {
@@ -1184,6 +1186,30 @@ public class LauncherAppsService extends SystemService {
mCallbackHandler.post(r);
}
+ /**
+ * Check all installed apps and if a package is installed via Incremental and not fully
+ * loaded, register loading progress listener.
+ */
+ void registerLoadingProgressForIncrementalApps() {
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ final List<UserHandle> users = mUm.getUserProfiles();
+ if (users == null) {
+ return;
+ }
+ for (UserHandle user : users) {
+ pmInt.forEachInstalledPackage(pkg -> {
+ final String packageName = pkg.getPackageName();
+ if (pmInt.getIncrementalStatesInfo(packageName, Process.myUid(),
+ user.getIdentifier()).isLoading()) {
+ pmInt.registerInstalledLoadingProgressCallback(packageName,
+ new PackageLoadingProgressCallback(packageName, user),
+ user.getIdentifier());
+ }
+ }, user.getIdentifier());
+ }
+ }
+
public static class ShortcutChangeHandler implements LauncherApps.ShortcutChangeCallback {
private final UserManagerInternal mUserManagerInternal;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 903652ab76a5..58e2aa2b7602 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -138,6 +138,7 @@ import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.content.PackageHelper;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.os.SomeArgs;
+import com.android.internal.security.VerityUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
@@ -146,7 +147,6 @@ import com.android.server.LocalServices;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.parsing.pkg.AndroidPackage;
-import com.android.server.security.VerityUtils;
import libcore.io.IoUtils;
import libcore.util.EmptyArray;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index bc991634fb07..ff87f1c4b4ca 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -349,6 +349,7 @@ import com.android.internal.content.om.OverlayConfig;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.SomeArgs;
import com.android.internal.policy.AttributeCache;
+import com.android.internal.security.VerityUtils;
import com.android.internal.telephony.CarrierAppUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
@@ -401,7 +402,6 @@ import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy;
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV1;
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV2;
import com.android.server.rollback.RollbackManagerInternal;
-import com.android.server.security.VerityUtils;
import com.android.server.storage.DeviceStorageMonitorInternal;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.utils.TimingsTraceAndSlog;
@@ -1979,6 +1979,8 @@ public class PackageManagerService extends IPackageManager.Stub
@Nullable ComponentName component, @ComponentType int componentType, int userId);
boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
int userId);
+ boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
+ int userId);
int bestDomainVerificationStatus(int status1, int status2);
int checkUidPermission(String permName, int uid);
int getPackageUidInternal(String packageName, int flags, int userId, int callingUid);
@@ -4143,6 +4145,19 @@ public class PackageManagerService extends IPackageManager.Stub
}
/**
+ * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
+ */
+ public boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
+ int userId) {
+ boolean filterApp = true;
+ for (int index = sus.packages.size() - 1; index >= 0 && filterApp; index--) {
+ filterApp &= shouldFilterApplicationLocked(sus.packages.valueAt(index),
+ callingUid, /* component */ null, TYPE_UNKNOWN, userId);
+ }
+ return filterApp;
+ }
+
+ /**
* Verification statuses are ordered from the worse to the best, except for
* INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
*/
@@ -4482,6 +4497,10 @@ public class PackageManagerService extends IPackageManager.Stub
break;
}
+ case DumpState.DUMP_PREFERRED:
+ mSettings.dumpPreferred(pw, dumpState, packageName);
+ break;
+
case DumpState.DUMP_PREFERRED_XML:
{
pw.flush();
@@ -7900,6 +7919,15 @@ public class PackageManagerService extends IPackageManager.Stub
ps, callingUid, userId);
}
+ /**
+ * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
+ */
+ @GuardedBy("mLock")
+ private boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
+ int userId) {
+ return liveComputer().shouldFilterApplicationLocked(sus, callingUid, userId);
+ }
+
@GuardedBy("mLock")
private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
int flags) {
@@ -8966,7 +8994,6 @@ public class PackageManagerService extends IPackageManager.Stub
public int checkUidSignatures(int uid1, int uid2) {
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
- final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
// Map to base uids.
final int appId1 = UserHandle.getAppId(uid1);
final int appId2 = UserHandle.getAppId(uid2);
@@ -8977,10 +9004,11 @@ public class PackageManagerService extends IPackageManager.Stub
Object obj = mSettings.getSettingLPr(appId1);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
- if (isCallerInstantApp) {
+ final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
- p1SigningDetails = ((SharedUserSetting) obj).signatures.mSigningDetails;
+ p1SigningDetails = sus.signatures.mSigningDetails;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
@@ -8996,10 +9024,11 @@ public class PackageManagerService extends IPackageManager.Stub
obj = mSettings.getSettingLPr(appId2);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
- if (isCallerInstantApp) {
+ final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
- p2SigningDetails = ((SharedUserSetting) obj).signatures.mSigningDetails;
+ p2SigningDetails = sus.signatures.mSigningDetails;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
@@ -9088,11 +9117,11 @@ public class PackageManagerService extends IPackageManager.Stub
final Object obj = mSettings.getSettingLPr(appId);
if (obj != null) {
if (obj instanceof SharedUserSetting) {
- final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
- if (isCallerInstantApp) {
+ final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
return false;
}
- signingDetails = ((SharedUserSetting)obj).signatures.mSigningDetails;
+ signingDetails = sus.signatures.mSigningDetails;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
@@ -9217,16 +9246,19 @@ public class PackageManagerService extends IPackageManager.Stub
if (getInstantAppPackageName(callingUid) != null) {
return null;
}
+ final int callingUserId = UserHandle.getUserId(callingUid);
final int appId = UserHandle.getAppId(uid);
synchronized (mLock) {
final Object obj = mSettings.getSettingLPr(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
+ return null;
+ }
return sus.name + ":" + sus.userId;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplicationLocked(
- ps, callingUid, UserHandle.getUserId(callingUid))) {
+ if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
return null;
}
return ps.name;
@@ -9244,6 +9276,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (getInstantAppPackageName(callingUid) != null) {
return null;
}
+ final int callingUserId = UserHandle.getUserId(callingUid);
final String[] names = new String[uids.length];
synchronized (mLock) {
for (int i = uids.length - 1; i >= 0; i--) {
@@ -9251,11 +9284,14 @@ public class PackageManagerService extends IPackageManager.Stub
final Object obj = mSettings.getSettingLPr(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
- names[i] = "shared:" + sus.name;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
+ names[i] = null;
+ } else {
+ names[i] = "shared:" + sus.name;
+ }
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplicationLocked(
- ps, callingUid, UserHandle.getUserId(callingUid))) {
+ if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
names[i] = null;
} else {
names[i] = ps.name;
@@ -9297,16 +9333,19 @@ public class PackageManagerService extends IPackageManager.Stub
if (getInstantAppPackageName(callingUid) != null) {
return 0;
}
+ final int callingUserId = UserHandle.getUserId(callingUid);
final int appId = UserHandle.getAppId(uid);
synchronized (mLock) {
final Object obj = mSettings.getSettingLPr(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
+ return 0;
+ }
return sus.pkgFlags;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplicationLocked(
- ps, callingUid, UserHandle.getUserId(callingUid))) {
+ if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
return 0;
}
return ps.pkgFlags;
@@ -9321,16 +9360,19 @@ public class PackageManagerService extends IPackageManager.Stub
if (getInstantAppPackageName(callingUid) != null) {
return 0;
}
+ final int callingUserId = UserHandle.getUserId(callingUid);
final int appId = UserHandle.getAppId(uid);
synchronized (mLock) {
final Object obj = mSettings.getSettingLPr(appId);
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
+ if (shouldFilterApplicationLocked(sus, callingUid, callingUserId)) {
+ return 0;
+ }
return sus.pkgPrivateFlags;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplicationLocked(
- ps, callingUid, UserHandle.getUserId(callingUid))) {
+ if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
return 0;
}
return ps.pkgPrivateFlags;
@@ -24141,11 +24183,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
- // TODO: This cannot be moved to ComputerEngine since some variables with collections
- // types in IntentResolver such as mTypeToFilter do not have a copy of `F[]`.
- synchronized (mLock) {
- mSettings.dumpPreferred(pw, dumpState, packageName);
- }
+ dump(DumpState.DUMP_PREFERRED, fd, pw, dumpState);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index d1cf55de7254..38cba4ca9e20 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -1889,231 +1889,248 @@ public class ShortcutService extends IShortcutService.Stub {
@Override
public void setDynamicShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId, @NonNull AndroidFuture callback) {
- verifyCaller(packageName, userId);
+ try {
+ verifyCaller(packageName, userId);
- final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
- verifyShortcutInfoPackages(packageName, newShortcuts);
- final int size = newShortcuts.size();
+ final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
+ verifyShortcutInfoPackages(packageName, newShortcuts);
+ final int size = newShortcuts.size();
- final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
- injectBinderCallingPid(), injectBinderCallingUid());
+ final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
+ injectBinderCallingPid(), injectBinderCallingUid());
- List<ShortcutInfo> changedShortcuts = null;
- List<ShortcutInfo> removedShortcuts = null;
+ List<ShortcutInfo> changedShortcuts = null;
+ List<ShortcutInfo> removedShortcuts = null;
- synchronized (mLock) {
- throwIfUserLockedL(userId);
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
+ final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName,
+ userId);
- ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
- ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
+ ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
+ ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
- fillInDefaultActivity(newShortcuts);
+ fillInDefaultActivity(newShortcuts);
- ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_SET);
+ ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_SET);
- // Throttling.
- if (!ps.tryApiCall(unlimited)) {
- callback.complete(false);
- }
+ // Throttling.
+ if (!ps.tryApiCall(unlimited)) {
+ callback.complete(false);
+ return;
+ }
- // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
- ps.clearAllImplicitRanks();
- assignImplicitRanks(newShortcuts);
+ // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
+ ps.clearAllImplicitRanks();
+ assignImplicitRanks(newShortcuts);
- for (int i = 0; i < size; i++) {
- fixUpIncomingShortcutInfo(newShortcuts.get(i), /* forUpdate= */ false);
- }
+ for (int i = 0; i < size; i++) {
+ fixUpIncomingShortcutInfo(newShortcuts.get(i), /* forUpdate= */ false);
+ }
- ArrayList<ShortcutInfo> cachedOrPinned = new ArrayList<>();
- ps.findAll(cachedOrPinned, (ShortcutInfo si) -> si.isVisibleToPublisher()
- && si.isDynamic() && (si.isCached() || si.isPinned()),
- ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
+ ArrayList<ShortcutInfo> cachedOrPinned = new ArrayList<>();
+ ps.findAll(cachedOrPinned, (ShortcutInfo si) -> si.isVisibleToPublisher()
+ && si.isDynamic() && (si.isCached() || si.isPinned()),
+ ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
- // First, remove all un-pinned and non-cached; dynamic shortcuts
- removedShortcuts = ps.deleteAllDynamicShortcuts(/*ignoreInvisible=*/ true);
+ // First, remove all un-pinned and non-cached; dynamic shortcuts
+ removedShortcuts = ps.deleteAllDynamicShortcuts(/*ignoreInvisible=*/ true);
- // Then, add/update all. We need to make sure to take over "pinned" flag.
- for (int i = 0; i < size; i++) {
- final ShortcutInfo newShortcut = newShortcuts.get(i);
- ps.addOrReplaceDynamicShortcut(newShortcut);
- }
+ // Then, add/update all. We need to make sure to take over "pinned" flag.
+ for (int i = 0; i < size; i++) {
+ final ShortcutInfo newShortcut = newShortcuts.get(i);
+ ps.addOrReplaceDynamicShortcut(newShortcut);
+ }
- // Lastly, adjust the ranks.
- ps.adjustRanks();
+ // Lastly, adjust the ranks.
+ ps.adjustRanks();
- changedShortcuts = prepareChangedShortcuts(
- cachedOrPinned, newShortcuts, removedShortcuts, ps);
- }
+ changedShortcuts = prepareChangedShortcuts(
+ cachedOrPinned, newShortcuts, removedShortcuts, ps);
+ }
- packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts);
+ packageShortcutsChanged(packageName, userId, changedShortcuts, removedShortcuts);
- verifyStates();
+ verifyStates();
- callback.complete(true);
+ callback.complete(true);
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
+ }
}
@Override
public void updateShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId, AndroidFuture callback) {
- verifyCaller(packageName, userId);
+ try {
+ verifyCaller(packageName, userId);
- final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
- verifyShortcutInfoPackages(packageName, newShortcuts);
- final int size = newShortcuts.size();
+ final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
+ verifyShortcutInfoPackages(packageName, newShortcuts);
+ final int size = newShortcuts.size();
- final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
- injectBinderCallingPid(), injectBinderCallingUid());
+ final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
+ injectBinderCallingPid(), injectBinderCallingUid());
- final List<ShortcutInfo> changedShortcuts = new ArrayList<>(1);
+ final List<ShortcutInfo> changedShortcuts = new ArrayList<>(1);
- synchronized (mLock) {
- throwIfUserLockedL(userId);
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
+ final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName,
+ userId);
- ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
- ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
+ ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
+ ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
- // For update, don't fill in the default activity. Having null activity means
- // "don't update the activity" here.
+ // For update, don't fill in the default activity. Having null activity means
+ // "don't update the activity" here.
- ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_UPDATE);
+ ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_UPDATE);
- // Throttling.
- if (!ps.tryApiCall(unlimited)) {
- callback.complete(false);
- return;
- }
+ // Throttling.
+ if (!ps.tryApiCall(unlimited)) {
+ callback.complete(false);
+ return;
+ }
- // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
- ps.clearAllImplicitRanks();
- assignImplicitRanks(newShortcuts);
+ // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
+ ps.clearAllImplicitRanks();
+ assignImplicitRanks(newShortcuts);
- for (int i = 0; i < size; i++) {
- final ShortcutInfo source = newShortcuts.get(i);
- fixUpIncomingShortcutInfo(source, /* forUpdate= */ true);
+ for (int i = 0; i < size; i++) {
+ final ShortcutInfo source = newShortcuts.get(i);
+ fixUpIncomingShortcutInfo(source, /* forUpdate= */ true);
- ps.mutateShortcut(source.getId(), null, target -> {
- // Invisible shortcuts can't be updated.
- if (target == null || !target.isVisibleToPublisher()) {
- return;
- }
+ ps.mutateShortcut(source.getId(), null, target -> {
+ // Invisible shortcuts can't be updated.
+ if (target == null || !target.isVisibleToPublisher()) {
+ return;
+ }
- if (target.isEnabled() != source.isEnabled()) {
- Slog.w(TAG,
- "ShortcutInfo.enabled cannot be changed with updateShortcuts()");
- }
+ if (target.isEnabled() != source.isEnabled()) {
+ Slog.w(TAG, "ShortcutInfo.enabled cannot be changed with"
+ + " updateShortcuts()");
+ }
- if (target.isLongLived() != source.isLongLived()) {
- Slog.w(TAG,
- "ShortcutInfo.longLived cannot be changed with updateShortcuts()");
- }
+ if (target.isLongLived() != source.isLongLived()) {
+ Slog.w(TAG,
+ "ShortcutInfo.longLived cannot be changed with"
+ + " updateShortcuts()");
+ }
- // When updating the rank, we need to insert between existing ranks, so set
- // this setRankChanged, and also copy the implicit rank fo adjustRanks().
- if (source.hasRank()) {
- target.setRankChanged();
- target.setImplicitRank(source.getImplicitRank());
- }
+ // When updating the rank, we need to insert between existing ranks, so set
+ // this setRankChanged, and also copy the implicit rank fo adjustRanks().
+ if (source.hasRank()) {
+ target.setRankChanged();
+ target.setImplicitRank(source.getImplicitRank());
+ }
- final boolean replacingIcon = (source.getIcon() != null);
- if (replacingIcon) {
- removeIconLocked(target);
- }
+ final boolean replacingIcon = (source.getIcon() != null);
+ if (replacingIcon) {
+ removeIconLocked(target);
+ }
- // Note copyNonNullFieldsFrom() does the "updatable with?" check too.
- target.copyNonNullFieldsFrom(source);
- target.setTimestamp(injectCurrentTimeMillis());
+ // Note copyNonNullFieldsFrom() does the "updatable with?" check too.
+ target.copyNonNullFieldsFrom(source);
+ target.setTimestamp(injectCurrentTimeMillis());
- if (replacingIcon) {
- saveIconAndFixUpShortcutLocked(target);
- }
+ if (replacingIcon) {
+ saveIconAndFixUpShortcutLocked(target);
+ }
- // When we're updating any resource related fields, re-extract the res names and
- // the values.
- if (replacingIcon || source.hasStringResources()) {
- fixUpShortcutResourceNamesAndValues(target);
- }
+ // When we're updating any resource related fields, re-extract the res
+ // names and the values.
+ if (replacingIcon || source.hasStringResources()) {
+ fixUpShortcutResourceNamesAndValues(target);
+ }
- changedShortcuts.add(target);
- });
- }
+ changedShortcuts.add(target);
+ });
+ }
- // Lastly, adjust the ranks.
- ps.adjustRanks();
- }
- packageShortcutsChanged(packageName, userId,
- changedShortcuts.isEmpty() ? null : changedShortcuts, null);
+ // Lastly, adjust the ranks.
+ ps.adjustRanks();
+ }
+ packageShortcutsChanged(packageName, userId,
+ changedShortcuts.isEmpty() ? null : changedShortcuts, null);
- verifyStates();
+ verifyStates();
- callback.complete(true);
+ callback.complete(true);
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
+ }
}
@Override
public void addDynamicShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId, AndroidFuture callback) {
- verifyCaller(packageName, userId);
+ try {
+ verifyCaller(packageName, userId);
- final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
- verifyShortcutInfoPackages(packageName, newShortcuts);
- final int size = newShortcuts.size();
+ final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
+ verifyShortcutInfoPackages(packageName, newShortcuts);
+ final int size = newShortcuts.size();
- final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
- injectBinderCallingPid(), injectBinderCallingUid());
+ final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
+ injectBinderCallingPid(), injectBinderCallingUid());
- List<ShortcutInfo> changedShortcuts = null;
+ List<ShortcutInfo> changedShortcuts = null;
- synchronized (mLock) {
- throwIfUserLockedL(userId);
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
+ final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName,
+ userId);
- ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
- ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
+ ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
+ ps.ensureNoBitmapIconIfShortcutIsLongLived(newShortcuts);
- fillInDefaultActivity(newShortcuts);
+ fillInDefaultActivity(newShortcuts);
- ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_ADD);
+ ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_ADD);
- // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
- ps.clearAllImplicitRanks();
- assignImplicitRanks(newShortcuts);
+ // Initialize the implicit ranks for ShortcutPackage.adjustRanks().
+ ps.clearAllImplicitRanks();
+ assignImplicitRanks(newShortcuts);
- // Throttling.
- if (!ps.tryApiCall(unlimited)) {
- callback.complete(false);
- return;
- }
- for (int i = 0; i < size; i++) {
- final ShortcutInfo newShortcut = newShortcuts.get(i);
+ // Throttling.
+ if (!ps.tryApiCall(unlimited)) {
+ callback.complete(false);
+ return;
+ }
+ for (int i = 0; i < size; i++) {
+ final ShortcutInfo newShortcut = newShortcuts.get(i);
- // Validate the shortcut.
- fixUpIncomingShortcutInfo(newShortcut, /* forUpdate= */ false);
+ // Validate the shortcut.
+ fixUpIncomingShortcutInfo(newShortcut, /* forUpdate= */ false);
- // When ranks are changing, we need to insert between ranks, so set the
- // "rank changed" flag.
- newShortcut.setRankChanged();
+ // When ranks are changing, we need to insert between ranks, so set the
+ // "rank changed" flag.
+ newShortcut.setRankChanged();
- // Add it.
- ps.addOrReplaceDynamicShortcut(newShortcut);
+ // Add it.
+ ps.addOrReplaceDynamicShortcut(newShortcut);
- if (changedShortcuts == null) {
- changedShortcuts = new ArrayList<>(1);
+ if (changedShortcuts == null) {
+ changedShortcuts = new ArrayList<>(1);
+ }
+ changedShortcuts.add(newShortcut);
}
- changedShortcuts.add(newShortcut);
- }
- // Lastly, adjust the ranks.
- ps.adjustRanks();
- }
- packageShortcutsChanged(packageName, userId, changedShortcuts, null);
+ // Lastly, adjust the ranks.
+ ps.adjustRanks();
+ }
+ packageShortcutsChanged(packageName, userId, changedShortcuts, null);
- verifyStates();
+ verifyStates();
- callback.complete(true);
+ callback.complete(true);
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
+ }
}
@Override
@@ -2180,31 +2197,40 @@ public class ShortcutService extends IShortcutService.Stub {
@Override
public void requestPinShortcut(String packageName, ShortcutInfo shortcut,
IntentSender resultIntent, int userId, AndroidFuture callback) {
- Objects.requireNonNull(shortcut);
- Objects.requireNonNull(callback);
- Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
- callback.complete(requestPinItem(packageName, userId, shortcut, null, null, resultIntent));
+ try {
+ Objects.requireNonNull(shortcut);
+ Objects.requireNonNull(callback);
+ Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
+ callback.complete(
+ requestPinItem(packageName, userId, shortcut, null, null, resultIntent));
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
+ }
}
@Override
public void createShortcutResultIntent(String packageName, ShortcutInfo shortcut, int userId,
AndroidFuture callback)
throws RemoteException {
- Objects.requireNonNull(shortcut);
- Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
- verifyCaller(packageName, userId);
- verifyShortcutInfoPackage(packageName, shortcut);
+ try {
+ Objects.requireNonNull(shortcut);
+ Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
+ verifyCaller(packageName, userId);
+ verifyShortcutInfoPackage(packageName, shortcut);
- final Intent ret;
- synchronized (mLock) {
- throwIfUserLockedL(userId);
+ final Intent ret;
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- // Send request to the launcher, if supported.
- ret = mShortcutRequestPinProcessor.createShortcutResultIntent(shortcut, userId);
- }
+ // Send request to the launcher, if supported.
+ ret = mShortcutRequestPinProcessor.createShortcutResultIntent(shortcut, userId);
+ }
- verifyStates();
- callback.complete(ret);
+ verifyStates();
+ callback.complete(ret);
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
+ }
}
/**
@@ -2464,47 +2490,57 @@ public class ShortcutService extends IShortcutService.Stub {
public void getShortcuts(String packageName,
@ShortcutManager.ShortcutMatchFlags int matchFlags, @UserIdInt int userId,
AndroidFuture<ParceledListSlice<ShortcutInfo>> callback) {
- verifyCaller(packageName, userId);
-
- synchronized (mLock) {
- throwIfUserLockedL(userId);
-
- final boolean matchDynamic = (matchFlags & ShortcutManager.FLAG_MATCH_DYNAMIC) != 0;
- final boolean matchPinned = (matchFlags & ShortcutManager.FLAG_MATCH_PINNED) != 0;
- final boolean matchManifest = (matchFlags & ShortcutManager.FLAG_MATCH_MANIFEST) != 0;
- final boolean matchCached = (matchFlags & ShortcutManager.FLAG_MATCH_CACHED) != 0;
+ try {
+ verifyCaller(packageName, userId);
- final int shortcutFlags = (matchDynamic ? ShortcutInfo.FLAG_DYNAMIC : 0)
- | (matchPinned ? ShortcutInfo.FLAG_PINNED : 0)
- | (matchManifest ? ShortcutInfo.FLAG_MANIFEST : 0)
- | (matchCached ? ShortcutInfo.FLAG_CACHED_ALL : 0);
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- callback.complete(getShortcutsWithQueryLocked(
- packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
- (ShortcutInfo si) ->
- si.isVisibleToPublisher() && (si.getFlags() & shortcutFlags) != 0));
+ final boolean matchDynamic = (matchFlags & ShortcutManager.FLAG_MATCH_DYNAMIC) != 0;
+ final boolean matchPinned = (matchFlags & ShortcutManager.FLAG_MATCH_PINNED) != 0;
+ final boolean matchManifest =
+ (matchFlags & ShortcutManager.FLAG_MATCH_MANIFEST) != 0;
+ final boolean matchCached = (matchFlags & ShortcutManager.FLAG_MATCH_CACHED) != 0;
+
+ final int shortcutFlags = (matchDynamic ? ShortcutInfo.FLAG_DYNAMIC : 0)
+ | (matchPinned ? ShortcutInfo.FLAG_PINNED : 0)
+ | (matchManifest ? ShortcutInfo.FLAG_MANIFEST : 0)
+ | (matchCached ? ShortcutInfo.FLAG_CACHED_ALL : 0);
+
+ callback.complete(getShortcutsWithQueryLocked(
+ packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
+ (ShortcutInfo si) ->
+ si.isVisibleToPublisher() && (si.getFlags() & shortcutFlags) != 0));
+ }
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
}
}
@Override
public void getShareTargets(String packageName, IntentFilter filter, @UserIdInt int userId,
AndroidFuture<ParceledListSlice> callback) {
- Preconditions.checkStringNotEmpty(packageName, "packageName");
- Objects.requireNonNull(filter, "intentFilter");
+ try {
+ Preconditions.checkStringNotEmpty(packageName, "packageName");
+ Objects.requireNonNull(filter, "intentFilter");
- verifyCaller(packageName, userId);
- enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APP_PREDICTIONS,
- "getShareTargets");
+ verifyCaller(packageName, userId);
+ enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APP_PREDICTIONS,
+ "getShareTargets");
- synchronized (mLock) {
- throwIfUserLockedL(userId);
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
- final List<ShortcutManager.ShareShortcutInfo> shortcutInfoList = new ArrayList<>();
+ final List<ShortcutManager.ShareShortcutInfo> shortcutInfoList = new ArrayList<>();
- final ShortcutUser user = getUserShortcutsLocked(userId);
- user.forAllPackages(p -> shortcutInfoList.addAll(p.getMatchingShareTargets(filter)));
+ final ShortcutUser user = getUserShortcutsLocked(userId);
+ user.forAllPackages(
+ p -> shortcutInfoList.addAll(p.getMatchingShareTargets(filter)));
- callback.complete(new ParceledListSlice<>(shortcutInfoList));
+ callback.complete(new ParceledListSlice<>(shortcutInfoList));
+ }
+ } catch (Exception e) {
+ callback.completeExceptionally(e);
}
}
diff --git a/services/core/java/com/android/server/power/FaceDownDetector.java b/services/core/java/com/android/server/power/FaceDownDetector.java
index 2442079bec8b..676181dcfb67 100644
--- a/services/core/java/com/android/server/power/FaceDownDetector.java
+++ b/services/core/java/com/android/server/power/FaceDownDetector.java
@@ -30,6 +30,7 @@ import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Looper;
+import android.os.PowerManager;
import android.os.SystemClock;
import android.provider.DeviceConfig;
import android.util.Slog;
@@ -66,7 +67,7 @@ public class FaceDownDetector implements SensorEventListener {
private static final float MOVING_AVERAGE_WEIGHT = 0.5f;
/** DeviceConfig flag name, if {@code true}, enables Face Down features. */
- private static final String KEY_FEATURE_ENABLED = "enable_flip_to_screen_off";
+ static final String KEY_FEATURE_ENABLED = "enable_flip_to_screen_off";
/** Default value in absence of {@link DeviceConfig} override. */
private static final boolean DEFAULT_FEATURE_ENABLED = true;
@@ -139,6 +140,7 @@ public class FaceDownDetector implements SensorEventListener {
new ExponentialMovingAverage(MOVING_AVERAGE_WEIGHT);
private boolean mFaceDown = false;
+ private boolean mInteractive = false;
private boolean mActive = false;
private float mPrevAcceleration = 0;
@@ -149,62 +151,64 @@ public class FaceDownDetector implements SensorEventListener {
private final Handler mHandler;
private final Runnable mUserActivityRunnable;
+ private final BroadcastReceiver mScreenReceiver;
+
+ private Context mContext;
public FaceDownDetector(@NonNull Consumer<Boolean> onFlip) {
mOnFlip = Objects.requireNonNull(onFlip);
mHandler = new Handler(Looper.getMainLooper());
+ mScreenReceiver = new ScreenStateReceiver();
mUserActivityRunnable = () -> {
if (mFaceDown) {
exitFaceDown(USER_INTERACTION, SystemClock.uptimeMillis() - mLastFlipTime);
- checkAndUpdateActiveState(false);
+ updateActiveState();
}
};
}
/** Initializes the FaceDownDetector and all necessary listeners. */
public void systemReady(Context context) {
+ mContext = context;
mSensorManager = context.getSystemService(SensorManager.class);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
readValuesFromDeviceConfig();
- checkAndUpdateActiveState(true);
DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_ATTENTION_MANAGER_SERVICE,
ActivityThread.currentApplication().getMainExecutor(),
(properties) -> onDeviceConfigChange(properties.getKeyset()));
+ updateActiveState();
+ }
+
+ private void registerScreenReceiver(Context context) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
- context.registerReceiver(new ScreenStateReceiver(), intentFilter);
+ context.registerReceiver(mScreenReceiver, intentFilter);
}
/**
* Sets the active state of the detector. If false, we will not process accelerometer changes.
*/
- private void checkAndUpdateActiveState(boolean active) {
- if (mIsEnabled && mActive != active) {
- final long currentTime = SystemClock.uptimeMillis();
- // Don't make active if there was recently a user interaction while face down.
- if (active && mPreviousResultType == USER_INTERACTION
- && currentTime - mPreviousResultTime < mUserInteractionBackoffMillis) {
- return;
- }
- if (DEBUG) Slog.d(TAG, "Update active - " + active);
- mActive = active;
- if (!active) {
- if (mFaceDown && mPreviousResultTime != USER_INTERACTION) {
- mPreviousResultType = SCREEN_OFF_RESULT;
- mPreviousResultTime = currentTime;
+ private void updateActiveState() {
+ final long currentTime = SystemClock.uptimeMillis();
+ final boolean sawRecentInteraction = mPreviousResultType == USER_INTERACTION
+ && currentTime - mPreviousResultTime < mUserInteractionBackoffMillis;
+ final boolean shouldBeActive = mInteractive && mIsEnabled && !sawRecentInteraction;
+ if (mActive != shouldBeActive) {
+ if (shouldBeActive) {
+ mSensorManager.registerListener(
+ this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
+ if (mPreviousResultType == SCREEN_OFF_RESULT) {
+ logScreenOff();
}
+ } else {
mSensorManager.unregisterListener(this);
mFaceDown = false;
mOnFlip.accept(false);
- } else {
- if (mPreviousResultType == SCREEN_OFF_RESULT) {
- logScreenOff();
- }
- mSensorManager.registerListener(
- this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
+ mActive = shouldBeActive;
+ if (DEBUG) Slog.d(TAG, "Update active - " + shouldBeActive);
}
}
@@ -287,8 +291,10 @@ public class FaceDownDetector implements SensorEventListener {
* The user interacted with the screen while face down, indicated the phone is in use.
* We log this event and temporarily make this detector inactive.
*/
- public void userActivity() {
- mHandler.post(mUserActivityRunnable);
+ public void userActivity(int event) {
+ if (event != PowerManager.USER_ACTIVITY_EVENT_FACE_DOWN) {
+ mHandler.post(mUserActivityRunnable);
+ }
}
private void exitFaceDown(int resultType, long millisSinceFlip) {
@@ -389,6 +395,7 @@ public class FaceDownDetector implements SensorEventListener {
case KEY_TIME_THRESHOLD_MILLIS:
case KEY_FEATURE_ENABLED:
readValuesFromDeviceConfig();
+ updateActiveState();
return;
default:
Slog.i(TAG, "Ignoring change on " + key);
@@ -401,8 +408,18 @@ public class FaceDownDetector implements SensorEventListener {
mZAccelerationThreshold = getZAccelerationThreshold();
mZAccelerationThresholdLenient = mZAccelerationThreshold + 1.0f;
mTimeThreshold = getTimeThreshold();
- mIsEnabled = isEnabled();
mUserInteractionBackoffMillis = getUserInteractionBackoffMillis();
+ final boolean oldEnabled = mIsEnabled;
+ mIsEnabled = isEnabled();
+ if (oldEnabled != mIsEnabled) {
+ if (!mIsEnabled) {
+ mContext.unregisterReceiver(mScreenReceiver);
+ mInteractive = false;
+ } else {
+ registerScreenReceiver(mContext);
+ mInteractive = mContext.getSystemService(PowerManager.class).isInteractive();
+ }
+ }
Slog.i(TAG, "readValuesFromDeviceConfig():"
+ "\nmAccelerationThreshold=" + mAccelerationThreshold
@@ -423,9 +440,11 @@ public class FaceDownDetector implements SensorEventListener {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
- checkAndUpdateActiveState(false);
+ mInteractive = false;
+ updateActiveState();
} else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
- checkAndUpdateActiveState(true);
+ mInteractive = true;
+ updateActiveState();
}
}
}
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index f49e2f1631b9..7555a7f2920b 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -549,6 +549,7 @@ public class Notifier {
if (!mUserActivityPending) {
mUserActivityPending = true;
Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY);
+ msg.arg1 = event;
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
}
@@ -647,7 +648,7 @@ public class Notifier {
mSuspendBlocker.release();
}
- private void sendUserActivity() {
+ private void sendUserActivity(int event) {
synchronized (mLock) {
if (!mUserActivityPending) {
return;
@@ -657,7 +658,7 @@ public class Notifier {
TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
tm.notifyUserActivity();
mPolicy.userActivity();
- mFaceDownDetector.userActivity();
+ mFaceDownDetector.userActivity(event);
}
void postEnhancedDischargePredictionBroadcast(long delayMs) {
@@ -833,7 +834,7 @@ public class Notifier {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_USER_ACTIVITY:
- sendUserActivity();
+ sendUserActivity(msg.arg1);
break;
case MSG_BROADCAST:
sendNextBroadcast();
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 29adde37ab3b..d2a4cd604c01 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -180,8 +180,6 @@ public final class PowerManagerService extends SystemService
private static final int DIRTY_VR_MODE_CHANGED = 1 << 13;
// Dirty bit: attentive timer may have timed out
private static final int DIRTY_ATTENTIVE = 1 << 14;
- // Dirty bit: phone flipped to face down
- private static final int DIRTY_FACE_DOWN = 1 << 15;
// Dirty bit: display group power state has changed
private static final int DIRTY_DISPLAY_GROUP_POWER_UPDATED = 1 << 16;
@@ -1069,8 +1067,9 @@ public final class PowerManagerService extends SystemService
final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout, -1L);
millisUntilNormalTimeout =
mLastUserActivityTime + screenOffTimeout - mClock.uptimeMillis();
- mDirty |= DIRTY_FACE_DOWN;
- updatePowerStateLocked();
+ userActivityInternal(mClock.uptimeMillis(),
+ PowerManager.USER_ACTIVITY_EVENT_FACE_DOWN, /* flags= */0,
+ Process.SYSTEM_UID);
}
}
if (isFaceDown) {
diff --git a/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java b/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java
index cfb4c27820fa..189f47f7f1da 100644
--- a/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java
+++ b/services/core/java/com/android/server/rotationresolver/RemoteRotationResolverService.java
@@ -77,9 +77,7 @@ class RemoteRotationResolverService extends ServiceConnector.Impl<IRotationResol
@GuardedBy("mLock")
public void resolveRotationLocked(RotationRequest request) {
- final RotationResolutionRequest remoteRequest = new RotationResolutionRequest(
- request.mProposedRotation, request.mCurrentRotation, request.mPackageName,
- request.mTimeoutMillis);
+ final RotationResolutionRequest remoteRequest = request.mRemoteRequest;
post(service -> service.resolveRotation(request.mIRotationResolverCallback, remoteRequest));
// schedule a timeout.
@@ -91,7 +89,7 @@ class RemoteRotationResolverService extends ServiceConnector.Impl<IRotationResol
request.cancelInternal();
}
}
- }, request.mTimeoutMillis);
+ }, request.mRemoteRequest.getTimeoutMillis());
}
@VisibleForTesting
@@ -109,28 +107,18 @@ class RemoteRotationResolverService extends ServiceConnector.Impl<IRotationResol
@GuardedBy("mLock")
boolean mIsFulfilled;
- private final long mTimeoutMillis;
-
@VisibleForTesting
- final int mProposedRotation;
-
- private final int mCurrentRotation;
- private final String mPackageName;
+ final RotationResolutionRequest mRemoteRequest;
boolean mIsDispatched;
private final Object mLock = new Object();
private final long mRequestStartTimeMillis;
RotationRequest(
- @NonNull RotationResolverInternal.RotationResolverCallbackInternal
- callbackInternal, int proposedRotation, int currentRotation,
- String packageName, long timeoutMillis,
- @NonNull CancellationSignal cancellationSignal) {
- mTimeoutMillis = timeoutMillis;
+ @NonNull RotationResolverInternal.RotationResolverCallbackInternal callbackInternal,
+ RotationResolutionRequest request, @NonNull CancellationSignal cancellationSignal) {
mCallbackInternal = callbackInternal;
- mProposedRotation = proposedRotation;
- mCurrentRotation = currentRotation;
- mPackageName = packageName;
+ mRemoteRequest = request;
mIRotationResolverCallback = new RotationResolverCallback(this);
mCancellationSignalInternal = cancellationSignal;
mRequestStartTimeMillis = SystemClock.elapsedRealtime();
@@ -185,8 +173,8 @@ class RemoteRotationResolverService extends ServiceConnector.Impl<IRotationResol
request.mCallbackInternal.onSuccess(rotation);
final long timeToCalculate =
SystemClock.elapsedRealtime() - request.mRequestStartTimeMillis;
- logRotationStats(request.mProposedRotation, request.mCurrentRotation, rotation,
- timeToCalculate);
+ logRotationStats(request.mRemoteRequest.getProposedRotation(),
+ request.mRemoteRequest.getCurrentRotation(), rotation, timeToCalculate);
Slog.d(TAG, "onSuccess:" + rotation);
Slog.d(TAG, "timeToCalculate:" + timeToCalculate);
}
@@ -204,8 +192,9 @@ class RemoteRotationResolverService extends ServiceConnector.Impl<IRotationResol
request.mCallbackInternal.onFailure(error);
final long timeToCalculate =
SystemClock.elapsedRealtime() - request.mRequestStartTimeMillis;
- logRotationStats(request.mProposedRotation, request.mCurrentRotation,
- RESOLUTION_FAILURE, timeToCalculate);
+ logRotationStats(request.mRemoteRequest.getProposedRotation(),
+ request.mRemoteRequest.getCurrentRotation(), RESOLUTION_FAILURE,
+ timeToCalculate);
Slog.d(TAG, "onFailure:" + error);
Slog.d(TAG, "timeToCalculate:" + timeToCalculate);
}
diff --git a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
index 13f8d61f74f5..1dbe3e485938 100644
--- a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
+++ b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerPerUserService.java
@@ -34,11 +34,11 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.CancellationSignal;
import android.rotationresolver.RotationResolverInternal;
+import android.service.rotationresolver.RotationResolutionRequest;
import android.service.rotationresolver.RotationResolverService;
import android.text.TextUtils;
import android.util.IndentingPrintWriter;
import android.util.Slog;
-import android.view.Surface;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -95,14 +95,14 @@ final class RotationResolverManagerPerUserService extends
@VisibleForTesting
void resolveRotationLocked(
@NonNull RotationResolverInternal.RotationResolverCallbackInternal callbackInternal,
- @Surface.Rotation int proposedRotation, @Surface.Rotation int currentRotation,
- String packageName, long timeoutMillis,
+ @NonNull RotationResolutionRequest request,
@NonNull CancellationSignal cancellationSignalInternal) {
if (!isServiceAvailableLocked()) {
Slog.w(TAG, "Service is not available at this moment.");
callbackInternal.onFailure(ROTATION_RESULT_FAILURE_CANCELLED);
- logRotationStats(proposedRotation, currentRotation, RESOLUTION_UNAVAILABLE);
+ logRotationStats(request.getProposedRotation(), request.getCurrentRotation(),
+ RESOLUTION_UNAVAILABLE);
return;
}
@@ -114,8 +114,7 @@ final class RotationResolverManagerPerUserService extends
}
mCurrentRequest = new RemoteRotationResolverService.RotationRequest(callbackInternal,
- proposedRotation, currentRotation, packageName, timeoutMillis,
- cancellationSignalInternal);
+ request, cancellationSignalInternal);
cancellationSignalInternal.setOnCancelListener(() -> {
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
index e57d4ce9ec31..a7f3cdb8bcd2 100644
--- a/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
+++ b/services/core/java/com/android/server/rotationresolver/RotationResolverManagerService.java
@@ -35,6 +35,7 @@ import android.os.ShellCallback;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.rotationresolver.RotationResolverInternal;
+import android.service.rotationresolver.RotationResolutionRequest;
import android.text.TextUtils;
import android.util.IndentingPrintWriter;
import android.util.Slog;
@@ -158,8 +159,9 @@ public class RotationResolverManagerService extends
if (mIsServiceEnabled) {
final RotationResolverManagerPerUserService service = getServiceForUserLocked(
UserHandle.getCallingUserId());
- service.resolveRotationLocked(callbackInternal, proposedRotation,
- currentRotation, /* packageName */ "", timeout,
+ final RotationResolutionRequest request = new RotationResolutionRequest("",
+ currentRotation, proposedRotation, true, timeout);
+ service.resolveRotationLocked(callbackInternal, request,
cancellationSignalInternal);
} else {
Slog.w(TAG, "Rotation Resolver service is disabled.");
diff --git a/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java b/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java
index e5088c023533..a0e04ee7a20d 100644
--- a/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java
+++ b/services/core/java/com/android/server/rotationresolver/RotationResolverShellCommand.java
@@ -22,6 +22,7 @@ import android.content.ComponentName;
import android.os.CancellationSignal;
import android.os.ShellCommand;
import android.rotationresolver.RotationResolverInternal.RotationResolverCallbackInternal;
+import android.service.rotationresolver.RotationResolutionRequest;
import android.text.TextUtils;
import android.view.Surface;
@@ -107,8 +108,10 @@ final class RotationResolverShellCommand extends ShellCommand {
}
private int runResolveRotation() {
- mService.resolveRotationLocked(sTestableRotationCallbackInternal, Surface.ROTATION_0,
- Surface.ROTATION_0, "", 2000L, new CancellationSignal());
+ final RotationResolutionRequest request = new RotationResolutionRequest("",
+ Surface.ROTATION_0, Surface.ROTATION_0, true, 2000L);
+ mService.resolveRotationLocked(sTestableRotationCallbackInternal, request,
+ new CancellationSignal());
return 0;
}
diff --git a/services/core/java/com/android/server/security/FileIntegrityService.java b/services/core/java/com/android/server/security/FileIntegrityService.java
index 74bb99351a6d..466ac74a8322 100644
--- a/services/core/java/com/android/server/security/FileIntegrityService.java
+++ b/services/core/java/com/android/server/security/FileIntegrityService.java
@@ -29,6 +29,7 @@ import android.os.UserHandle;
import android.security.IFileIntegrityService;
import android.util.Slog;
+import com.android.internal.security.VerityUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
diff --git a/services/core/java/com/android/server/security/OWNERS b/services/core/java/com/android/server/security/OWNERS
index 91b240bcb189..e6f5826557b5 100644
--- a/services/core/java/com/android/server/security/OWNERS
+++ b/services/core/java/com/android/server/security/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 36824
per-file FileIntegrityService.java = victorhsieh@google.com
-per-file VerityUtils.java = victorhsieh@google.com
diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
index dbe73546d748..52c1467bd5d0 100644
--- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
+++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
@@ -16,6 +16,8 @@
package com.android.server.speech;
+import static android.Manifest.permission.MANAGE_SPEECH_RECOGNITION;
+
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.ComponentName;
@@ -24,6 +26,7 @@ import android.os.IBinder;
import android.os.UserHandle;
import android.speech.IRecognitionServiceManager;
import android.speech.IRecognitionServiceManagerCallback;
+import android.util.Slog;
import com.android.internal.R;
import com.android.server.infra.AbstractMasterSystemService;
@@ -42,6 +45,8 @@ public final class SpeechRecognitionManagerService extends
SpeechRecognitionManagerServiceImpl> {
private static final String TAG = SpeechRecognitionManagerService.class.getSimpleName();
+ private static final int MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS = 60_000;
+
public SpeechRecognitionManagerService(@NonNull Context context) {
super(context,
// TODO(b/176578753): think if we want to favor the particular service here.
@@ -58,6 +63,16 @@ public final class SpeechRecognitionManagerService extends
}
@Override
+ protected void enforceCallingPermissionForManagement() {
+ getContext().enforceCallingPermission(MANAGE_SPEECH_RECOGNITION, TAG);
+ }
+
+ @Override
+ protected int getMaximumTemporaryServiceDurationMs() {
+ return MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS;
+ }
+
+ @Override
protected SpeechRecognitionManagerServiceImpl newServiceLocked(
@UserIdInt int resolvedUserId, boolean disabled) {
return new SpeechRecognitionManagerServiceImpl(this, mLock, resolvedUserId, disabled);
@@ -77,5 +92,21 @@ public final class SpeechRecognitionManagerService extends
service.createSessionLocked(componentName, clientToken, onDevice, callback);
}
}
+
+ @Override
+ public void setTemporaryComponent(ComponentName componentName) {
+ int userId = UserHandle.getCallingUserId();
+ if (componentName == null) {
+ resetTemporaryService(userId);
+ Slog.i(TAG, "Reset temporary service for user " + userId);
+ return;
+ }
+ setTemporaryService(
+ userId,
+ componentName.flattenToString(),
+ MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS);
+ Slog.i(TAG, "SpeechRecognition temporarily set to " + componentName + " for "
+ + MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS + "ms");
+ }
}
}
diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
index 2656a3d32555..769e049c8d0e 100644
--- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
@@ -100,6 +100,9 @@ final class SpeechRecognitionManagerServiceImpl extends
}
if (serviceComponent == null) {
+ if (mMaster.debug) {
+ Slog.i(TAG, "Service component is undefined, responding with error.");
+ }
tryRespondWithError(callback, SpeechRecognizer.ERROR_CLIENT);
return;
}
@@ -213,6 +216,10 @@ final class SpeechRecognitionManagerServiceImpl extends
@Nullable
private ComponentName getOnDeviceComponentNameLocked() {
final String serviceName = getComponentNameLocked();
+ if (mMaster.debug) {
+ Slog.i(TAG, "Resolved component name: " + serviceName);
+ }
+
if (serviceName == null) {
if (mMaster.verbose) {
Slog.v(TAG, "ensureRemoteServiceLocked(): no service component name.");
@@ -241,6 +248,11 @@ final class SpeechRecognitionManagerServiceImpl extends
service.getServiceComponentName().equals(serviceComponent))
.findFirst();
if (existingService.isPresent()) {
+
+ if (mMaster.debug) {
+ Slog.i(TAG, "Reused existing connection to " + serviceComponent);
+ }
+
return existingService.get();
}
}
@@ -253,6 +265,10 @@ final class SpeechRecognitionManagerServiceImpl extends
mRemoteServicesByUid.computeIfAbsent(callingUid, key -> new HashSet<>());
valuesByCaller.add(service);
+ if (mMaster.debug) {
+ Slog.i(TAG, "Creating a new connection to " + serviceComponent);
+ }
+
return service;
}
}
diff --git a/services/core/java/com/android/server/stats/OWNERS b/services/core/java/com/android/server/stats/OWNERS
index fc7fd220b26a..174ad3ad2e25 100644
--- a/services/core/java/com/android/server/stats/OWNERS
+++ b/services/core/java/com/android/server/stats/OWNERS
@@ -1,7 +1,10 @@
jeffreyhuang@google.com
joeo@google.com
+jtnguyen@google.com
muhammadq@google.com
+rslawik@google.com
ruchirr@google.com
+sharaienko@google.com
singhtejinder@google.com
tsaichristine@google.com
yaochen@google.com
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 7ed7a592a972..8023fd42edfa 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -148,11 +148,13 @@ import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeRead
import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader;
import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader;
import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader;
+import com.android.internal.os.KernelSingleProcessCpuThreadReader.ProcessCpuUsage;
import com.android.internal.os.KernelWakelockReader;
import com.android.internal.os.KernelWakelockStats;
import com.android.internal.os.LooperStats;
import com.android.internal.os.PowerProfile;
import com.android.internal.os.ProcessCpuTracker;
+import com.android.internal.os.SelectedProcessCpuThreadReader;
import com.android.internal.os.StoragedUidIoStatsReader;
import com.android.internal.os.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes;
import com.android.internal.util.CollectionUtils;
@@ -351,6 +353,8 @@ public class StatsPullAtomService extends SystemService {
@GuardedBy("mDataBytesTransferLock")
private final ArrayList<SubInfo> mHistoricalSubs = new ArrayList<>();
+ private SelectedProcessCpuThreadReader mSurfaceFlingerProcessCpuThreadReader;
+
// Puller locks
private final Object mDataBytesTransferLock = new Object();
private final Object mBluetoothBytesTransferLock = new Object();
@@ -753,6 +757,9 @@ public class StatsPullAtomService extends SystemService {
}
}
}
+
+ mSurfaceFlingerProcessCpuThreadReader =
+ new SelectedProcessCpuThreadReader("/system/bin/surfaceflinger");
}
void registerEventListeners() {
@@ -1479,7 +1486,7 @@ public class StatsPullAtomService extends SystemService {
}
for (int freqIndex = 0; freqIndex < timesMs.length; ++freqIndex) {
int cluster = freqsClusters[freqIndex];
- long freq = freqs[freqIndex];
+ int freq = (int) freqs[freqIndex];
long timeMs = timesMs[freqIndex];
pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, cluster, freq, timeMs));
}
@@ -1678,6 +1685,18 @@ public class StatsPullAtomService extends SystemService {
FrameworkStatsLog.CPU_CYCLES_PER_THREAD_GROUP_CLUSTER__THREAD_GROUP__SYSTEM_SERVER_BINDER,
times.binderThreadCpuTimesUs);
+ ProcessCpuUsage surfaceFlingerTimes = mSurfaceFlingerProcessCpuThreadReader.readAbsolute();
+ if (surfaceFlingerTimes != null && surfaceFlingerTimes.threadCpuTimesMillis != null) {
+ long[] surfaceFlingerTimesUs =
+ new long[surfaceFlingerTimes.threadCpuTimesMillis.length];
+ for (int i = 0; i < surfaceFlingerTimesUs.length; ++i) {
+ surfaceFlingerTimesUs[i] = surfaceFlingerTimes.threadCpuTimesMillis[i] * 1_000;
+ }
+ addCpuCyclesPerThreadGroupClusterAtoms(atomTag, pulledData,
+ FrameworkStatsLog.CPU_CYCLES_PER_THREAD_GROUP_CLUSTER__THREAD_GROUP__SURFACE_FLINGER,
+ surfaceFlingerTimesUs);
+ }
+
return StatsManager.PULL_SUCCESS;
}
diff --git a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
index 3ae9d641e81c..ee78a4e4d1cf 100644
--- a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
+++ b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java
@@ -28,8 +28,6 @@ import android.app.time.TimeZoneCapabilitiesAndConfig;
import android.app.time.TimeZoneConfiguration;
import android.os.UserHandle;
-import com.android.internal.util.Preconditions;
-
import java.util.Objects;
/**
@@ -39,7 +37,7 @@ import java.util.Objects;
*/
public final class ConfigurationInternal {
- private final boolean mAutoDetectionSupported;
+ private final boolean mTelephonyDetectionSupported;
private final boolean mGeoDetectionSupported;
private final boolean mAutoDetectionEnabled;
private final @UserIdInt int mUserId;
@@ -48,7 +46,7 @@ public final class ConfigurationInternal {
private final boolean mGeoDetectionEnabled;
private ConfigurationInternal(Builder builder) {
- mAutoDetectionSupported = builder.mAutoDetectionSupported;
+ mTelephonyDetectionSupported = builder.mTelephonyDetectionSupported;
mGeoDetectionSupported = builder.mGeoDetectionSupported;
mAutoDetectionEnabled = builder.mAutoDetectionEnabled;
@@ -56,14 +54,16 @@ public final class ConfigurationInternal {
mUserConfigAllowed = builder.mUserConfigAllowed;
mLocationEnabled = builder.mLocationEnabled;
mGeoDetectionEnabled = builder.mGeoDetectionEnabled;
- // if mGeoDetectionSupported then mAutoDetectionSupported, i.e. mGeoDetectionSupported
- // cannot be true if mAutoDetectionSupported == false
- Preconditions.checkState(mAutoDetectionSupported || !mGeoDetectionSupported);
}
/** Returns true if the device supports any form of auto time zone detection. */
public boolean isAutoDetectionSupported() {
- return mAutoDetectionSupported;
+ return mTelephonyDetectionSupported || mGeoDetectionSupported;
+ }
+
+ /** Returns true if the device supports telephony time zone detection. */
+ public boolean isTelephonyDetectionSupported() {
+ return mTelephonyDetectionSupported;
}
/** Returns true if the device supports geolocation time zone detection. */
@@ -78,9 +78,10 @@ public final class ConfigurationInternal {
/**
* Returns true if auto time zone detection behavior is actually enabled, which can be distinct
- * from the raw setting value. */
+ * from the raw setting value.
+ */
public boolean getAutoDetectionEnabledBehavior() {
- return mAutoDetectionSupported && mAutoDetectionEnabled;
+ return isAutoDetectionSupported() && mAutoDetectionEnabled;
}
/** Returns the ID of the user this configuration is associated with. */
@@ -212,7 +213,7 @@ public final class ConfigurationInternal {
ConfigurationInternal that = (ConfigurationInternal) o;
return mUserId == that.mUserId
&& mUserConfigAllowed == that.mUserConfigAllowed
- && mAutoDetectionSupported == that.mAutoDetectionSupported
+ && mTelephonyDetectionSupported == that.mTelephonyDetectionSupported
&& mGeoDetectionSupported == that.mGeoDetectionSupported
&& mAutoDetectionEnabled == that.mAutoDetectionEnabled
&& mLocationEnabled == that.mLocationEnabled
@@ -221,7 +222,7 @@ public final class ConfigurationInternal {
@Override
public int hashCode() {
- return Objects.hash(mUserId, mUserConfigAllowed, mAutoDetectionSupported,
+ return Objects.hash(mUserId, mUserConfigAllowed, mTelephonyDetectionSupported,
mGeoDetectionSupported, mAutoDetectionEnabled, mLocationEnabled,
mGeoDetectionEnabled);
}
@@ -231,7 +232,7 @@ public final class ConfigurationInternal {
return "ConfigurationInternal{"
+ "mUserId=" + mUserId
+ ", mUserConfigAllowed=" + mUserConfigAllowed
- + ", mAutoDetectionSupported=" + mAutoDetectionSupported
+ + ", mTelephonyDetectionSupported=" + mTelephonyDetectionSupported
+ ", mGeoDetectionSupported=" + mGeoDetectionSupported
+ ", mAutoDetectionEnabled=" + mAutoDetectionEnabled
+ ", mLocationEnabled=" + mLocationEnabled
@@ -247,7 +248,7 @@ public final class ConfigurationInternal {
private final @UserIdInt int mUserId;
private boolean mUserConfigAllowed;
- private boolean mAutoDetectionSupported;
+ private boolean mTelephonyDetectionSupported;
private boolean mGeoDetectionSupported;
private boolean mAutoDetectionEnabled;
private boolean mLocationEnabled;
@@ -266,7 +267,7 @@ public final class ConfigurationInternal {
public Builder(ConfigurationInternal toCopy) {
this.mUserId = toCopy.mUserId;
this.mUserConfigAllowed = toCopy.mUserConfigAllowed;
- this.mAutoDetectionSupported = toCopy.mAutoDetectionSupported;
+ this.mTelephonyDetectionSupported = toCopy.mTelephonyDetectionSupported;
this.mGeoDetectionSupported = toCopy.mGeoDetectionSupported;
this.mAutoDetectionEnabled = toCopy.mAutoDetectionEnabled;
this.mLocationEnabled = toCopy.mLocationEnabled;
@@ -282,10 +283,10 @@ public final class ConfigurationInternal {
}
/**
- * Sets whether any form of automatic time zone detection is supported on this device.
+ * Sets whether telephony time zone detection is supported on this device.
*/
- public Builder setAutoDetectionFeatureSupported(boolean supported) {
- mAutoDetectionSupported = supported;
+ public Builder setTelephonyDetectionFeatureSupported(boolean supported) {
+ mTelephonyDetectionSupported = supported;
return this;
}
diff --git a/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java b/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java
index e3caae9482d9..0e5f3bfbb4b1 100644
--- a/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/EnvironmentImpl.java
@@ -128,8 +128,8 @@ public final class EnvironmentImpl implements TimeZoneDetectorStrategyImpl.Envir
@Override
public ConfigurationInternal getConfigurationInternal(@UserIdInt int userId) {
return new ConfigurationInternal.Builder(userId)
- .setAutoDetectionFeatureSupported(
- mServiceConfigAccessor.isAutoDetectionFeatureSupported())
+ .setTelephonyDetectionFeatureSupported(
+ mServiceConfigAccessor.isTelephonyTimeZoneDetectionFeatureSupported())
.setGeoDetectionFeatureSupported(
mServiceConfigAccessor.isGeoTimeZoneDetectionFeatureSupported())
.setAutoDetectionEnabled(isAutoDetectionEnabled())
diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
index 86c32f8d7b45..2452c8d3ddc9 100644
--- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
+++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessor.java
@@ -115,10 +115,15 @@ public final class ServiceConfigAccessor {
/** Returns {@code true} if any form of automatic time zone detection is supported. */
public boolean isAutoDetectionFeatureSupported() {
- return deviceHasTelephonyNetwork() || isGeoTimeZoneDetectionFeatureSupported();
+ return isTelephonyTimeZoneDetectionFeatureSupported()
+ || isGeoTimeZoneDetectionFeatureSupported();
}
- private boolean deviceHasTelephonyNetwork() {
+ /**
+ * Returns {@code true} if the telephony-based time zone detection feature is supported on the
+ * device.
+ */
+ public boolean isTelephonyTimeZoneDetectionFeatureSupported() {
// TODO b/150583524 Avoid the use of a deprecated API.
return mContext.getSystemService(ConnectivityManager.class)
.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
index 2d5dacdd6acc..7ba20eee0392 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorInternalImpl.java
@@ -86,7 +86,7 @@ public final class TimeZoneDetectorInternalImpl implements TimeZoneDetectorInter
@NonNull GeolocationTimeZoneSuggestion timeZoneSuggestion) {
Objects.requireNonNull(timeZoneSuggestion);
- // All strategy calls must take place on the mHandler thread.
+ // This call can take place on the mHandler thread because there is no return value.
mHandler.post(
() -> mTimeZoneDetectorStrategy.suggestGeolocationTimeZone(timeZoneSuggestion));
}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
index d163a0e22320..2e96a1065af4 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
@@ -195,6 +195,13 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
private ReferenceWithHistory<GeolocationTimeZoneSuggestion> mLatestGeoLocationSuggestion =
new ReferenceWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
+ /**
+ * The latest manual suggestion received.
+ */
+ @GuardedBy("this")
+ private ReferenceWithHistory<ManualTimeZoneSuggestion> mLatestManualSuggestion =
+ new ReferenceWithHistory<>(KEEP_SUGGESTION_HISTORY_SIZE);
+
@GuardedBy("this")
private final List<Dumpable> mDumpables = new ArrayList<>();
@@ -286,6 +293,7 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
if (currentUserConfig.getGeoDetectionEnabledBehavior()) {
// Only store a geolocation suggestion if geolocation detection is currently enabled.
+ // See also clearGeolocationSuggestionIfNeeded().
mLatestGeoLocationSuggestion.set(suggestion);
// Now perform auto time zone detection. The new suggestion may be used to modify the
@@ -324,6 +332,12 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
return false;
}
+ // Record the manual suggestion for debugging / metrics (but only if manual detection is
+ // currently enabled).
+ // Note: This is not used to set the device back to a previous manual suggestion if the user
+ // later disables automatic time zone detection.
+ mLatestManualSuggestion.set(suggestion);
+
setDeviceTimeZoneIfRequired(timeZoneId, cause);
return true;
}
@@ -619,6 +633,11 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
mTimeZoneChangesLog.dump(ipw);
ipw.decreaseIndent(); // level 2
+ ipw.println("Manual suggestion history:");
+ ipw.increaseIndent(); // level 2
+ mLatestManualSuggestion.dump(ipw);
+ ipw.decreaseIndent(); // level 2
+
ipw.println("Geolocation suggestion history:");
ipw.increaseIndent(); // level 2
mLatestGeoLocationSuggestion.dump(ipw);
@@ -639,6 +658,14 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
* A method used to inspect strategy state during tests. Not intended for general use.
*/
@VisibleForTesting
+ public synchronized ManualTimeZoneSuggestion getLatestManualSuggestion() {
+ return mLatestManualSuggestion.get();
+ }
+
+ /**
+ * A method used to inspect strategy state during tests. Not intended for general use.
+ */
+ @VisibleForTesting
public synchronized QualifiedTelephonyTimeZoneSuggestion getLatestTelephonySuggestion(
int slotIndex) {
return mTelephonySuggestionsBySlotIndex.get(slotIndex);
diff --git a/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java b/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java
index c0c9e6d58622..417a6368be4c 100644
--- a/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java
+++ b/services/core/java/com/android/server/timezonedetector/location/BinderLocationTimeZoneProvider.java
@@ -39,15 +39,13 @@ import java.util.Objects;
*/
class BinderLocationTimeZoneProvider extends LocationTimeZoneProvider {
- private static final String TAG = LocationTimeZoneManagerService.TAG;
-
@NonNull private final LocationTimeZoneProviderProxy mProxy;
BinderLocationTimeZoneProvider(
@NonNull ThreadingDomain threadingDomain,
@NonNull String providerName,
@NonNull LocationTimeZoneProviderProxy proxy) {
- super(threadingDomain, providerName);
+ super(threadingDomain, providerName, new ZoneInfoDbTimeZoneIdValidator());
mProxy = Objects.requireNonNull(proxy);
}
diff --git a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java
index 0d1692a8781d..588382158bc9 100644
--- a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java
+++ b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneManagerService.java
@@ -520,6 +520,12 @@ public class LocationTimeZoneManagerService extends Binder {
}
}
+ static void infoLog(String msg) {
+ if (Log.isLoggable(TAG, Log.INFO)) {
+ Slog.i(TAG, msg);
+ }
+ }
+
static void warnLog(String msg) {
warnLog(msg, null);
}
diff --git a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java
index ef2f357b8c3e..b97c838017eb 100644
--- a/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java
+++ b/services/core/java/com/android/server/timezonedetector/location/LocationTimeZoneProvider.java
@@ -20,6 +20,7 @@ import static android.service.timezone.TimeZoneProviderService.TEST_COMMAND_RESU
import static android.service.timezone.TimeZoneProviderService.TEST_COMMAND_RESULT_SUCCESS_KEY;
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.debugLog;
+import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.infoLog;
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.warnLog;
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_DESTROYED;
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_PERM_FAILED;
@@ -85,6 +86,18 @@ abstract class LocationTimeZoneProvider implements Dumpable {
}
/**
+ * Used by {@link LocationTimeZoneProvider} to check if time zone IDs are understood
+ * by the platform.
+ */
+ interface TimeZoneIdValidator {
+
+ /**
+ * Returns whether {@code timeZoneId} is supported by the platform or not.
+ */
+ boolean isValid(@NonNull String timeZoneId);
+ }
+
+ /**
* Information about the provider's current state.
*/
static class ProviderState {
@@ -364,13 +377,17 @@ abstract class LocationTimeZoneProvider implements Dumpable {
// Non-null and effectively final after initialize() is called.
ProviderListener mProviderListener;
+ @NonNull private TimeZoneIdValidator mTimeZoneIdValidator;
+
/** Creates the instance. */
LocationTimeZoneProvider(@NonNull ThreadingDomain threadingDomain,
- @NonNull String providerName) {
+ @NonNull String providerName,
+ @NonNull TimeZoneIdValidator timeZoneIdValidator) {
mThreadingDomain = Objects.requireNonNull(threadingDomain);
mInitializationTimeoutQueue = threadingDomain.createSingleRunnableQueue();
mSharedLock = threadingDomain.getLockObject();
mProviderName = Objects.requireNonNull(providerName);
+ mTimeZoneIdValidator = Objects.requireNonNull(timeZoneIdValidator);
}
/**
@@ -610,6 +627,25 @@ abstract class LocationTimeZoneProvider implements Dumpable {
mThreadingDomain.assertCurrentThread();
Objects.requireNonNull(timeZoneProviderEvent);
+ // If the provider has made a suggestion with unknown time zone IDs it cannot be used to set
+ // the device's time zone. This logic prevents bad time zone IDs entering the time zone
+ // detection logic from third party code.
+ //
+ // An event containing an unknown time zone ID could occur if the provider is using a
+ // different TZDB version than the device. Provider developers are expected to take steps to
+ // avoid version skew problem, e.g. by ensuring atomic updates with the platform time zone
+ // rules, or providing IDs based on the device's TZDB version, so this is not considered a
+ // common case.
+ //
+ // Treating a suggestion containing unknown time zone IDs as "uncertain" in the primary
+ // enables immediate failover to a secondary provider, one that might provide valid IDs for
+ // the same location, which should provide better behavior than just ignoring the event.
+ if (hasInvalidTimeZones(timeZoneProviderEvent)) {
+ infoLog("event=" + timeZoneProviderEvent + " has unsupported time zones. "
+ + "Replacing it with uncertain event.");
+ timeZoneProviderEvent = TimeZoneProviderEvent.createUncertainEvent();
+ }
+
synchronized (mSharedLock) {
debugLog("handleTimeZoneProviderEvent: mProviderName=" + mProviderName
+ ", timeZoneProviderEvent=" + timeZoneProviderEvent);
@@ -707,6 +743,20 @@ abstract class LocationTimeZoneProvider implements Dumpable {
}
}
+ private boolean hasInvalidTimeZones(@NonNull TimeZoneProviderEvent event) {
+ if (event.getSuggestion() == null) {
+ return false;
+ }
+
+ for (String timeZone : event.getSuggestion().getTimeZoneIds()) {
+ if (!mTimeZoneIdValidator.isValid(timeZone)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
@GuardedBy("mSharedLock")
private void assertIsStarted() {
ProviderState currentState = mCurrentState.get();
diff --git a/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java b/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
new file mode 100644
index 000000000000..cab5ad25c54e
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timezonedetector.location;
+
+import android.annotation.NonNull;
+
+import com.android.i18n.timezone.ZoneInfoDb;
+
+class ZoneInfoDbTimeZoneIdValidator implements
+ LocationTimeZoneProvider.TimeZoneIdValidator {
+
+ @Override
+ public boolean isValid(@NonNull String timeZoneId) {
+ return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
+ }
+}
diff --git a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
index b2db9f5af07e..8dcc547508ec 100644
--- a/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
+++ b/services/core/java/com/android/server/vcn/UnderlyingNetworkTracker.java
@@ -23,7 +23,6 @@ import android.net.ConnectivityManager.NetworkCallback;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
-import android.net.NetworkCapabilities.NetCapability;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.os.Handler;
@@ -115,33 +114,61 @@ public class UnderlyingNetworkTracker {
getWifiNetworkRequest(), mHandler, mWifiBringupCallback);
updateSubIdsAndCellularRequests();
- // register Network-selection request used to decide selected underlying Network
+ // Register Network-selection request used to decide selected underlying Network. All
+ // underlying networks must be VCN managed in order to be used.
mConnectivityManager.requestBackgroundNetwork(
- getNetworkRequestBase().build(), mHandler, mRouteSelectionCallback);
+ getBaseNetworkRequest(true /* requireVcnManaged */).build(),
+ mHandler,
+ mRouteSelectionCallback);
}
private NetworkRequest getWifiNetworkRequest() {
- return getNetworkRequestBase().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build();
+ // Request exclusively VCN managed networks to ensure that we only ever keep carrier wifi
+ // alive.
+ return getBaseNetworkRequest(true /* requireVcnManaged */)
+ .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ .build();
}
private NetworkRequest getCellNetworkRequestForSubId(int subId) {
- return getNetworkRequestBase()
+ // Do not request NOT_VCN_MANAGED to ensure that the TelephonyNetworkFactory has a
+ // fulfillable request to bring up underlying cellular Networks even if the VCN is already
+ // connected.
+ return getBaseNetworkRequest(false /* requireVcnManaged */)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId))
.build();
}
- private NetworkRequest.Builder getNetworkRequestBase() {
- NetworkRequest.Builder requestBase = new NetworkRequest.Builder();
- for (@NetCapability int capability : mRequiredUnderlyingNetworkCapabilities) {
+ /**
+ * Builds and returns a NetworkRequest builder common to all Underlying Network requests
+ *
+ * <p>A NetworkRequest may either (1) Require the presence of a capability by using
+ * addCapability(), (2) require the absence of a capability using unwanted capabilities, or (3)
+ * allow any state. Underlying networks are never desired to have the NOT_VCN_MANAGED
+ * capability, and only cases (2) and (3) are used.
+ *
+ * @param requireVcnManaged whether the underlying network is required to be VCN managed to
+ * match this request. If {@code true}, the NOT_VCN_MANAGED capability will be set as
+ * unwanted. Else, the NOT_VCN_MANAGED capability will be removed, and any state is
+ * acceptable.
+ */
+ private NetworkRequest.Builder getBaseNetworkRequest(boolean requireVcnManaged) {
+ NetworkRequest.Builder requestBase =
+ new NetworkRequest.Builder()
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+
+ for (int capability : mRequiredUnderlyingNetworkCapabilities) {
requestBase.addCapability(capability);
}
- return requestBase
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
- .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ if (requireVcnManaged) {
+ requestBase.addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ }
+
+ return requestBase;
}
/**
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index c55913e2e547..3f74938005a7 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -299,9 +299,7 @@ public class Vcn extends Handler {
for (VcnGatewayConnectionConfig gatewayConnectionConfig :
mConfig.getGatewayConnectionConfigs()) {
if (isRequestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
- Slog.v(
- getLogTag(),
- "Bringing up new VcnGatewayConnection for request " + request.requestId);
+ Slog.v(getLogTag(), "Bringing up new VcnGatewayConnection for request " + request);
final VcnGatewayConnection vcnGatewayConnection =
mDeps.newVcnGatewayConnection(
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 6bc9978a0731..69a153f79a1b 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -20,6 +20,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.vcn.VcnManager.VCN_ERROR_CODE_CONFIG_ERROR;
@@ -59,6 +60,7 @@ import android.net.ipsec.ike.exceptions.AuthenticationFailedException;
import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeInternalException;
import android.net.ipsec.ike.exceptions.IkeProtocolException;
+import android.net.vcn.VcnControlPlaneIkeConfig;
import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
@@ -979,7 +981,7 @@ public class VcnGatewayConnection extends StateMachine {
// IkeSessionCallback.onClosedExceptionally(), which calls sessionClosed()
if (exception != null) {
mGatewayStatusCallback.onGatewayConnectionError(
- mConnectionConfig.getRequiredUnderlyingCapabilities(),
+ mConnectionConfig.getExposedCapabilities(),
VCN_ERROR_CODE_INTERNAL_ERROR,
RuntimeException.class.getName(),
"Received "
@@ -1016,7 +1018,7 @@ public class VcnGatewayConnection extends StateMachine {
}
mGatewayStatusCallback.onGatewayConnectionError(
- mConnectionConfig.getRequiredUnderlyingCapabilities(),
+ mConnectionConfig.getExposedCapabilities(),
errorCode,
exceptionClass,
exceptionMessage);
@@ -1348,7 +1350,7 @@ public class VcnGatewayConnection extends StateMachine {
mIkeSession = null;
}
- mIkeSession = buildIkeSession();
+ mIkeSession = buildIkeSession(mUnderlying.network);
}
@Override
@@ -1726,6 +1728,7 @@ public class VcnGatewayConnection extends StateMachine {
final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
builder.addTransportType(TRANSPORT_CELLULAR);
+ builder.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
builder.addCapability(NET_CAPABILITY_NOT_CONGESTED);
builder.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
@@ -1939,23 +1942,29 @@ public class VcnGatewayConnection extends StateMachine {
new EventDisconnectRequestedInfo(reason, shouldQuit));
}
- private IkeSessionParams buildIkeParams() {
- // TODO: Implement this once IkeSessionParams is persisted
- return null;
+ private IkeSessionParams buildIkeParams(@NonNull Network network) {
+ final VcnControlPlaneIkeConfig controlPlaneConfig =
+ (VcnControlPlaneIkeConfig) mConnectionConfig.getControlPlaneConfig();
+ final IkeSessionParams.Builder builder =
+ new IkeSessionParams.Builder(controlPlaneConfig.getIkeSessionParams());
+ builder.setConfiguredNetwork(network);
+
+ return builder.build();
}
private ChildSessionParams buildChildParams() {
- // TODO: Implement this once IkeSessionParams is persisted
- return null;
+ final VcnControlPlaneIkeConfig controlPlaneConfig =
+ (VcnControlPlaneIkeConfig) mConnectionConfig.getControlPlaneConfig();
+ return controlPlaneConfig.getChildSessionParams();
}
@VisibleForTesting(visibility = Visibility.PRIVATE)
- VcnIkeSession buildIkeSession() {
+ VcnIkeSession buildIkeSession(@NonNull Network network) {
final int token = ++mCurrentToken;
return mDeps.newIkeSession(
mVcnContext,
- buildIkeParams(),
+ buildIkeParams(network),
buildChildParams(),
new IkeSessionCallbackImpl(token),
new VcnChildSessionCallback(token));
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 5446a39fad86..aeeabe21460c 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
@@ -84,8 +85,12 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VER
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.content.pm.ActivityInfo.SIZE_CHANGES_SUPPORTED_METADATA;
+import static android.content.pm.ActivityInfo.SIZE_CHANGES_SUPPORTED_OVERRIDE;
+import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_OVERRIDE;
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.res.Configuration.EMPTY;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -205,6 +210,7 @@ import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainerChildProto.ACTIVITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -278,6 +284,7 @@ import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.os.storage.StorageManager;
+import android.permission.PermissionManager;
import android.service.dreams.DreamActivity;
import android.service.dreams.DreamManagerInternal;
import android.service.voice.IVoiceInteractionSession;
@@ -6815,8 +6822,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* aspect ratio.
*/
boolean shouldCreateCompatDisplayInsets() {
- if (info.supportsSizeChanges() != ActivityInfo.SIZE_CHANGES_UNSUPPORTED) {
- return false;
+ switch (info.supportsSizeChanges()) {
+ case SIZE_CHANGES_SUPPORTED_METADATA:
+ case SIZE_CHANGES_SUPPORTED_OVERRIDE:
+ return false;
+ case SIZE_CHANGES_UNSUPPORTED_OVERRIDE:
+ return true;
+ default:
+ // Fall through
}
if (inMultiWindowMode() || getWindowConfiguration().hasWindowDecorCaption()) {
final ActivityRecord root = task != null ? task.getRootActivity() : null;
@@ -6955,6 +6968,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// layout traversals.
mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
getResolvedOverrideConfiguration().seq = mConfigurationSeq;
+
+ // Sandbox max bounds by setting it to the app bounds, if activity is letterboxed or in
+ // size compat mode.
+ if (providesMaxBounds()) {
+ if (DEBUG_CONFIGURATION) {
+ ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds for uid %s to bounds %s "
+ + "due to letterboxing from mismatch with parent bounds? %s size compat "
+ + "mode %s", getUid(),
+ resolvedConfig.windowConfiguration.getBounds(), !matchParentBounds(),
+ inSizeCompatMode());
+ }
+ resolvedConfig.windowConfiguration
+ .setMaxBounds(resolvedConfig.windowConfiguration.getBounds());
+ }
}
/**
@@ -7296,6 +7323,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return super.getBounds();
}
+ @Override
+ public boolean providesMaxBounds() {
+ // System and SystemUI should always be able to access the physical display bounds,
+ // so do not provide it with the overridden maximum bounds.
+ // TODO(b/179179513) check WindowState#mOwnerCanAddInternalSystemWindow instead
+ if (getUid() == SYSTEM_UID || PermissionManager.checkPermission(INTERNAL_SYSTEM_WINDOW,
+ getPid(), info.applicationInfo.uid) == PERMISSION_GRANTED) {
+ return false;
+ }
+ // Max bounds should be sandboxed where an activity is letterboxed (activity bounds will be
+ // smaller than task bounds) or put in size compat mode.
+ return !matchParentBounds() || inSizeCompatMode();
+ }
+
@VisibleForTesting
@Override
Rect getAnimationBounds(int appRootTaskClipMode) {
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 62a00802896f..8fbe1775fd19 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -367,8 +367,7 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
* Returns {@code true} if this {@link ConfigurationContainer} provides the maximum bounds to
* its child {@link ConfigurationContainer}s. Returns {@code false}, otherwise.
* <p>
- * The maximum bounds is how large a window can be expanded. Currently only
- * {@link DisplayContent} and {@link DisplayArea} effect this property.
+ * The maximum bounds is how large a window can be expanded.
* </p>
*/
protected boolean providesMaxBounds() {
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 42cb96f65738..6fc585e473a9 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -104,11 +104,11 @@ class RemoteAnimationController implements DeathRecipient {
*/
void goodToGo(@WindowManager.TransitionOldType int transit) {
ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo()");
- if (mPendingAnimations.isEmpty() || mCanceled) {
+ if (mCanceled) {
ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS,
- "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d",
- mCanceled, mPendingAnimations.size());
+ "goodToGo(): Animation canceled already");
onAnimationFinished();
+ invokeAnimationCancelled();
return;
}
@@ -120,8 +120,11 @@ class RemoteAnimationController implements DeathRecipient {
// Create the app targets
final RemoteAnimationTarget[] appTargets = createAppAnimations();
if (appTargets.length == 0) {
- ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo(): No apps to animate");
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS,
+ "goodToGo(): No apps to animate, mPendingAnimations=%d",
+ mPendingAnimations.size());
onAnimationFinished();
+ invokeAnimationCancelled();
return;
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index d992a4591a22..04a254c2aabf 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -5245,17 +5245,29 @@ class Task extends WindowContainer<WindowContainer> {
if (mForceHiddenFlags == newFlags) {
return false;
}
+
final boolean wasHidden = isForceHidden();
+ final boolean wasVisible = isVisible();
mForceHiddenFlags = newFlags;
- if (wasHidden != isForceHidden() && isTopActivityFocusable()) {
- // The change in force-hidden state will change visibility without triggering a root
- // task order change, so we should reset the preferred top focusable root task to ensure
- // it's not used if a new activity is started from this task.
- getDisplayArea().resetPreferredTopFocusableRootTaskIfNeeded(this);
+ final boolean nowHidden = isForceHidden();
+ if (wasHidden != nowHidden) {
+ final String reason = "setForceHidden";
+ if (wasVisible && nowHidden) {
+ // Move this visible task to back when the task is forced hidden
+ moveToBack(reason, null);
+ } else if (isAlwaysOnTop()) {
+ // Move this always-on-top task to front when no longer hidden
+ moveToFront(reason);
+ }
}
return true;
}
+ @Override
+ public boolean isAlwaysOnTop() {
+ return !isForceHidden() && super.isAlwaysOnTop();
+ }
+
/**
* Returns whether this task is currently forced to be hidden for any reason.
*/
@@ -7482,17 +7494,22 @@ class Task extends WindowContainer<WindowContainer> {
}
public void setAlwaysOnTop(boolean alwaysOnTop) {
- if (isAlwaysOnTop() == alwaysOnTop) {
+ // {@link #isAwaysonTop} overrides the original behavior which also evaluates if this
+ // task is force hidden, so super.isAlwaysOnTop() is used here to see whether the
+ // alwaysOnTop attributes should be updated.
+ if (super.isAlwaysOnTop() == alwaysOnTop) {
return;
}
super.setAlwaysOnTop(alwaysOnTop);
- final TaskDisplayArea taskDisplayArea = getDisplayArea();
// positionChildAtTop() must be called even when always on top gets turned off because we
// need to make sure that the root task is moved from among always on top windows to
// below other always on top windows. Since the position the root task should be inserted
// into is calculated properly in {@link DisplayContent#getTopInsertPosition()} in both
// cases, we can just request that the root task is put at top here.
- taskDisplayArea.positionChildAt(POSITION_TOP, this, false /* includingParents */);
+ // Don't bother moving task to top if this task is force hidden and invisible to user.
+ if (!isForceHidden()) {
+ getDisplayArea().positionChildAt(POSITION_TOP, this, false /* includingParents */);
+ }
}
void dismissPip() {
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index ed92fd08bef5..91aa48effe84 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -393,7 +393,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
final boolean moveToBottom = position <= 0;
final int oldPosition = mChildren.indexOf(child);
- if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
+ if (child.isAlwaysOnTop() && !moveToTop) {
// This root task is always-on-top, override the default behavior.
Slog.w(TAG_WM, "Ignoring move of always-on-top root task=" + this + " to bottom");
@@ -974,14 +974,6 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
onRootTaskOrderChanged(rootTask);
}
- /** Reset the mPreferredTopFocusableRootTask if it is or below the given task. */
- void resetPreferredTopFocusableRootTaskIfNeeded(Task task) {
- if (mPreferredTopFocusableRootTask != null
- && mPreferredTopFocusableRootTask.compareTo(task) <= 0) {
- mPreferredTopFocusableRootTask = null;
- }
- }
-
/**
* Moves/reparents `task` to the back of whatever container the root home task is in. This is
* for when we just want to move a task to "the back" vs. a specific place. The primary use-case
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6f853c795525..3ddb6fc84cd8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -273,7 +273,6 @@ import android.window.TaskSnapshot;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.os.BackgroundThread;
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
@@ -529,14 +528,6 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
boolean asProto) {
- // Bugreport dumps the trace 2x, 1x as proto and 1x as text. Save file to disk only 1x.
- if (asProto && mWindowTracing.isEnabled()) {
- mWindowTracing.stopTrace(null, false /* writeToFile */);
- BackgroundThread.getHandler().post(() -> {
- mWindowTracing.writeTraceToFile();
- mWindowTracing.startTrace(null);
- });
- }
doDump(fd, pw, new String[] {"-a"}, asProto);
}
diff --git a/services/core/java/com/android/server/wm/WindowTracing.java b/services/core/java/com/android/server/wm/WindowTracing.java
index e8b8bfce21a3..0bb97f560a1c 100644
--- a/services/core/java/com/android/server/wm/WindowTracing.java
+++ b/services/core/java/com/android/server/wm/WindowTracing.java
@@ -114,15 +114,6 @@ class WindowTracing {
* @param pw Print writer
*/
void stopTrace(@Nullable PrintWriter pw) {
- stopTrace(pw, true /* writeToFile */);
- }
-
- /**
- * Stops the trace
- * @param pw Print writer
- * @param writeToFile If the current buffer should be written to disk or not
- */
- void stopTrace(@Nullable PrintWriter pw, boolean writeToFile) {
if (IS_USER) {
logAndPrintln(pw, "Error: Tracing is not supported on user builds.");
return;
@@ -135,12 +126,35 @@ class WindowTracing {
logAndPrintln(pw, "ERROR: tracing was re-enabled while waiting for flush.");
throw new IllegalStateException("tracing enabled while waiting for flush.");
}
- if (writeToFile) {
- writeTraceToFileLocked();
- logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
+ writeTraceToFileLocked();
+ logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
+ }
+ ProtoLogImpl.getSingleInstance().stopProtoLog(pw, true);
+ }
+
+ /**
+ * Stops the trace and write the current buffer to disk then restart, if it's already running.
+ * @param pw Print writer
+ */
+ void saveForBugreport(@Nullable PrintWriter pw) {
+ if (IS_USER) {
+ logAndPrintln(pw, "Error: Tracing is not supported on user builds.");
+ return;
+ }
+ synchronized (mEnabledLock) {
+ if (!mEnabled) {
+ return;
}
+ mEnabled = mEnabledLockFree = false;
+ logAndPrintln(pw, "Stop tracing to " + mTraceFile + ". Waiting for traces to flush.");
+ writeTraceToFileLocked();
+ logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
+ ProtoLogImpl.getSingleInstance().stopProtoLog(pw, true);
+ logAndPrintln(pw, "Start tracing to " + mTraceFile + ".");
+ mBuffer.resetBuffer();
+ mEnabled = mEnabledLockFree = true;
+ ProtoLogImpl.getSingleInstance().startProtoLog(pw);
}
- ProtoLogImpl.getSingleInstance().stopProtoLog(pw, writeToFile);
}
private void setLogLevel(@WindowTraceLogLevel int logLevel, PrintWriter pw) {
@@ -188,6 +202,9 @@ class WindowTracing {
case "stop":
stopTrace(pw);
return 0;
+ case "save-for-bugreport":
+ saveForBugreport(pw);
+ return 0;
case "status":
logAndPrintln(pw, getStatus());
return 0;
@@ -230,6 +247,7 @@ class WindowTracing {
pw.println("Window manager trace options:");
pw.println(" start: Start logging");
pw.println(" stop: Stop logging");
+ pw.println(" save-for-bugreport: Save logging data to file if it's running.");
pw.println(" frame: Log trace once per frame");
pw.println(" transaction: Log each transaction");
pw.println(" size: Set the maximum log size (in KB)");
@@ -316,19 +334,6 @@ class WindowTracing {
}
}
- /**
- * Writes the trace buffer to new file for the bugreport.
- *
- * This method is synchronized with {@code #startTrace(PrintWriter)} and
- * {@link #stopTrace(PrintWriter)}.
- */
- void writeTraceToFile() {
- synchronized (mEnabledLock) {
- writeTraceToFileLocked();
- }
- ProtoLogImpl.getSingleInstance().writeProtoLogToFile();
- }
-
private void logAndPrintln(@Nullable PrintWriter pw, String msg) {
Log.i(TAG, msg);
if (pw != null) {
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 29bce792fe30..0a02a86e71a6 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -49,7 +49,6 @@ cc_library_static {
"com_android_server_net_NetworkStatsService.cpp",
"com_android_server_power_PowerManagerService.cpp",
"com_android_server_powerstats_PowerStatsService.cpp",
- "com_android_server_security_VerityUtils.cpp",
"com_android_server_SerialService.cpp",
"com_android_server_soundtrigger_middleware_AudioSessionProviderImpl.cpp",
"com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker.cpp",
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 1815f0cd44c9..03a01523b8e2 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -52,7 +52,6 @@ int register_android_server_SyntheticPasswordManager(JNIEnv* env);
int register_android_hardware_display_DisplayViewport(JNIEnv* env);
int register_android_server_net_NetworkStatsFactory(JNIEnv* env);
int register_android_server_net_NetworkStatsService(JNIEnv* env);
-int register_android_server_security_VerityUtils(JNIEnv* env);
int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
int register_android_server_am_LowMemDetector(JNIEnv* env);
int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(JNIEnv* env);
@@ -106,7 +105,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_hardware_display_DisplayViewport(env);
register_android_server_net_NetworkStatsFactory(env);
register_android_server_net_NetworkStatsService(env);
- register_android_server_security_VerityUtils(env);
register_android_server_am_CachedAppOptimizer(env);
register_android_server_am_LowMemDetector(env);
register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(env);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index a3dadd835202..1590ef1c4cb9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -473,7 +473,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
// to decide whether an existing policy in the {@link #DEVICE_POLICIES_XML} needs to
// be upgraded. See {@link PolicyVersionUpgrader} on instructions how to add an upgrade
// step.
- static final int DPMS_VERSION = 1;
+ static final int DPMS_VERSION = 2;
static {
SECURE_SETTINGS_ALLOWLIST = new ArraySet<>();
@@ -2969,8 +2969,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
private class DpmsUpgradeDataProvider implements PolicyUpgraderDataProvider {
@Override
- public boolean isUserDeviceOwner(int userId) {
- return mOwners.isDeviceOwnerUserId(userId);
+ public boolean isUserDeviceOwner(int userId, ComponentName who) {
+ return mOwners.isDeviceOwnerUserId(userId)
+ && mOwners.getDeviceOwnerComponent().equals(who);
}
@Override
@@ -9329,6 +9330,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
dumpResources(pw, mContext, "vendor_cross_profile_apps", R.array.vendor_cross_profile_apps);
dumpResources(pw, mContext, "config_packagesExemptFromSuspension",
R.array.config_packagesExemptFromSuspension);
+ dumpResources(pw, mContext, "policy_exempt_apps", R.array.policy_exempt_apps);
+ dumpResources(pw, mContext, "vendor_policy_exempt_apps", R.array.vendor_policy_exempt_apps);
pw.decreaseIndent();
pw.println();
}
@@ -14214,10 +14217,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
enforceCallerSystemUserHandle();
- // no effect if it's called from user build
- if (!mInjector.isBuildDebuggable()) {
- return;
- }
final int userId = UserHandle.USER_SYSTEM;
boolean isUserCompleted = mInjector.settingsSecureGetIntForUser(
Settings.Secure.USER_SETUP_COMPLETE, 0, userId) != 0;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java
index b6420f8ff4bc..c20d0f5f5f5f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyUpgraderDataProvider.java
@@ -33,7 +33,7 @@ public interface PolicyUpgraderDataProvider {
* Returns true if the provided {@code userId} is a device owner. May affect some policy
* defaults.
*/
- boolean isUserDeviceOwner(int userId);
+ boolean isUserDeviceOwner(int userId, ComponentName who);
/**
* Returns true if the storage manager indicates file-based encryption is enabled.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java
index cea08634910c..2ab4b66a6831 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java
@@ -83,6 +83,27 @@ public class PolicyVersionUpgrader {
currentVersion = 1;
}
+ if (currentVersion == 1) {
+ Slog.i(LOG_TAG, String.format("Upgrading from version %d", currentVersion));
+ // This upgrade step is for Device Owner scenario only: For devices upgrading to S,
+ // if there is a device owner, it retains the ability to control sensors-related
+ // permission grants.
+ for (int userId : allUsers) {
+ DevicePolicyData userData = allUsersData.get(userId);
+ if (userData == null) {
+ continue;
+ }
+ for (ActiveAdmin admin : userData.mAdminList) {
+ if (mProvider.isUserDeviceOwner(userId, admin.info.getComponent())) {
+ Slog.i(LOG_TAG, String.format(
+ "Marking Device Owner in user %d for permission grant ", userId));
+ admin.mAdminCanGrantSensorsPermissions = true;
+ }
+ }
+ }
+ currentVersion = 2;
+ }
+
writePoliciesAndVersion(allUsers, allUsersData, currentVersion);
}
diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp
index 5ffbd771764d..5140b9f6db58 100644
--- a/services/incremental/Android.bp
+++ b/services/incremental/Android.bp
@@ -68,6 +68,7 @@ cc_defaults {
"libutils",
"libvold_binder",
"libc++fs",
+ "libziparchive_for_incfs",
],
shared_libs: [
"libandroidfw",
@@ -77,7 +78,6 @@ cc_defaults {
"libincfs",
"liblog",
"libz",
- "libziparchive",
],
}
diff --git a/services/incremental/BinderIncrementalService.cpp b/services/incremental/BinderIncrementalService.cpp
index 42360d82afe9..8f12b2e5c132 100644
--- a/services/incremental/BinderIncrementalService.cpp
+++ b/services/incremental/BinderIncrementalService.cpp
@@ -348,6 +348,12 @@ binder::Status BinderIncrementalService::unregisterStorageHealthListener(int32_t
return ok();
}
+binder::Status BinderIncrementalService::getMetrics(int32_t storageId,
+ android::os::PersistableBundle* _aidl_return) {
+ mImpl.getMetrics(storageId, _aidl_return);
+ return ok();
+}
+
} // namespace android::os::incremental
jlong Incremental_IncrementalService_Start(JNIEnv* env) {
diff --git a/services/incremental/BinderIncrementalService.h b/services/incremental/BinderIncrementalService.h
index 740c542f9759..ebb23dc25bac 100644
--- a/services/incremental/BinderIncrementalService.h
+++ b/services/incremental/BinderIncrementalService.h
@@ -18,6 +18,7 @@
#include <binder/BinderService.h>
#include <binder/IServiceManager.h>
+#include <binder/PersistableBundle.h>
#include <jni.h>
#include "IncrementalService.h"
@@ -97,6 +98,8 @@ public:
const ::android::os::incremental::StorageHealthCheckParams& healthCheckParams,
const ::android::sp<IStorageHealthListener>& healthListener, bool* _aidl_return) final;
binder::Status unregisterStorageHealthListener(int32_t storageId) final;
+ binder::Status getMetrics(int32_t storageId,
+ android::os::PersistableBundle* _aidl_return) final;
private:
android::incremental::IncrementalService mImpl;
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index ce6e6ab1e29c..1fcc2843bd43 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -2118,6 +2118,29 @@ bool IncrementalService::removeTimedJobs(TimedQueueWrapper& timedQueue, MountId
return true;
}
+void IncrementalService::getMetrics(StorageId storageId, android::os::PersistableBundle* result) {
+ const auto duration = getMillsSinceOldestPendingRead(storageId);
+ if (duration >= 0) {
+ const auto kMetricsMillisSinceOldestPendingRead =
+ os::incremental::BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ();
+ result->putLong(String16(kMetricsMillisSinceOldestPendingRead.data()), duration);
+ }
+}
+
+long IncrementalService::getMillsSinceOldestPendingRead(StorageId storageId) {
+ std::unique_lock l(mLock);
+ const auto ifs = getIfsLocked(storageId);
+ if (!ifs) {
+ LOG(ERROR) << "getMillsSinceOldestPendingRead failed, invalid storageId: " << storageId;
+ return -EINVAL;
+ }
+ if (!ifs->dataLoaderStub) {
+ LOG(ERROR) << "getMillsSinceOldestPendingRead failed, no data loader: " << storageId;
+ return -EINVAL;
+ }
+ return ifs->dataLoaderStub->elapsedMsSinceOldestPendingRead();
+}
+
IncrementalService::DataLoaderStub::DataLoaderStub(IncrementalService& service, MountId id,
DataLoaderParamsParcel&& params,
FileSystemControlParcel&& control,
@@ -2516,9 +2539,7 @@ void IncrementalService::DataLoaderStub::updateHealthStatus(bool baseline) {
std::max(1000ms,
std::chrono::milliseconds(mHealthCheckParams.unhealthyMonitoringMs));
- const auto kernelDeltaUs = kernelTsUs - mHealthBase.kernelTsUs;
- const auto userTs = mHealthBase.userTs + std::chrono::microseconds(kernelDeltaUs);
- const auto delta = std::chrono::duration_cast<std::chrono::milliseconds>(now - userTs);
+ const auto delta = elapsedMsSinceKernelTs(now, kernelTsUs);
Milliseconds checkBackAfter;
if (delta + kTolerance < blockedTimeout) {
@@ -2550,6 +2571,13 @@ void IncrementalService::DataLoaderStub::updateHealthStatus(bool baseline) {
fsmStep();
}
+Milliseconds IncrementalService::DataLoaderStub::elapsedMsSinceKernelTs(TimePoint now,
+ BootClockTsUs kernelTsUs) {
+ const auto kernelDeltaUs = kernelTsUs - mHealthBase.kernelTsUs;
+ const auto userTs = mHealthBase.userTs + std::chrono::microseconds(kernelDeltaUs);
+ return std::chrono::duration_cast<Milliseconds>(now - userTs);
+}
+
const incfs::UniqueControl& IncrementalService::DataLoaderStub::initializeHealthControl() {
if (mHealthPath.empty()) {
resetHealthControl();
@@ -2581,16 +2609,15 @@ BootClockTsUs IncrementalService::DataLoaderStub::getOldestPendingReadTs() {
if (mService.mIncFs->waitForPendingReads(control, 0ms, &mLastPendingReads) !=
android::incfs::WaitResult::HaveData ||
mLastPendingReads.empty()) {
+ // Clear previous pending reads
+ mLastPendingReads.clear();
return result;
}
LOG(DEBUG) << id() << ": pendingReads: " << control.pendingReads() << ", "
<< mLastPendingReads.size() << ": " << mLastPendingReads.front().bootClockTsUs;
- for (auto&& pendingRead : mLastPendingReads) {
- result = std::min(result, pendingRead.bootClockTsUs);
- }
- return result;
+ return getOldestTsFromLastPendingReads();
}
void IncrementalService::DataLoaderStub::registerForPendingReads() {
@@ -2612,6 +2639,22 @@ void IncrementalService::DataLoaderStub::registerForPendingReads() {
mService.mLooper->wake();
}
+BootClockTsUs IncrementalService::DataLoaderStub::getOldestTsFromLastPendingReads() {
+ auto result = kMaxBootClockTsUs;
+ for (auto&& pendingRead : mLastPendingReads) {
+ result = std::min(result, pendingRead.bootClockTsUs);
+ }
+ return result;
+}
+
+long IncrementalService::DataLoaderStub::elapsedMsSinceOldestPendingRead() {
+ const auto oldestPendingReadKernelTs = getOldestTsFromLastPendingReads();
+ if (oldestPendingReadKernelTs == kMaxBootClockTsUs) {
+ return 0;
+ }
+ return elapsedMsSinceKernelTs(Clock::now(), oldestPendingReadKernelTs).count();
+}
+
void IncrementalService::DataLoaderStub::unregisterFromPendingReads() {
const auto pendingReadsFd = mHealthControl.pendingReads();
if (pendingReadsFd < 0) {
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index d8f2c91a971c..14e5a7734172 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -20,12 +20,14 @@
#include <android/content/pm/DataLoaderParamsParcel.h>
#include <android/content/pm/FileSystemControlParcel.h>
#include <android/content/pm/IDataLoaderStatusListener.h>
+#include <android/os/incremental/BnIncrementalService.h>
#include <android/os/incremental/BnIncrementalServiceConnector.h>
#include <android/os/incremental/BnStorageHealthListener.h>
#include <android/os/incremental/BnStorageLoadingProgressListener.h>
#include <android/os/incremental/PerUidReadTimeouts.h>
#include <android/os/incremental/StorageHealthCheckParams.h>
#include <binder/IAppOpsCallback.h>
+#include <binder/PersistableBundle.h>
#include <utils/String16.h>
#include <utils/StrongPointer.h>
#include <ziparchive/zip_archive.h>
@@ -181,6 +183,8 @@ public:
bool extractNativeLibs);
bool waitForNativeBinariesExtraction(StorageId storage);
+ void getMetrics(int32_t storageId, android::os::PersistableBundle* _aidl_return);
+
class AppOpsListener : public android::BnAppOpsCallback {
public:
AppOpsListener(IncrementalService& incrementalService, std::string packageName)
@@ -229,6 +233,7 @@ private:
const content::pm::DataLoaderParamsParcel& params() const { return mParams; }
void setHealthListener(StorageHealthCheckParams&& healthCheckParams,
const StorageHealthListener* healthListener);
+ long elapsedMsSinceOldestPendingRead();
private:
binder::Status onStatusChanged(MountId mount, int newStatus) final;
@@ -259,6 +264,8 @@ private:
void resetHealthControl();
BootClockTsUs getOldestPendingReadTs();
+ BootClockTsUs getOldestTsFromLastPendingReads();
+ Milliseconds elapsedMsSinceKernelTs(TimePoint now, BootClockTsUs kernelTsUs);
Milliseconds updateBindDelay();
@@ -424,6 +431,7 @@ private:
bool removeTimedJobs(TimedQueueWrapper& timedQueue, MountId id);
bool updateLoadingProgress(int32_t storageId,
const StorageLoadingProgressListener& progressListener);
+ long getMillsSinceOldestPendingRead(StorageId storage);
private:
const std::unique_ptr<VoldServiceWrapper> mVold;
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index b00a84fcd003..5236983c83ff 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -21,6 +21,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <utils/Log.h>
+#include <utils/String16.h>
#include <chrono>
#include <future>
@@ -701,6 +702,18 @@ public:
mDataLoaderManager->getDataLoaderSuccess();
}
+ void checkMillisSinceOldestPendingRead(int storageId, long expected) {
+ android::os::PersistableBundle result{};
+ mIncrementalService->getMetrics(storageId, &result);
+ int64_t value = -1;
+ ASSERT_TRUE(result.getLong(String16(BnIncrementalService::
+ METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
+ .c_str()),
+ &value));
+ ASSERT_EQ(expected, value);
+ ASSERT_EQ(1, (int)result.size());
+ }
+
protected:
NiceMock<MockVoldService>* mVold = nullptr;
NiceMock<MockIncFs>* mIncFs = nullptr;
@@ -995,6 +1008,7 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
ASSERT_NE(nullptr, mLooper->mCallbackData);
ASSERT_EQ(storageId, listener->mStorageId);
ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
+ checkMillisSinceOldestPendingRead(storageId, 0);
// Looper/epoll callback.
mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
@@ -1020,6 +1034,8 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
ASSERT_EQ(nullptr, mLooper->mCallbackData);
ASSERT_EQ(storageId, listener->mStorageId);
ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
+ checkMillisSinceOldestPendingRead(storageId, params.blockedTimeoutMs);
+
// Timed callback present.
ASSERT_EQ(storageId, mTimedQueue->mId);
ASSERT_GE(mTimedQueue->mAfter, 1000ms);
@@ -1035,6 +1051,8 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
ASSERT_EQ(nullptr, mLooper->mCallbackData);
ASSERT_EQ(storageId, listener->mStorageId);
ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
+ checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs);
+
// Timed callback present.
ASSERT_EQ(storageId, mTimedQueue->mId);
ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
@@ -1050,6 +1068,8 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
ASSERT_EQ(nullptr, mLooper->mCallbackData);
ASSERT_EQ(storageId, listener->mStorageId);
ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
+ checkMillisSinceOldestPendingRead(storageId, params.unhealthyTimeoutMs);
+
// Timed callback present.
ASSERT_EQ(storageId, mTimedQueue->mId);
ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
@@ -1065,6 +1085,7 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
ASSERT_NE(nullptr, mLooper->mCallbackData);
ASSERT_EQ(storageId, listener->mStorageId);
ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
+ checkMillisSinceOldestPendingRead(storageId, 0);
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
@@ -1581,4 +1602,52 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) {
ASSERT_EQ(mTimedQueue->mAfter, Milliseconds());
}
+TEST_F(IncrementalServiceTest, testInvalidMetricsQuery) {
+ const auto invalidStorageId = 100;
+ android::os::PersistableBundle result{};
+ mIncrementalService->getMetrics(invalidStorageId, &result);
+ int64_t expected = -1, value = -1;
+ ASSERT_FALSE(
+ result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
+ .c_str()),
+ &value));
+ ASSERT_EQ(expected, value);
+ ASSERT_TRUE(result.empty());
+}
+
+TEST_F(IncrementalServiceTest, testNoMetrics) {
+ mVold->setIncFsMountOptionsSuccess();
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_GE(storageId, 0);
+ android::os::PersistableBundle result{};
+ mIncrementalService->getMetrics(storageId, &result);
+ int64_t expected = -1, value = -1;
+ ASSERT_FALSE(
+ result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
+ .c_str()),
+ &value));
+ ASSERT_EQ(expected, value);
+ ASSERT_EQ(0, (int)result.size());
+}
+
+TEST_F(IncrementalServiceTest, testInvalidMetricsKeys) {
+ mVold->setIncFsMountOptionsSuccess();
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_GE(storageId, 0);
+ ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
+ {}, {}));
+ android::os::PersistableBundle result{};
+ mIncrementalService->getMetrics(storageId, &result);
+ int64_t expected = -1, value = -1;
+ ASSERT_FALSE(result.getLong(String16("invalid"), &value));
+ ASSERT_EQ(expected, value);
+ ASSERT_EQ(1, (int)result.size());
+}
+
} // namespace android::os::incremental
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index 51c9b0ddb0d6..f2e85a700327 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -49,8 +49,10 @@ import static com.android.server.alarm.AlarmManagerService.AlarmHandler.APP_STAN
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.CHARGING_STATUS_CHANGED;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_FOR_CANCELED;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA;
+import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_QUOTA;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION;
+import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WINDOW;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LAZY_BATCHING;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_INTERVAL;
@@ -566,17 +568,23 @@ public class AlarmManagerServiceTest {
setDeviceConfigLong(KEY_MAX_INTERVAL, 15);
setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_QUOTA, 20);
setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA, 25);
- setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION, 30);
- setDeviceConfigLong(KEY_LISTENER_TIMEOUT, 35);
+ setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WINDOW, 30);
+ setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW, 35);
+ setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION, 40);
+ setDeviceConfigLong(KEY_LISTENER_TIMEOUT, 45);
assertEquals(5, mService.mConstants.MIN_FUTURITY);
assertEquals(10, mService.mConstants.MIN_INTERVAL);
assertEquals(15, mService.mConstants.MAX_INTERVAL);
assertEquals(20, mService.mConstants.ALLOW_WHILE_IDLE_QUOTA);
assertEquals(25, mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_QUOTA);
- assertEquals(30, mService.mConstants.ALLOW_WHILE_IDLE_WHITELIST_DURATION);
- assertEquals(35, mService.mConstants.LISTENER_TIMEOUT);
+ assertEquals(30, mService.mConstants.ALLOW_WHILE_IDLE_WINDOW);
+ assertEquals(35, mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW);
+ assertEquals(40, mService.mConstants.ALLOW_WHILE_IDLE_WHITELIST_DURATION);
+ assertEquals(45, mService.mConstants.LISTENER_TIMEOUT);
+ }
- // Test safeguards.
+ @Test
+ public void positiveWhileIdleQuotas() {
setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_QUOTA, -3);
assertEquals(1, mService.mConstants.ALLOW_WHILE_IDLE_QUOTA);
setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_QUOTA, 0);
@@ -589,6 +597,21 @@ public class AlarmManagerServiceTest {
}
@Test
+ public void whileIdleWindowsDontExceedAnHour() {
+ setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WINDOW, AlarmManager.INTERVAL_DAY);
+ assertEquals(AlarmManager.INTERVAL_HOUR, mService.mConstants.ALLOW_WHILE_IDLE_WINDOW);
+ setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_WINDOW, AlarmManager.INTERVAL_HOUR + 1);
+ assertEquals(AlarmManager.INTERVAL_HOUR, mService.mConstants.ALLOW_WHILE_IDLE_WINDOW);
+
+ setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW, AlarmManager.INTERVAL_DAY);
+ assertEquals(AlarmManager.INTERVAL_HOUR,
+ mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW);
+ setDeviceConfigLong(KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW, AlarmManager.INTERVAL_HOUR + 1);
+ assertEquals(AlarmManager.INTERVAL_HOUR,
+ mService.mConstants.ALLOW_WHILE_IDLE_COMPAT_WINDOW);
+ }
+
+ @Test
public void testMinFuturity() {
setDeviceConfigLong(KEY_MIN_FUTURITY, 10L);
assertEquals(10, mService.mConstants.MIN_FUTURITY);
diff --git a/services/tests/servicestests/src/com/android/server/power/FaceDownDetectorTest.java b/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java
index ef20ee7e6ecd..8ecb07158564 100644
--- a/services/tests/servicestests/src/com/android/server/power/FaceDownDetectorTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/power/FaceDownDetectorTest.java
@@ -16,59 +16,74 @@
package com.android.server.power;
+import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
+
+import static com.android.server.power.FaceDownDetector.KEY_FEATURE_ENABLED;
+
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorManager;
+import android.os.PowerManager;
+import android.provider.DeviceConfig;
import android.testing.TestableContext;
import androidx.test.platform.app.InstrumentationRegistry;
-import com.android.server.display.TestUtils;
+import com.android.server.testables.TestableDeviceConfig;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.time.Duration;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
public class FaceDownDetectorTest {
@ClassRule
public static final TestableContext sContext = new TestableContext(
InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+ @Rule
+ public TestableDeviceConfig.TestableDeviceConfigRule
+ mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule();
- private final FaceDownDetector mFaceDownDetector =
- new FaceDownDetector(this::onFlip);
+ private final FaceDownDetector mFaceDownDetector = new FaceDownDetector(this::onFlip);
@Mock private SensorManager mSensorManager;
+ @Mock private PowerManager mPowerManager;
- private long mCurrentTime;
- private int mOnFaceDownCalls = 0;
- private int mOnFaceDownExitCalls = 0;
+ private Duration mCurrentTime;
+ private int mOnFaceDownCalls;
+ private int mOnFaceDownExitCalls;
@Before
- public void setup() {
+ public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
sContext.addMockSystemService(SensorManager.class, mSensorManager);
- mCurrentTime = 0;
+ sContext.addMockSystemService(PowerManager.class, mPowerManager);
+ doReturn(true).when(mPowerManager).isInteractive();
+ DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+ KEY_FEATURE_ENABLED, "true", false);
+ mCurrentTime = Duration.ZERO;
+ mOnFaceDownCalls = 0;
+ mOnFaceDownExitCalls = 0;
}
@Test
public void faceDownFor2Seconds_triggersFaceDown() throws Exception {
mFaceDownDetector.systemReady(sContext);
- // Face up
- // Using 0.5 on x to simulate constant acceleration, such as a sloped surface.
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, 10.0f));
-
- for (int i = 0; i < 200; i++) {
- advanceTime(Duration.ofMillis(20));
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, -10.0f));
- }
+ triggerFaceDown();
assertThat(mOnFaceDownCalls).isEqualTo(1);
assertThat(mOnFaceDownExitCalls).isEqualTo(0);
@@ -111,15 +126,7 @@ public class FaceDownDetectorTest {
public void faceDownFor2Seconds_followedByFaceUp_triggersFaceDownExit() throws Exception {
mFaceDownDetector.systemReady(sContext);
- // Face up
- // Using 0.5 on x to simulate constant acceleration, such as a sloped surface.
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, 10.0f));
-
- // Trigger face down
- for (int i = 0; i < 100; i++) {
- advanceTime(Duration.ofMillis(20));
- mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, -10.0f));
- }
+ triggerFaceDown();
// Phone flips
for (int i = 0; i < 10; i++) {
@@ -131,8 +138,71 @@ public class FaceDownDetectorTest {
assertThat(mOnFaceDownExitCalls).isEqualTo(1);
}
+ @Test
+ public void notInteractive_doesNotTriggerFaceDown() throws Exception {
+ doReturn(false).when(mPowerManager).isInteractive();
+ mFaceDownDetector.systemReady(sContext);
+
+ triggerFaceDown();
+
+ assertThat(mOnFaceDownCalls).isEqualTo(0);
+ assertThat(mOnFaceDownExitCalls).isEqualTo(0);
+ }
+
+ @Test
+ public void afterDisablingFeature_doesNotTriggerFaceDown() throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+ setEnabled(false);
+
+ triggerFaceDown();
+
+ assertThat(mOnFaceDownCalls).isEqualTo(0);
+ }
+
+ @Test
+ public void afterReenablingWhileNonInteractive_doesNotTriggerFaceDown() throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+ setEnabled(false);
+
+ doReturn(false).when(mPowerManager).isInteractive();
+ setEnabled(true);
+
+ triggerFaceDown();
+
+ assertThat(mOnFaceDownCalls).isEqualTo(0);
+ }
+
+ @Test
+ public void afterReenablingWhileInteractive_doesTriggerFaceDown() throws Exception {
+ mFaceDownDetector.systemReady(sContext);
+ setEnabled(false);
+
+ setEnabled(true);
+
+ triggerFaceDown();
+
+ assertThat(mOnFaceDownCalls).isEqualTo(1);
+ }
+
+ private void triggerFaceDown() throws Exception {
+ // Face up
+ // Using 0.5 on x to simulate constant acceleration, such as a sloped surface.
+ mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, 10.0f));
+
+ for (int i = 0; i < 200; i++) {
+ advanceTime(Duration.ofMillis(20));
+ mFaceDownDetector.onSensorChanged(createTestEvent(0.5f, 0.0f, -10.0f));
+ }
+ }
+
+ private void setEnabled(Boolean enabled) throws Exception {
+ DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+ KEY_FEATURE_ENABLED, enabled.toString(), false);
+ waitForListenerToHandle();
+ }
+
private void advanceTime(Duration duration) {
- mCurrentTime += duration.toNanos();
+ mCurrentTime = mCurrentTime.plus(duration);
}
/**
@@ -146,12 +216,11 @@ public class FaceDownDetectorTest {
SensorEvent.class.getDeclaredConstructor(int.class);
constructor.setAccessible(true);
final SensorEvent event = constructor.newInstance(3);
- event.sensor =
- TestUtils.createSensor(Sensor.TYPE_ACCELEROMETER, Sensor.STRING_TYPE_ACCELEROMETER);
+ event.sensor = createSensor(Sensor.TYPE_ACCELEROMETER, Sensor.STRING_TYPE_ACCELEROMETER);
event.values[0] = x;
event.values[1] = y;
event.values[2] = gravity;
- event.timestamp = mCurrentTime;
+ event.timestamp = mCurrentTime.toNanos();
return event;
}
@@ -162,4 +231,25 @@ public class FaceDownDetectorTest {
mOnFaceDownExitCalls++;
}
}
+
+ private Sensor createSensor(int type, String strType) throws Exception {
+ Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
+ constr.setAccessible(true);
+ Sensor sensor = constr.newInstance();
+ Method setter = Sensor.class.getDeclaredMethod("setType", Integer.TYPE);
+ setter.setAccessible(true);
+ setter.invoke(sensor, type);
+ if (strType != null) {
+ Field f = sensor.getClass().getDeclaredField("mStringType");
+ f.setAccessible(true);
+ f.set(sensor, strType);
+ }
+ return sensor;
+ }
+
+ private void waitForListenerToHandle() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ sContext.getMainExecutor().execute(latch::countDown);
+ assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
index 07f67327b2bf..1c9683803857 100644
--- a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
@@ -40,9 +40,11 @@ import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.RemoteException;
import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
+import com.android.server.LocalServices;
import com.android.server.SystemService;
import org.junit.Before;
@@ -60,6 +62,7 @@ import java.util.List;
* Tests for {@link com.android.server.apphibernation.AppHibernationService}
*/
@SmallTest
+@Presubmit
public final class AppHibernationServiceTest {
private static final String PACKAGE_SCHEME = "package";
private static final String PACKAGE_NAME_1 = "package1";
@@ -91,6 +94,7 @@ public final class AppHibernationServiceTest {
MockitoAnnotations.initMocks(this);
doReturn(mContext).when(mContext).createContextAsUser(any(), anyInt());
+ LocalServices.removeServiceForTest(AppHibernationManagerInternal.class);
mAppHibernationService = new AppHibernationService(new MockInjector(mContext));
verify(mContext).registerReceiver(mReceiverCaptor.capture(), any());
diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java
index 59f3c35f2137..2237c845cde7 100644
--- a/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/apphibernation/HibernationStateDiskStoreTest.java
@@ -19,6 +19,7 @@ package com.android.server.apphibernation;
import static org.junit.Assert.assertEquals;
import android.os.FileUtils;
+import android.platform.test.annotations.Presubmit;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
@@ -48,6 +49,7 @@ import java.util.concurrent.TimeoutException;
@SmallTest
+@Presubmit
public class HibernationStateDiskStoreTest {
private static final String STATES_FILE_NAME = "states";
private final MockScheduledExecutorService mMockScheduledExecutorService =
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 87100a63e35e..89435e9a8862 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -3875,7 +3875,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
}
@Test
- public void testForceUpdateUserSetupComplete_userbuild() {
+ public void testForceUpdateUserSetupComplete_forcesUpdate() {
mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -3888,34 +3888,6 @@ public class DevicePolicyManagerTest extends DpmTestBase {
userData.mUserSetupComplete = true;
dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
- // GIVEN it's user build
- getServices().buildMock.isDebuggable = false;
-
- assertThat(dpms.hasUserSetupCompleted()).isTrue();
-
- dpm.forceUpdateUserSetupComplete();
-
- // THEN the state in dpms is not changed
- assertThat(dpms.hasUserSetupCompleted()).isTrue();
- }
-
- @Test
- public void testForceUpdateUserSetupComplete_userDebugbuild() {
- mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
- mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
-
- final int userId = UserHandle.USER_SYSTEM;
- // GIVEN userComplete is false in SettingsProvider
- setUserSetupCompleteForUser(false, userId);
-
- // GIVEN userComplete is true in DPM
- DevicePolicyData userData = new DevicePolicyData(userId);
- userData.mUserSetupComplete = true;
- dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
-
- // GIVEN it's userdebug build
- getServices().buildMock.isDebuggable = true;
-
assertThat(dpms.hasUserSetupCompleted()).isTrue();
dpm.forceUpdateUserSetupComplete();
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java
index f94b800afbef..2fe47d3ff184 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java
@@ -21,6 +21,11 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.admin.DeviceAdminInfo;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.os.Parcel;
+import android.util.TypedXmlPullParser;
+import android.util.Xml;
import androidx.test.InstrumentationRegistry;
@@ -32,9 +37,14 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
@@ -44,18 +54,21 @@ import java.util.function.Function;
public class PolicyVersionUpgraderTest {
// NOTE: Only change this value if the corresponding CL also adds a test to test the upgrade
// to the new version.
- private static final int LATEST_TESTED_VERSION = 1;
+ private static final int LATEST_TESTED_VERSION = 2;
+ public static final String PERMISSIONS_TAG = "admin-can-grant-sensors-permissions";
+ private ComponentName mFakeAdmin;
private static class FakePolicyUpgraderDataProvider implements PolicyUpgraderDataProvider {
int mDeviceOwnerUserId;
+ ComponentName mDeviceOwnerComponent = new ComponentName("", "");
boolean mIsFileBasedEncryptionEnabled;
Map<Integer, ComponentName> mUserToComponent = new HashMap<>();
- Map<ComponentName, DeviceAdminInfo> mComponentToDeviceAdminInfo;
+ Map<ComponentName, DeviceAdminInfo> mComponentToDeviceAdminInfo = new HashMap<>();
File mDataDir;
@Override
- public boolean isUserDeviceOwner(int userId) {
- return userId == mDeviceOwnerUserId;
+ public boolean isUserDeviceOwner(int userId, ComponentName who) {
+ return userId == mDeviceOwnerUserId && mDeviceOwnerComponent.equals(who);
}
@Override
@@ -105,7 +118,14 @@ public class PolicyVersionUpgraderTest {
mUpgrader = new PolicyVersionUpgrader(mProvider);
mDataDir = new File(mRealTestContext.getCacheDir(), "test-data");
mDataDir.getParentFile().mkdirs();
+ // Prepare provider.
mProvider.mDataDir = mDataDir;
+ mFakeAdmin = new ComponentName(
+ "com.android.frameworks.servicestests",
+ "com.android.server.devicepolicy.DummyDeviceAdmins$Admin1");
+ ActivityInfo activityInfo = createActivityInfo(mFakeAdmin);
+ DeviceAdminInfo dai = createDeviceAdminInfo(activityInfo);
+ mProvider.mComponentToDeviceAdminInfo.put(mFakeAdmin, dai);
}
@Test
@@ -122,21 +142,43 @@ public class PolicyVersionUpgraderTest {
}
@Test
- public void testUpgrade0To1RemovesPasswordMetrics() throws IOException {
+ public void testUpgrade0To1RemovesPasswordMetrics() throws IOException, XmlPullParserException {
+ final String activePasswordTag = "active-password";
int[] users = new int[] {0, 10};
writeVersionToXml(0);
for (int userId : users) {
preparePoliciesFile(userId);
}
-
- String oldContents = readPoliciesFile(0);
- assertThat(oldContents).contains("active-password");
+ // Validate test set-up.
+ assertThat(isTagPresent(readPoliciesFileToStream(0), activePasswordTag)).isTrue();
mUpgrader.upgradePolicy(users, 1);
- assertThat(readVersionFromXml()).isEqualTo(1);
- assertThat(readPoliciesFile(users[0])).doesNotContain("active-password");
- assertThat(readPoliciesFile(users[1])).doesNotContain("active-password");
+ assertThat(readVersionFromXml()).isGreaterThan(1);
+ for (int user: users) {
+ assertThat(isTagPresent(readPoliciesFileToStream(user), activePasswordTag)).isFalse();
+ }
+ }
+
+ @Test
+ public void testUpgrade1To2MarksDoForPermissionControl()
+ throws IOException, XmlPullParserException {
+ int[] users = new int[] {0, 10};
+ writeVersionToXml(1);
+ for (int userId : users) {
+ preparePoliciesFile(userId);
+ }
+ mProvider.mDeviceOwnerUserId = 10;
+ mProvider.mDeviceOwnerComponent = mFakeAdmin;
+ mProvider.mUserToComponent.put(10, mFakeAdmin);
+
+ mUpgrader.upgradePolicy(users, 2);
+
+ assertThat(readVersionFromXml()).isEqualTo(2);
+ assertThat(getBooleanValueTag(readPoliciesFileToStream(users[0]),
+ PERMISSIONS_TAG)).isFalse();
+ assertThat(getBooleanValueTag(readPoliciesFileToStream(users[1]),
+ PERMISSIONS_TAG)).isTrue();
}
@Test
@@ -169,6 +211,70 @@ public class PolicyVersionUpgraderTest {
private String readPoliciesFile(int userId) throws IOException {
File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead();
- return new String(Files.asByteSource(policiesFile).read());
+ FileReader reader = new FileReader(policiesFile);
+ return new String(Files.asByteSource(policiesFile).read(), Charset.defaultCharset());
+ }
+
+ private InputStream readPoliciesFileToStream(int userId) throws IOException {
+ File policiesFile = mProvider.makeDevicePoliciesJournaledFile(userId).chooseForRead();
+ return new FileInputStream(policiesFile);
+ }
+
+ private boolean getBooleanValueTag(InputStream inputXml, String tagName)
+ throws IOException, XmlPullParserException {
+ TypedXmlPullParser parser = Xml.resolvePullParser(inputXml);
+
+ int eventType = parser.getEventType();
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ String tag = parser.getName();
+ if (tagName.equals(tag)) {
+ String res = parser.getAttributeValue(null, "value");
+ return Boolean.parseBoolean(res);
+ }
+ }
+ eventType = parser.next();
+ }
+
+ throw new IllegalStateException("Could not find " + tagName);
+ }
+
+ private boolean isTagPresent(InputStream inputXml, String tagName)
+ throws IOException, XmlPullParserException {
+ TypedXmlPullParser parser = Xml.resolvePullParser(inputXml);
+
+ int eventType = parser.getEventType();
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ String tag = parser.getName();
+ if (tagName.equals(tag)) {
+ return true;
+ }
+ }
+ eventType = parser.next();
+ }
+
+ return false;
+ }
+
+ private ActivityInfo createActivityInfo(ComponentName admin) {
+ ActivityInfo ai = new ActivityInfo();
+ ApplicationInfo applicationInfo = new ApplicationInfo();
+ applicationInfo.className = admin.getClassName();
+ applicationInfo.uid = 2222;
+ ai.applicationInfo = applicationInfo;
+ ai.name = admin.getClassName();
+ ai.packageName = admin.getPackageName();
+ return ai;
+ }
+
+ private DeviceAdminInfo createDeviceAdminInfo(ActivityInfo activityInfo) {
+ Parcel parcel = Parcel.obtain();
+ activityInfo.writeToParcel(parcel, 0);
+ parcel.writeInt(0);
+ parcel.writeBoolean(true);
+ parcel.setDataPosition(0);
+
+ return DeviceAdminInfo.CREATOR.createFromParcel(parcel);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index d36279109254..893ce9e6c70c 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -38,6 +38,7 @@ import android.hardware.SensorEventListener;
import android.hardware.display.AmbientBrightnessDayStats;
import android.hardware.display.BrightnessChangeEvent;
import android.hardware.display.BrightnessConfiguration;
+import android.hardware.display.ColorDisplayManager;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayedContentSample;
import android.hardware.display.DisplayedContentSamplingAttributes;
@@ -91,6 +92,7 @@ public class BrightnessTrackerTest {
new HandlerThread("brightness.test", android.os.Process.THREAD_PRIORITY_BACKGROUND);
private int mDefaultNightModeColorTemperature;
+ private float mRbcOffsetFactor;
private static Handler ensureHandler() {
synchronized (sHandlerLock) {
@@ -111,6 +113,8 @@ public class BrightnessTrackerTest {
mDefaultNightModeColorTemperature =
InstrumentationRegistry.getContext().getResources().getInteger(
R.integer.config_nightDisplayColorTemperatureDefault);
+ mRbcOffsetFactor = InstrumentationRegistry.getContext()
+ .getSystemService(ColorDisplayManager.class).getReduceBrightColorsOffsetFactor();
}
@Test
@@ -314,6 +318,9 @@ public class BrightnessTrackerTest {
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3333);
+ mInjector.mSecureIntSettings.put(Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
+ mInjector.mSecureIntSettings.put(Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 40);
+
startTracker(mTracker, initialBrightness, DEFAULT_COLOR_SAMPLING_ENABLED);
mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
batteryChangeEvent(30, 60));
@@ -337,7 +344,7 @@ public class BrightnessTrackerTest {
assertEquals(3333, event.colorTemperature);
assertTrue(event.reduceBrightColors);
assertEquals(40, event.reduceBrightColorsStrength);
- assertEquals(20f, event.reduceBrightColorsOffset, FLOAT_DELTA);
+ assertEquals(brightness * mRbcOffsetFactor, event.reduceBrightColorsOffset, FLOAT_DELTA);
assertEquals("a.package", event.packageName);
assertEquals(0, event.userId);
assertArrayEquals(new long[] {1, 10, 100, 1000, 300, 30, 10, 1}, event.colorValueBuckets);
@@ -445,7 +452,9 @@ public class BrightnessTrackerTest {
+ Long.toString(someTimeAgo) + "\" packageName=\""
+ "com.example.app\" user=\"10\" "
+ "lastNits=\"32.333\" "
- + "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\"\n"
+ + "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\" "
+ + "reduceBrightColors=\"false\" reduceBrightColorsStrength=\"40\" "
+ + "reduceBrightColorsOffset=\"0\"\n"
+ "lux=\"32.2,31.1\" luxTimestamps=\""
+ Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\""
+ "defaultConfig=\"true\" powerSaveFactor=\"0.5\" userPoint=\"true\" />"
@@ -453,7 +462,9 @@ public class BrightnessTrackerTest {
+ Long.toString(someTimeAgo) + "\" packageName=\""
+ "com.android.anapp\" user=\"11\" "
+ "lastNits=\"32\" "
- + "batteryLevel=\"0.5\" nightMode=\"true\" colorTemperature=\"3235\"\n"
+ + "batteryLevel=\"0.5\" nightMode=\"true\" colorTemperature=\"3235\" "
+ + "reduceBrightColors=\"true\" reduceBrightColorsStrength=\"40\" "
+ + "reduceBrightColorsOffset=\"0\"\n"
+ "lux=\"132.2,131.1\" luxTimestamps=\""
+ Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\""
+ "colorSampleDuration=\"3456\" colorValueBuckets=\"123,598,23,19\"/>"
@@ -462,7 +473,9 @@ public class BrightnessTrackerTest {
+ Long.toString(twoMonthsAgo) + "\" packageName=\""
+ "com.example.app\" user=\"10\" "
+ "lastNits=\"32\" "
- + "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\"\n"
+ + "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\" "
+ + "reduceBrightColors=\"false\" reduceBrightColorsStrength=\"40\" "
+ + "reduceBrightColorsOffset=\"0\"\n"
+ "lux=\"32.2,31.1\" luxTimestamps=\""
+ Long.toString(twoMonthsAgo) + "," + Long.toString(twoMonthsAgo) + "\"/>"
+ "</events>";
@@ -477,6 +490,7 @@ public class BrightnessTrackerTest {
assertEquals(32.333, event.lastBrightness, FLOAT_DELTA);
assertEquals(0, event.userId);
assertFalse(event.nightMode);
+ assertFalse(event.reduceBrightColors);
assertEquals(1.0f, event.batteryLevel, FLOAT_DELTA);
assertEquals("com.example.app", event.packageName);
assertTrue(event.isDefaultBrightnessConfig);
@@ -495,6 +509,7 @@ public class BrightnessTrackerTest {
assertEquals(1, event.userId);
assertTrue(event.nightMode);
assertEquals(3235, event.colorTemperature);
+ assertTrue(event.reduceBrightColors);
assertEquals(0.5f, event.batteryLevel, FLOAT_DELTA);
assertEquals("com.android.anapp", event.packageName);
// Not present in the event so default to false.
@@ -600,7 +615,7 @@ public class BrightnessTrackerTest {
assertEquals(3339, event.colorTemperature);
assertTrue(event.reduceBrightColors);
assertEquals(40, event.reduceBrightColorsStrength);
- assertEquals(20f, event.reduceBrightColorsOffset, FLOAT_DELTA);
+ assertEquals(brightness * mRbcOffsetFactor, event.reduceBrightColorsOffset, FLOAT_DELTA);
assertEquals(0.5f, event.powerBrightnessFactor, FLOAT_DELTA);
assertTrue(event.isUserSetBrightness);
assertFalse(event.isDefaultBrightnessConfig);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 915392e6eb80..1a6bad8b29cf 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -61,6 +61,12 @@ import java.util.concurrent.TimeUnit;
/** Tests for {@link HdmiCecLocalDevicePlayback} class. */
public class HdmiCecLocalDevicePlaybackTest {
+ private static final int PORT_1 = 1;
+ private static final HdmiDeviceInfo INFO_TV = new HdmiDeviceInfo(
+ ADDR_TV, 0x0000, PORT_1, HdmiDeviceInfo.DEVICE_TV,
+ 0x1234, "TV",
+ HdmiControlManager.POWER_STATUS_ON, HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
+
private HdmiControlService mHdmiControlService;
private HdmiCecController mHdmiCecController;
private HdmiCecLocalDevicePlayback mHdmiCecLocalDevicePlayback;
@@ -159,6 +165,7 @@ public class HdmiCecLocalDevicePlaybackTest {
mNativeWrapper.setPhysicalAddress(mPlaybackPhysicalAddress);
mTestLooper.dispatchAll();
mPlaybackLogicalAddress = mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress();
+ mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
mNativeWrapper.clearResultMessages();
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
new file mode 100644
index 000000000000..907cf3eb1f70
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/OneTouchPlayActionTest.java
@@ -0,0 +1,420 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import static com.android.server.hdmi.Constants.ADDR_TV;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
+import static com.android.server.hdmi.OneTouchPlayAction.STATE_WAITING_FOR_REPORT_POWER_STATUS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.hardware.hdmi.IHdmiControlCallback;
+import android.media.AudioManager;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.IThermalService;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.test.TestLooper;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import com.android.server.hdmi.HdmiCecFeatureAction.ActionTimer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+/** Tests for {@link OneTouchPlayAction} */
+@SmallTest
+@RunWith(JUnit4.class)
+public class OneTouchPlayActionTest {
+ private static final byte[] POWER_ON = new byte[]{HdmiControlManager.POWER_STATUS_ON};
+ private static final byte[] POWER_TRANSIENT_TO_ON =
+ new byte[]{HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON};
+
+ private static final int PORT_1 = 1;
+ private static final HdmiDeviceInfo INFO_TV = new HdmiDeviceInfo(
+ ADDR_TV, 0x0000, PORT_1, HdmiDeviceInfo.DEVICE_TV,
+ 0x1234, "TV",
+ HdmiControlManager.POWER_STATUS_ON, HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
+
+ private Context mContextSpy;
+ private HdmiControlService mHdmiControlService;
+ private FakeNativeWrapper mNativeWrapper;
+
+ private TestLooper mTestLooper = new TestLooper();
+ private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
+ private int mPhysicalAddress;
+
+ @Mock
+ private IPowerManager mIPowerManagerMock;
+ @Mock
+ private IThermalService mIThermalServiceMock;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
+
+ PowerManager powerManager = new PowerManager(mContextSpy, mIPowerManagerMock,
+ mIThermalServiceMock, new Handler(mTestLooper.getLooper()));
+ when(mContextSpy.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager);
+ when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
+ when(mIPowerManagerMock.isInteractive()).thenReturn(true);
+
+ mHdmiControlService = new HdmiControlService(mContextSpy) {
+ @Override
+ AudioManager getAudioManager() {
+ return new AudioManager() {
+ @Override
+ public void setWiredDeviceConnectionState(
+ int type, int state, String address, String name) {
+ // Do nothing.
+ }
+ };
+ }
+
+ @Override
+ void wakeUp() {
+ }
+
+ @Override
+ boolean isPowerStandby() {
+ return false;
+ }
+
+ @Override
+ protected PowerManager getPowerManager() {
+ return powerManager;
+ }
+
+ @Override
+ protected void writeStringSystemProperty(String key, String value) {
+ // do nothing
+ }
+ };
+
+ Looper looper = mTestLooper.getLooper();
+ mHdmiControlService.setIoLooper(looper);
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
+ mNativeWrapper = new FakeNativeWrapper();
+ HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
+ this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
+ mHdmiControlService.setCecController(hdmiCecController);
+ mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
+ mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
+ mHdmiControlService.initService();
+ mPhysicalAddress = 0x2000;
+ mNativeWrapper.setPhysicalAddress(mPhysicalAddress);
+ mTestLooper.dispatchAll();
+ mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
+ }
+
+ private OneTouchPlayAction createOneTouchPlayAction(HdmiCecLocalDevicePlayback device,
+ TestActionTimer actionTimer, TestCallback callback, boolean isCec20) {
+ OneTouchPlayAction action = new OneTouchPlayAction(device, ADDR_TV, callback, isCec20);
+ action.setActionTimer(actionTimer);
+ return action;
+ }
+
+ @Test
+ public void succeedAfterGettingPowerStatusOn_Cec14b() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ false);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+ assertThat(actionTimer.getState()).isEqualTo(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ HdmiCecMessage reportPowerStatusOn = new HdmiCecMessage(
+ ADDR_TV, playbackDevice.mAddress, Constants.MESSAGE_REPORT_POWER_STATUS, POWER_ON);
+ action.processCommand(reportPowerStatusOn);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+ }
+
+ @Test
+ public void succeedAfterGettingTransientPowerStatus_Cec14b() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ false);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+ assertThat(actionTimer.getState()).isEqualTo(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ HdmiCecMessage reportPowerStatusTransientToOn = new HdmiCecMessage(
+ ADDR_TV, playbackDevice.mAddress, Constants.MESSAGE_REPORT_POWER_STATUS,
+ POWER_TRANSIENT_TO_ON);
+ action.processCommand(reportPowerStatusTransientToOn);
+ action.handleTimerEvent(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+
+ HdmiCecMessage reportPowerStatusOn = new HdmiCecMessage(
+ ADDR_TV, playbackDevice.mAddress, Constants.MESSAGE_REPORT_POWER_STATUS, POWER_ON);
+ action.processCommand(reportPowerStatusOn);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+ }
+
+ @Test
+ public void timeOut_Cec14b() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ false);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+ assertThat(actionTimer.getState()).isEqualTo(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ for (int i = 0; i < 10; ++i) {
+ action.handleTimerEvent(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ mTestLooper.dispatchAll();
+ }
+
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ action.handleTimerEvent(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT);
+ }
+
+ @Test
+ public void succeedIfPowerStatusOn_Cec20() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mHdmiControlService.getHdmiCecNetwork().updateDevicePowerStatus(ADDR_TV,
+ HdmiControlManager.POWER_STATUS_ON);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ true);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+ }
+
+ @Test
+ public void succeedIfPowerStatusUnknown_Cec20() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mHdmiControlService.getHdmiCecNetwork().updateDevicePowerStatus(ADDR_TV,
+ HdmiControlManager.POWER_STATUS_UNKNOWN);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ true);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+ assertThat(actionTimer.getState()).isEqualTo(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ HdmiCecMessage reportPowerStatusOn = new HdmiCecMessage(
+ ADDR_TV, playbackDevice.mAddress, Constants.MESSAGE_REPORT_POWER_STATUS, POWER_ON);
+ action.processCommand(reportPowerStatusOn);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+ }
+
+ @Test
+ public void succeedIfPowerStatusStandby_Cec20() {
+ HdmiCecLocalDevicePlayback playbackDevice = new HdmiCecLocalDevicePlayback(
+ mHdmiControlService);
+ playbackDevice.init();
+ mLocalDevices.add(playbackDevice);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mHdmiControlService.getHdmiCecNetwork().updateDevicePowerStatus(ADDR_TV,
+ HdmiControlManager.POWER_STATUS_STANDBY);
+ mTestLooper.dispatchAll();
+
+ TestActionTimer actionTimer = new TestActionTimer();
+ TestCallback callback = new TestCallback();
+ OneTouchPlayAction action = createOneTouchPlayAction(playbackDevice, actionTimer, callback,
+ true);
+ playbackDevice.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
+ playbackDevice.mAddress, mPhysicalAddress);
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(playbackDevice.mAddress,
+ ADDR_TV);
+ HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder
+ .buildGiveDevicePowerStatus(playbackDevice.mAddress, ADDR_TV);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ mNativeWrapper.clearResultMessages();
+ assertThat(actionTimer.getState()).isEqualTo(STATE_WAITING_FOR_REPORT_POWER_STATUS);
+ HdmiCecMessage reportPowerStatusOn = new HdmiCecMessage(
+ ADDR_TV, playbackDevice.mAddress, Constants.MESSAGE_REPORT_POWER_STATUS, POWER_ON);
+ action.processCommand(reportPowerStatusOn);
+ mTestLooper.dispatchAll();
+
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+ assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
+ assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
+ assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+ }
+
+ private static class TestActionTimer implements ActionTimer {
+ private int mState;
+
+ @Override
+ public void sendTimerMessage(int state, long delayMillis) {
+ mState = state;
+ }
+
+ @Override
+ public void clearTimerMessage() {
+ }
+
+ private int getState() {
+ return mState;
+ }
+ }
+
+ private static class TestCallback extends IHdmiControlCallback.Stub {
+ private final ArrayList<Integer> mCallbackResult = new ArrayList<Integer>();
+
+ @Override
+ public void onComplete(int result) {
+ mCallbackResult.add(result);
+ }
+
+ private int getResult() {
+ assertThat(mCallbackResult.size()).isEqualTo(1);
+ return mCallbackResult.get(0);
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
new file mode 100644
index 000000000000..865eb7a3b56d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+
+import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
+import static com.android.server.hdmi.SystemAudioAutoInitiationAction.RETRIES_ON_TIMEOUT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.hardware.hdmi.HdmiPortInfo;
+import android.media.AudioManager;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.IThermalService;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.test.TestLooper;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+/**
+ * Test for {@link SystemAudioAutoInitiationAction}.
+ */
+@SmallTest
+@RunWith(JUnit4.class)
+public class SystemAudioAutoInitiationActionTest {
+
+ private Context mContextSpy;
+ private HdmiControlService mHdmiControlService;
+ private FakeNativeWrapper mNativeWrapper;
+
+ private HdmiCecLocalDeviceTv mHdmiCecLocalDeviceTv;
+
+ private TestLooper mTestLooper = new TestLooper();
+ private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
+ private int mPhysicalAddress;
+
+ @Mock
+ private IPowerManager mIPowerManagerMock;
+ @Mock
+ private IThermalService mIThermalServiceMock;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
+
+ Looper myLooper = mTestLooper.getLooper();
+ PowerManager powerManager = new PowerManager(mContextSpy, mIPowerManagerMock,
+ mIThermalServiceMock, new Handler(myLooper));
+ when(mContextSpy.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager);
+ when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
+ when(mIPowerManagerMock.isInteractive()).thenReturn(true);
+
+ mHdmiControlService = new HdmiControlService(mContextSpy) {
+ @Override
+ AudioManager getAudioManager() {
+ return new AudioManager() {
+ @Override
+ public void setWiredDeviceConnectionState(
+ int type, int state, String address, String name) {
+ // Do nothing.
+ }
+ };
+ }
+
+ @Override
+ void wakeUp() {
+ }
+
+ @Override
+ boolean isPowerStandby() {
+ return false;
+ }
+
+ @Override
+ protected PowerManager getPowerManager() {
+ return powerManager;
+ }
+
+ @Override
+ protected void writeStringSystemProperty(String key, String value) {
+ // do nothing
+ }
+ };
+
+ mHdmiCecLocalDeviceTv = new HdmiCecLocalDeviceTv(mHdmiControlService);
+ mHdmiCecLocalDeviceTv.init();
+ mHdmiControlService.setIoLooper(myLooper);
+ mNativeWrapper = new FakeNativeWrapper();
+ HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
+ mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
+ mHdmiControlService.setCecController(hdmiCecController);
+ mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
+ mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
+ mLocalDevices.add(mHdmiCecLocalDeviceTv);
+ HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[2];
+ hdmiPortInfos[0] =
+ new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x1000, true, false, false);
+ hdmiPortInfos[1] =
+ new HdmiPortInfo(2, HdmiPortInfo.PORT_INPUT, 0x2000, true, false, true);
+ mNativeWrapper.setPortInfo(hdmiPortInfos);
+ mHdmiControlService.initService();
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mPhysicalAddress = 0x0000;
+ mNativeWrapper.setPhysicalAddress(mPhysicalAddress);
+ mTestLooper.dispatchAll();
+ mPhysicalAddress = mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress();
+ mNativeWrapper.clearResultMessages();
+ }
+
+ private void setSystemAudioSetting(boolean on) {
+ mHdmiCecLocalDeviceTv.setSystemAudioControlFeatureEnabled(on);
+ }
+
+ private void setTvHasSystemAudioChangeAction() {
+ mHdmiCecLocalDeviceTv.addAndStartAction(
+ new SystemAudioActionFromTv(mHdmiCecLocalDeviceTv, Constants.ADDR_AUDIO_SYSTEM,
+ true, null));
+ }
+
+ @Test
+ public void testReceiveSystemAudioMode_systemAudioOn() {
+ // Record that previous system audio mode is on.
+ setSystemAudioSetting(true);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, true);
+ mHdmiControlService.handleCecCommand(reportSystemAudioMode);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue();
+ }
+
+ @Test
+ public void testReceiveSystemAudioMode_systemAudioOnAndImpossibleToChangeSystemAudio() {
+ // Turn on system audio.
+ setSystemAudioSetting(true);
+ // Impossible to change system audio mode while SystemAudioActionFromTv is in progress.
+ setTvHasSystemAudioChangeAction();
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, true);
+ mHdmiControlService.handleCecCommand(reportSystemAudioMode);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiControlService.isSystemAudioActivated()).isFalse();
+ }
+
+ @Test
+ public void testReceiveSystemAudioMode_systemAudioOnAndResponseOff() {
+ // Record that previous system audio mode is on.
+ setSystemAudioSetting(true);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, false);
+ mHdmiControlService.handleCecCommand(reportSystemAudioMode);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiCecLocalDeviceTv.getActions(SystemAudioActionFromTv.class)).isNotEmpty();
+ SystemAudioActionFromTv resultingAction = mHdmiCecLocalDeviceTv.getActions(
+ SystemAudioActionFromTv.class).get(0);
+ assertThat(resultingAction.mTargetAudioStatus).isTrue();
+ }
+
+ @Test
+ public void testReceiveSystemAudioMode_settingOffAndResponseOn() {
+ // Turn off system audio.
+ setSystemAudioSetting(false);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, true);
+ mHdmiControlService.handleCecCommand(reportSystemAudioMode);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiCecLocalDeviceTv.getActions(SystemAudioActionFromTv.class)).isNotEmpty();
+ SystemAudioActionFromTv resultingAction = mHdmiCecLocalDeviceTv.getActions(
+ SystemAudioActionFromTv.class).get(0);
+ assertThat(resultingAction.mTargetAudioStatus).isFalse();
+ }
+
+ @Test
+ public void testReceiveSystemAudioMode_settingOffAndResponseOff() {
+ // Turn off system audio.
+ setSystemAudioSetting(false);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ HdmiCecMessage reportSystemAudioMode = HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, mHdmiCecLocalDeviceTv.mAddress, false);
+ mHdmiControlService.handleCecCommand(reportSystemAudioMode);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiCecLocalDeviceTv.getActions(SystemAudioActionFromTv.class)).isEmpty();
+ assertThat(mHdmiControlService.isSystemAudioActivated()).isFalse();
+ }
+
+ @Test
+ public void testTimeout_systemAudioOn_retries() {
+ // Turn on system audio.
+ setSystemAudioSetting(true);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+ mNativeWrapper.clearResultMessages();
+
+ mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
+ mTestLooper.dispatchAll();
+
+ // Retry sends <Give System Audio Mode Status> again
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+ }
+
+ @Test
+ public void testTimeout_systemAudioOn_allRetriesFail() {
+ boolean targetStatus = true;
+ // Turn on system audio.
+ setSystemAudioSetting(targetStatus);
+
+ HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv,
+ ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceTv.addAndStartAction(action);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage giveSystemAudioModeStatus =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mHdmiCecLocalDeviceTv.mAddress, ADDR_AUDIO_SYSTEM);
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+
+ for (int i = 0; i < RETRIES_ON_TIMEOUT; i++) {
+ mNativeWrapper.clearResultMessages();
+
+ // Target device doesn't respond within timeout
+ mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
+ mTestLooper.dispatchAll();
+
+ // Retry sends <Give System Audio Mode Status> again
+ assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus);
+ }
+
+ // Target device doesn't respond within timeouts
+ mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
+ mTestLooper.dispatchAll();
+
+ assertThat(mHdmiCecLocalDeviceTv.getActions(SystemAudioActionFromTv.class)).isNotEmpty();
+ SystemAudioActionFromTv resultingAction = mHdmiCecLocalDeviceTv.getActions(
+ SystemAudioActionFromTv.class).get(0);
+ assertThat(resultingAction.mTargetAudioStatus).isEqualTo(targetStatus);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
index 1db5544871bf..d07831dd7929 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
@@ -11,15 +11,15 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.inputmethod;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
-import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
+import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
index 6ab48e53648c..9092ec325946 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
@@ -177,10 +177,10 @@ public class InputMethodSubtypeSwitchingControllerTest {
private void assertRotationOrder(final ControllerImpl controller,
final boolean onlyCurrentIme,
final ImeSubtypeListItem... expectedRotationOrderOfImeSubtypeList) {
- final int N = expectedRotationOrderOfImeSubtypeList.length;
- for (int i = 0; i < N; i++) {
+ final int numItems = expectedRotationOrderOfImeSubtypeList.length;
+ for (int i = 0; i < numItems; i++) {
final int currentIndex = i;
- final int nextIndex = (currentIndex + 1) % N;
+ final int nextIndex = (currentIndex + 1) % numItems;
final ImeSubtypeListItem currentItem =
expectedRotationOrderOfImeSubtypeList[currentIndex];
final ImeSubtypeListItem nextItem = expectedRotationOrderOfImeSubtypeList[nextIndex];
@@ -200,47 +200,47 @@ public class InputMethodSubtypeSwitchingControllerTest {
@Test
public void testControllerImpl() throws Exception {
final List<ImeSubtypeListItem> disabledItems = createDisabledImeSubtypes();
- final ImeSubtypeListItem disabledIme_en_US = disabledItems.get(0);
+ final ImeSubtypeListItem disabledIme_en_us = disabledItems.get(0);
final ImeSubtypeListItem disabledIme_hi = disabledItems.get(1);
final ImeSubtypeListItem disabledSwitchingUnawareIme = disabledItems.get(2);
final ImeSubtypeListItem disabledSubtypeUnawareIme = disabledItems.get(3);
final List<ImeSubtypeListItem> enabledItems = createEnabledImeSubtypes();
- final ImeSubtypeListItem latinIme_en_US = enabledItems.get(0);
+ final ImeSubtypeListItem latinIme_en_us = enabledItems.get(0);
final ImeSubtypeListItem latinIme_fr = enabledItems.get(1);
- final ImeSubtypeListItem switchingUnawarelatinIme_en_UK = enabledItems.get(2);
- final ImeSubtypeListItem switchingUnawarelatinIme_hi = enabledItems.get(3);
+ final ImeSubtypeListItem switchingUnawareLatinIme_en_uk = enabledItems.get(2);
+ final ImeSubtypeListItem switchingUnawareLatinIme_hi = enabledItems.get(3);
final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(4);
- final ImeSubtypeListItem japaneseIme_ja_JP = enabledItems.get(5);
- final ImeSubtypeListItem switchUnawareJapaneseIme_ja_JP = enabledItems.get(6);
+ final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(5);
+ final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(6);
final ControllerImpl controller = ControllerImpl.createFrom(
null /* currentInstance */, enabledItems);
// switching-aware loop
assertRotationOrder(controller, false /* onlyCurrentIme */,
- latinIme_en_US, latinIme_fr, japaneseIme_ja_JP);
+ latinIme_en_us, latinIme_fr, japaneseIme_ja_jp);
// switching-unaware loop
assertRotationOrder(controller, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
- switchUnawareJapaneseIme_ja_JP);
+ switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme,
+ switchUnawareJapaneseIme_ja_jp);
// test onlyCurrentIme == true
assertRotationOrder(controller, true /* onlyCurrentIme */,
- latinIme_en_US, latinIme_fr);
+ latinIme_en_us, latinIme_fr);
assertRotationOrder(controller, true /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi);
+ switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
subtypeUnawareIme, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- japaneseIme_ja_JP, null);
+ japaneseIme_ja_jp, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- switchUnawareJapaneseIme_ja_JP, null);
+ switchUnawareJapaneseIme_ja_jp, null);
// Make sure that disabled IMEs are not accepted.
assertNextInputMethod(controller, false /* onlyCurrentIme */,
- disabledIme_en_US, null);
+ disabledIme_en_us, null);
assertNextInputMethod(controller, false /* onlyCurrentIme */,
disabledIme_hi, null);
assertNextInputMethod(controller, false /* onlyCurrentIme */,
@@ -248,7 +248,7 @@ public class InputMethodSubtypeSwitchingControllerTest {
assertNextInputMethod(controller, false /* onlyCurrentIme */,
disabledSubtypeUnawareIme, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- disabledIme_en_US, null);
+ disabledIme_en_us, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
disabledIme_hi, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
@@ -260,82 +260,82 @@ public class InputMethodSubtypeSwitchingControllerTest {
@Test
public void testControllerImplWithUserAction() throws Exception {
final List<ImeSubtypeListItem> enabledItems = createEnabledImeSubtypes();
- final ImeSubtypeListItem latinIme_en_US = enabledItems.get(0);
+ final ImeSubtypeListItem latinIme_en_us = enabledItems.get(0);
final ImeSubtypeListItem latinIme_fr = enabledItems.get(1);
- final ImeSubtypeListItem switchingUnawarelatinIme_en_UK = enabledItems.get(2);
+ final ImeSubtypeListItem switchingUnawarelatinIme_en_uk = enabledItems.get(2);
final ImeSubtypeListItem switchingUnawarelatinIme_hi = enabledItems.get(3);
final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(4);
- final ImeSubtypeListItem japaneseIme_ja_JP = enabledItems.get(5);
- final ImeSubtypeListItem switchUnawareJapaneseIme_ja_JP = enabledItems.get(6);
+ final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(5);
+ final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(6);
final ControllerImpl controller = ControllerImpl.createFrom(
null /* currentInstance */, enabledItems);
// === switching-aware loop ===
assertRotationOrder(controller, false /* onlyCurrentIme */,
- latinIme_en_US, latinIme_fr, japaneseIme_ja_JP);
+ latinIme_en_us, latinIme_fr, japaneseIme_ja_jp);
// Then notify that a user did something for latinIme_fr.
onUserAction(controller, latinIme_fr);
assertRotationOrder(controller, false /* onlyCurrentIme */,
- latinIme_fr, latinIme_en_US, japaneseIme_ja_JP);
+ latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
// Then notify that a user did something for latinIme_fr again.
onUserAction(controller, latinIme_fr);
assertRotationOrder(controller, false /* onlyCurrentIme */,
- latinIme_fr, latinIme_en_US, japaneseIme_ja_JP);
+ latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
// Then notify that a user did something for japaneseIme_ja_JP.
onUserAction(controller, latinIme_fr);
assertRotationOrder(controller, false /* onlyCurrentIme */,
- japaneseIme_ja_JP, latinIme_fr, latinIme_en_US);
+ japaneseIme_ja_jp, latinIme_fr, latinIme_en_us);
// Check onlyCurrentIme == true.
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- japaneseIme_ja_JP, null);
+ japaneseIme_ja_jp, null);
assertRotationOrder(controller, true /* onlyCurrentIme */,
- latinIme_fr, latinIme_en_US);
+ latinIme_fr, latinIme_en_us);
assertRotationOrder(controller, true /* onlyCurrentIme */,
- latinIme_en_US, latinIme_fr);
+ latinIme_en_us, latinIme_fr);
// === switching-unaware loop ===
assertRotationOrder(controller, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
- switchUnawareJapaneseIme_ja_JP);
+ switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+ switchUnawareJapaneseIme_ja_jp);
// User action should be ignored for switching unaware IMEs.
onUserAction(controller, switchingUnawarelatinIme_hi);
assertRotationOrder(controller, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
- switchUnawareJapaneseIme_ja_JP);
+ switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+ switchUnawareJapaneseIme_ja_jp);
// User action should be ignored for switching unaware IMEs.
- onUserAction(controller, switchUnawareJapaneseIme_ja_JP);
+ onUserAction(controller, switchUnawareJapaneseIme_ja_jp);
assertRotationOrder(controller, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
- switchUnawareJapaneseIme_ja_JP);
+ switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+ switchUnawareJapaneseIme_ja_jp);
// Check onlyCurrentIme == true.
assertRotationOrder(controller, true /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi);
+ switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
subtypeUnawareIme, null);
assertNextInputMethod(controller, true /* onlyCurrentIme */,
- switchUnawareJapaneseIme_ja_JP, null);
+ switchUnawareJapaneseIme_ja_jp, null);
// Rotation order should be preserved when created with the same subtype list.
final List<ImeSubtypeListItem> sameEnabledItems = createEnabledImeSubtypes();
final ControllerImpl newController = ControllerImpl.createFrom(controller,
sameEnabledItems);
assertRotationOrder(newController, false /* onlyCurrentIme */,
- japaneseIme_ja_JP, latinIme_fr, latinIme_en_US);
+ japaneseIme_ja_jp, latinIme_fr, latinIme_en_us);
assertRotationOrder(newController, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
- switchUnawareJapaneseIme_ja_JP);
+ switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+ switchUnawareJapaneseIme_ja_jp);
// Rotation order should be initialized when created with a different subtype list.
final List<ImeSubtypeListItem> differentEnabledItems = Arrays.asList(
- latinIme_en_US, latinIme_fr, switchingUnawarelatinIme_en_UK,
- switchUnawareJapaneseIme_ja_JP);
+ latinIme_en_us, latinIme_fr, switchingUnawarelatinIme_en_uk,
+ switchUnawareJapaneseIme_ja_jp);
final ControllerImpl anotherController = ControllerImpl.createFrom(controller,
differentEnabledItems);
assertRotationOrder(anotherController, false /* onlyCurrentIme */,
- latinIme_en_US, latinIme_fr);
+ latinIme_en_us, latinIme_fr);
assertRotationOrder(anotherController, false /* onlyCurrentIme */,
- switchingUnawarelatinIme_en_UK, switchUnawareJapaneseIme_ja_JP);
+ switchingUnawarelatinIme_en_uk, switchUnawareJapaneseIme_ja_jp);
}
@Test
@@ -344,27 +344,27 @@ public class InputMethodSubtypeSwitchingControllerTest {
addDummyImeSubtypeListItems(items, "LatinIme", "LatinIme",
Arrays.asList("en_US", "fr", "en", "en_uk", "enn", "e", "EN_US"),
true /* supportsSwitchingToNextInputMethod*/);
- final ImeSubtypeListItem item_en_US = items.get(0);
+ final ImeSubtypeListItem item_en_us = items.get(0);
final ImeSubtypeListItem item_fr = items.get(1);
final ImeSubtypeListItem item_en = items.get(2);
final ImeSubtypeListItem item_enn = items.get(3);
final ImeSubtypeListItem item_e = items.get(4);
- final ImeSubtypeListItem item_EN_US = items.get(5);
+ final ImeSubtypeListItem item_en_us_allcaps = items.get(5);
- assertTrue(item_en_US.mIsSystemLocale);
+ assertTrue(item_en_us.mIsSystemLocale);
assertFalse(item_fr.mIsSystemLocale);
assertFalse(item_en.mIsSystemLocale);
assertFalse(item_en.mIsSystemLocale);
assertFalse(item_enn.mIsSystemLocale);
assertFalse(item_e.mIsSystemLocale);
- assertFalse(item_EN_US.mIsSystemLocale);
+ assertFalse(item_en_us_allcaps.mIsSystemLocale);
- assertTrue(item_en_US.mIsSystemLanguage);
+ assertTrue(item_en_us.mIsSystemLanguage);
assertFalse(item_fr.mIsSystemLanguage);
assertTrue(item_en.mIsSystemLanguage);
assertFalse(item_enn.mIsSystemLocale);
assertFalse(item_e.mIsSystemLocale);
- assertFalse(item_EN_US.mIsSystemLocale);
+ assertFalse(item_en_us_allcaps.mIsSystemLocale);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
index 1d914ec083fa..eebc25aab279 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
@@ -60,6 +60,7 @@ public class InputMethodUtilsTest {
private static final boolean IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE = true;
private static final boolean IS_ASCII_CAPABLE = true;
private static final boolean IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE = true;
+ private static final boolean CHECK_COUNTRY = true;
private static final Locale LOCALE_EN = new Locale("en");
private static final Locale LOCALE_EN_US = new Locale("en", "US");
private static final Locale LOCALE_EN_GB = new Locale("en", "GB");
@@ -668,8 +669,6 @@ public class InputMethodUtilsTest {
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final boolean CHECK_COUNTRY = true;
-
{
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoEnUS);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
index b51f4df43259..91342ce925f6 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
@@ -109,7 +110,8 @@ public class RebootEscrowManagerTests {
public interface MockableRebootEscrowInjected {
int getBootCount();
- void reportMetric(boolean success);
+ void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
+ int escrowDurationInSeconds, int vbmetaDigestStatus, int durationSinceBootComplete);
}
static class MockInjector extends RebootEscrowManager.Injector {
@@ -119,6 +121,7 @@ public class RebootEscrowManagerTests {
private final UserManager mUserManager;
private final MockableRebootEscrowInjected mInjected;
private final RebootEscrowKeyStoreManager mKeyStoreManager;
+ private final boolean mServerBased;
MockInjector(Context context, UserManager userManager,
IRebootEscrow rebootEscrow,
@@ -128,6 +131,7 @@ public class RebootEscrowManagerTests {
super(context, storage);
mRebootEscrow = rebootEscrow;
mServiceConnection = null;
+ mServerBased = false;
RebootEscrowProviderHalImpl.Injector halInjector =
new RebootEscrowProviderHalImpl.Injector() {
@Override
@@ -149,6 +153,7 @@ public class RebootEscrowManagerTests {
super(context, storage);
mServiceConnection = serviceConnection;
mRebootEscrow = null;
+ mServerBased = true;
RebootEscrowProviderServerBasedImpl.Injector injector =
new RebootEscrowProviderServerBasedImpl.Injector(serviceConnection);
mRebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(storage, injector);
@@ -168,6 +173,11 @@ public class RebootEscrowManagerTests {
}
@Override
+ public boolean serverBasedResumeOnReboot() {
+ return mServerBased;
+ }
+
+ @Override
public RebootEscrowProviderInterface getRebootEscrowProvider() {
return mRebootEscrowProvider;
}
@@ -195,8 +205,11 @@ public class RebootEscrowManagerTests {
}
@Override
- public void reportMetric(boolean success) {
- mInjected.reportMetric(success);
+ public void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
+ int escrowDurationInSeconds, int vbmetaDigestStatus,
+ int durationSinceBootComplete) {
+ mInjected.reportMetric(success, errorCode, serviceType, attemptCount,
+ escrowDurationInSeconds, vbmetaDigestStatus, durationSinceBootComplete);
}
}
@@ -418,7 +431,9 @@ public class RebootEscrowManagerTests {
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+ doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+ eq(0) /* error code */, eq(1) /* HAL based */, eq(1) /* attempt count */,
+ anyInt(), anyInt(), anyInt());
when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> keyByteCaptor.getValue());
mService.loadRebootEscrowDataIfAvailable(null);
@@ -451,7 +466,9 @@ public class RebootEscrowManagerTests {
// pretend reboot happens here
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+ doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+ eq(0) /* error code */, eq(2) /* Server based */, eq(1) /* attempt count */,
+ anyInt(), anyInt(), anyInt());
when(mServiceConnection.unwrap(any(), anyLong()))
.thenAnswer(invocation -> invocation.getArgument(0));
@@ -485,7 +502,8 @@ public class RebootEscrowManagerTests {
// pretend reboot happens here
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+ doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+ anyInt(), anyInt(), eq(2) /* attempt count */, anyInt(), anyInt(), anyInt());
when(mServiceConnection.unwrap(any(), anyLong()))
.thenThrow(new IOException())
@@ -528,7 +546,8 @@ public class RebootEscrowManagerTests {
mService.loadRebootEscrowDataIfAvailable(null);
verify(mRebootEscrow).retrieveKey();
- verify(mInjected, never()).reportMetric(anyBoolean());
+ verify(mInjected, never()).reportMetric(anyBoolean(), anyInt(), anyInt(), anyInt(),
+ anyInt(), anyInt(), anyInt());
}
@Test
@@ -554,7 +573,8 @@ public class RebootEscrowManagerTests {
when(mRebootEscrow.retrieveKey()).thenReturn(new byte[32]);
mService.loadRebootEscrowDataIfAvailable(null);
- verify(mInjected, never()).reportMetric(anyBoolean());
+ verify(mInjected, never()).reportMetric(anyBoolean(), anyInt(), anyInt(), anyInt(),
+ anyInt(), anyInt(), anyInt());
}
@Test
@@ -588,7 +608,8 @@ public class RebootEscrowManagerTests {
when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> keyByteCaptor.getValue());
mService.loadRebootEscrowDataIfAvailable(null);
- verify(mInjected).reportMetric(eq(true));
+ verify(mInjected).reportMetric(eq(true), eq(0) /* error code */, eq(1) /* HAL based */,
+ eq(1) /* attempt count */, anyInt(), anyInt(), anyInt());
}
@Test
@@ -615,7 +636,9 @@ public class RebootEscrowManagerTests {
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
- doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
+ doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture(),
+ anyInt() /* error code */, eq(1) /* HAL based */, eq(1) /* attempt count */,
+ anyInt(), anyInt(), anyInt());
when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> new byte[32]);
mService.loadRebootEscrowDataIfAvailable(null);
verify(mRebootEscrow).retrieveKey();
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
index dd3054f6543c..3fd2c97075ac 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
@@ -32,7 +32,6 @@ import android.app.KeyguardManager;
import android.content.Context;
import android.os.RemoteException;
import android.security.GateKeeper;
-import android.security.keystore.AndroidKeyStoreSecretKey;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
@@ -59,6 +58,7 @@ import java.security.UnrecoverableKeyException;
import java.util.List;
import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -575,7 +575,7 @@ public class PlatformKeyManagerTest {
return (KeyProtection) mProtectionParameterCaptor.getValue();
}
- private AndroidKeyStoreSecretKey generateAndroidKeyStoreKey() throws Exception {
+ private SecretKey generateAndroidKeyStoreKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(
KEY_ALGORITHM,
ANDROID_KEY_STORE_PROVIDER);
@@ -584,7 +584,7 @@ public class PlatformKeyManagerTest {
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build());
- return (AndroidKeyStoreSecretKey) keyGenerator.generateKey();
+ return keyGenerator.generateKey();
}
class PlatformKeyManagerTestable extends PlatformKeyManager {
diff --git a/services/tests/servicestests/src/com/android/server/rotationresolver/RotationResolverManagerPerUserServiceTest.java b/services/tests/servicestests/src/com/android/server/rotationresolver/RotationResolverManagerPerUserServiceTest.java
index 22c38c1961b8..fa2123c0d09a 100644
--- a/services/tests/servicestests/src/com/android/server/rotationresolver/RotationResolverManagerPerUserServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/rotationresolver/RotationResolverManagerPerUserServiceTest.java
@@ -31,6 +31,7 @@ import android.content.pm.ServiceInfo;
import android.os.CancellationSignal;
import android.os.RemoteException;
import android.rotationresolver.RotationResolverInternal;
+import android.service.rotationresolver.RotationResolutionRequest;
import android.view.Surface;
import androidx.test.core.app.ApplicationProvider;
@@ -58,6 +59,7 @@ public class RotationResolverManagerPerUserServiceTest {
private Context mContext;
private CancellationSignal mCancellationSignal;
private RotationResolverManagerPerUserService mService;
+ private RotationResolutionRequest mRequest;
@Before
public void setUp() throws RemoteException {
@@ -79,9 +81,10 @@ public class RotationResolverManagerPerUserServiceTest {
mCancellationSignal = new CancellationSignal();
+ mRequest = new RotationResolutionRequest("", Surface.ROTATION_0, Surface.ROTATION_0,
+ true, 1000L);
this.mService.mCurrentRequest = new RemoteRotationResolverService.RotationRequest(
- mMockCallbackInternal, Surface.ROTATION_0, Surface.ROTATION_0, "", 1000L,
- mCancellationSignal);
+ mMockCallbackInternal, mRequest, mCancellationSignal);
this.mService.getMaster().mIsServiceEnabled = true;
@@ -99,8 +102,7 @@ public class RotationResolverManagerPerUserServiceTest {
RotationResolverInternal.RotationResolverCallbackInternal callbackInternal =
Mockito.mock(RotationResolverInternal.RotationResolverCallbackInternal.class);
- mService.resolveRotationLocked(callbackInternal, Surface.ROTATION_0, Surface.ROTATION_0,
- "", 1000L, mCancellationSignal);
+ mService.resolveRotationLocked(callbackInternal, mRequest, mCancellationSignal);
verify(callbackInternal).onSuccess(anyInt());
}
@@ -110,8 +112,7 @@ public class RotationResolverManagerPerUserServiceTest {
Mockito.mock(RotationResolverInternal.RotationResolverCallbackInternal.class);
final CancellationSignal cancellationSignal = new CancellationSignal();
- mService.resolveRotationLocked(callbackInternal, Surface.ROTATION_0, Surface.ROTATION_0,
- "", 1000L, cancellationSignal);
+ mService.resolveRotationLocked(callbackInternal, mRequest, cancellationSignal);
cancellationSignal.cancel();
}
@@ -132,7 +133,7 @@ public class RotationResolverManagerPerUserServiceTest {
@Override
public void resolveRotationLocked(RotationRequest request) {
- request.mCallbackInternal.onSuccess(request.mProposedRotation);
+ request.mCallbackInternal.onSuccess(request.mRemoteRequest.getProposedRotation());
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index 5f86d282406a..bbf11fd557a3 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -209,7 +209,7 @@ public class TimeDetectorServiceTest {
@Test(expected = SecurityException.class)
public void testSuggestExternalTime_withoutPermission() {
doThrow(new SecurityException("Mock"))
- .when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
+ .when(mMockContext).enforceCallingPermission(anyString(), any());
ExternalTimeSuggestion externalTimeSuggestion = createExternalTimeSuggestion();
try {
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java
index 5d2755221288..00369829db56 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java
@@ -46,7 +46,7 @@ public class ConfigurationInternalTest {
public void test_unrestricted() {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
@@ -108,7 +108,7 @@ public class ConfigurationInternalTest {
public void test_restricted() {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
.setUserConfigAllowed(false)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
@@ -170,7 +170,7 @@ public class ConfigurationInternalTest {
public void test_autoDetectNotSupported() {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(false)
+ .setTelephonyDetectionFeatureSupported(false)
.setGeoDetectionFeatureSupported(false)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
@@ -232,7 +232,7 @@ public class ConfigurationInternalTest {
public void test_geoDetectNotSupported() {
ConfigurationInternal baseConfig = new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(false)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
index 14e0bbd6fa42..8af2c4d04fd9 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
@@ -364,7 +364,7 @@ public class TimeZoneDetectorServiceTest {
// the tests.
final boolean geoDetectionEnabled = autoDetectionEnabled;
return new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setUserConfigAllowed(true)
.setAutoDetectionEnabled(autoDetectionEnabled)
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
index f1f8b2f5e81a..b0341d7d67d5 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
@@ -90,7 +90,7 @@ public class TimeZoneDetectorStrategyImplTest {
private static final ConfigurationInternal CONFIG_INT_USER_RESTRICTED_AUTO_DISABLED =
new ConfigurationInternal.Builder(USER_ID)
.setUserConfigAllowed(false)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(false)
.setLocationEnabled(true)
@@ -100,7 +100,7 @@ public class TimeZoneDetectorStrategyImplTest {
private static final ConfigurationInternal CONFIG_INT_USER_RESTRICTED_AUTO_ENABLED =
new ConfigurationInternal.Builder(USER_ID)
.setUserConfigAllowed(false)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
@@ -110,17 +110,17 @@ public class TimeZoneDetectorStrategyImplTest {
private static final ConfigurationInternal CONFIG_INT_AUTO_DETECT_NOT_SUPPORTED =
new ConfigurationInternal.Builder(USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(false)
+ .setTelephonyDetectionFeatureSupported(false)
.setGeoDetectionFeatureSupported(false)
.setAutoDetectionEnabled(false)
.setLocationEnabled(true)
.setGeoDetectionEnabled(false)
.build();
- private static final ConfigurationInternal CONFIG_INT_AUTO_SUPPORTED_GEO_NOT_SUPPORTED =
+ private static final ConfigurationInternal CONFIG_INT_TELEPHONY_SUPPORTED_GEO_NOT_SUPPORTED =
new ConfigurationInternal.Builder(USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(false)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
@@ -130,7 +130,7 @@ public class TimeZoneDetectorStrategyImplTest {
private static final ConfigurationInternal CONFIG_INT_AUTO_DISABLED_GEO_DISABLED =
new ConfigurationInternal.Builder(USER_ID)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(false)
.setLocationEnabled(true)
@@ -139,7 +139,7 @@ public class TimeZoneDetectorStrategyImplTest {
private static final ConfigurationInternal CONFIG_INT_AUTO_ENABLED_GEO_DISABLED =
new ConfigurationInternal.Builder(USER_ID)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setUserConfigAllowed(true)
.setAutoDetectionEnabled(true)
@@ -149,7 +149,7 @@ public class TimeZoneDetectorStrategyImplTest {
private static final ConfigurationInternal CONFIG_INT_AUTO_ENABLED_GEO_ENABLED =
new ConfigurationInternal.Builder(USER_ID)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setUserConfigAllowed(true)
.setAutoDetectionEnabled(true)
@@ -266,7 +266,8 @@ public class TimeZoneDetectorStrategyImplTest {
@Test
public void testUpdateConfiguration_autoDetectSupportedGeoNotSupported() {
- Script script = new Script().initializeConfig(CONFIG_INT_AUTO_SUPPORTED_GEO_NOT_SUPPORTED);
+ Script script = new Script().initializeConfig(
+ CONFIG_INT_TELEPHONY_SUPPORTED_GEO_NOT_SUPPORTED);
// Update the configuration with auto detection disabled.
script.simulateUpdateConfiguration(
@@ -274,7 +275,7 @@ public class TimeZoneDetectorStrategyImplTest {
// The settings should have been changed and the StrategyListener onChange() called.
ConfigurationInternal expectedConfig =
- new ConfigurationInternal.Builder(CONFIG_INT_AUTO_SUPPORTED_GEO_NOT_SUPPORTED)
+ new ConfigurationInternal.Builder(CONFIG_INT_TELEPHONY_SUPPORTED_GEO_NOT_SUPPORTED)
.setAutoDetectionEnabled(false)
.build();
script.verifyConfigurationChangedAndReset(expectedConfig);
@@ -675,6 +676,8 @@ public class TimeZoneDetectorStrategyImplTest {
script.simulateManualTimeZoneSuggestion(
USER_ID, createManualSuggestion("Europe/Paris"), false /* expectedResult */)
.verifyTimeZoneNotChanged();
+
+ assertNull(mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
@@ -687,6 +690,8 @@ public class TimeZoneDetectorStrategyImplTest {
script.simulateManualTimeZoneSuggestion(
USER_ID, createManualSuggestion("Europe/Paris"), false /* expectedResult */)
.verifyTimeZoneNotChanged();
+
+ assertNull(mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
@@ -700,6 +705,8 @@ public class TimeZoneDetectorStrategyImplTest {
script.simulateManualTimeZoneSuggestion(
USER_ID, manualSuggestion, true /* expectedResult */)
.verifyTimeZoneChangedAndReset(manualSuggestion);
+
+ assertEquals(manualSuggestion, mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
@@ -713,6 +720,8 @@ public class TimeZoneDetectorStrategyImplTest {
script.simulateManualTimeZoneSuggestion(
USER_ID, manualSuggestion, false /* expectedResult */)
.verifyTimeZoneNotChanged();
+
+ assertNull(mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
@@ -726,6 +735,8 @@ public class TimeZoneDetectorStrategyImplTest {
script.simulateManualTimeZoneSuggestion(
USER_ID, manualSuggestion, true /* expectedResult */)
.verifyTimeZoneChangedAndReset(manualSuggestion);
+
+ assertEquals(manualSuggestion, mTimeZoneDetectorStrategy.getLatestManualSuggestion());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java
index 4284240c72b4..3daa7f0483c6 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ControllerImplTest.java
@@ -72,6 +72,7 @@ public class ControllerImplTest {
private TestCallback mTestCallback;
private TestLocationTimeZoneProvider mTestPrimaryLocationTimeZoneProvider;
private TestLocationTimeZoneProvider mTestSecondaryLocationTimeZoneProvider;
+ private FakeTimeZoneIdValidator mTimeZoneAvailabilityChecker;
@Before
public void setUp() {
@@ -80,10 +81,13 @@ public class ControllerImplTest {
// will never get a chance to execute.
mTestThreadingDomain = new TestThreadingDomain();
mTestCallback = new TestCallback(mTestThreadingDomain);
+ mTimeZoneAvailabilityChecker = new FakeTimeZoneIdValidator();
mTestPrimaryLocationTimeZoneProvider =
- new TestLocationTimeZoneProvider(mTestThreadingDomain, "primary");
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain, "primary", mTimeZoneAvailabilityChecker);
mTestSecondaryLocationTimeZoneProvider =
- new TestLocationTimeZoneProvider(mTestThreadingDomain, "secondary");
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain, "secondary", mTimeZoneAvailabilityChecker);
}
@Test
@@ -1177,8 +1181,10 @@ public class ControllerImplTest {
/**
* Creates the instance.
*/
- TestLocationTimeZoneProvider(ThreadingDomain threadingDomain, String providerName) {
- super(threadingDomain, providerName);
+ TestLocationTimeZoneProvider(ThreadingDomain threadingDomain,
+ String providerName,
+ TimeZoneIdValidator timeZoneIdValidator) {
+ super(threadingDomain, providerName, timeZoneIdValidator);
}
public void setFailDuringInitialization(boolean failInitialization) {
@@ -1311,4 +1317,14 @@ public class ControllerImplTest {
mTestProviderState.commitLatest();
}
}
+
+ private static final class FakeTimeZoneIdValidator
+ implements LocationTimeZoneProvider.TimeZoneIdValidator {
+
+ @Override
+ public boolean isValid(@NonNull String timeZoneId) {
+ return true;
+ }
+
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java
index 095c868fc74c..278fdaff260f 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/LocationTimeZoneProviderTest.java
@@ -32,6 +32,8 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static java.util.Arrays.asList;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
@@ -50,7 +52,9 @@ import org.junit.Test;
import java.time.Duration;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -62,20 +66,25 @@ public class LocationTimeZoneProviderTest {
private static final long ARBITRARY_ELAPSED_REALTIME_MILLIS = 123456789L;
private TestThreadingDomain mTestThreadingDomain;
-
private TestProviderListener mProviderListener;
+ private FakeTimeZoneIdValidator mTimeZoneAvailabilityChecker;
@Before
public void setUp() {
mTestThreadingDomain = new TestThreadingDomain();
mProviderListener = new TestProviderListener();
+ mTimeZoneAvailabilityChecker = new FakeTimeZoneIdValidator();
}
@Test
public void lifecycle() {
String providerName = "arbitrary";
TestLocationTimeZoneProvider provider =
- new TestLocationTimeZoneProvider(mTestThreadingDomain, providerName);
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain,
+ providerName,
+ mTimeZoneAvailabilityChecker);
+ mTimeZoneAvailabilityChecker.validIds("Europe/London");
// initialize()
provider.initialize(mProviderListener);
@@ -163,7 +172,10 @@ public class LocationTimeZoneProviderTest {
public void defaultHandleTestCommandImpl() {
String providerName = "primary";
TestLocationTimeZoneProvider provider =
- new TestLocationTimeZoneProvider(mTestThreadingDomain, providerName);
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain,
+ providerName,
+ mTimeZoneAvailabilityChecker);
TestCommand testCommand = TestCommand.createForTests("test", new Bundle());
AtomicReference<Bundle> resultReference = new AtomicReference<>();
@@ -180,8 +192,12 @@ public class LocationTimeZoneProviderTest {
public void stateRecording() {
String providerName = "primary";
TestLocationTimeZoneProvider provider =
- new TestLocationTimeZoneProvider(mTestThreadingDomain, providerName);
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain,
+ providerName,
+ mTimeZoneAvailabilityChecker);
provider.setStateChangeRecordingEnabled(true);
+ mTimeZoneAvailabilityChecker.validIds("Europe/London");
// initialize()
provider.initialize(mProviderListener);
@@ -218,6 +234,34 @@ public class LocationTimeZoneProviderTest {
provider.assertLatestRecordedState(PROVIDER_STATE_DESTROYED);
}
+ @Test
+ public void considerSuggestionWithInvalidTimeZoneIdsAsUncertain() {
+ String providerName = "primary";
+ TestLocationTimeZoneProvider provider =
+ new TestLocationTimeZoneProvider(
+ mTestThreadingDomain,
+ providerName,
+ mTimeZoneAvailabilityChecker);
+ provider.setStateChangeRecordingEnabled(true);
+ provider.initialize(mProviderListener);
+
+ ConfigurationInternal config = USER1_CONFIG_GEO_DETECTION_ENABLED;
+ Duration arbitraryInitializationTimeout = Duration.ofMinutes(5);
+ Duration arbitraryInitializationTimeoutFuzz = Duration.ofMinutes(2);
+ provider.startUpdates(config, arbitraryInitializationTimeout,
+ arbitraryInitializationTimeoutFuzz);
+
+ List<String> invalidTimeZoneIds = asList("Atlantic/Atlantis");
+ TimeZoneProviderSuggestion invalidIdSuggestion = new TimeZoneProviderSuggestion.Builder()
+ .setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS)
+ .setTimeZoneIds(invalidTimeZoneIds)
+ .build();
+ TimeZoneProviderEvent event =
+ TimeZoneProviderEvent.createSuggestionEvent(invalidIdSuggestion);
+ provider.simulateProviderEventReceived(event);
+ provider.assertLatestRecordedState(PROVIDER_STATE_STARTED_UNCERTAIN);
+ }
+
/** A test stand-in for the real {@link LocationTimeZoneProviderController}'s listener. */
private static class TestProviderListener implements ProviderListener {
@@ -251,8 +295,9 @@ public class LocationTimeZoneProviderTest {
/** Creates the instance. */
TestLocationTimeZoneProvider(@NonNull ThreadingDomain threadingDomain,
- @NonNull String providerName) {
- super(threadingDomain, providerName);
+ @NonNull String providerName,
+ @NonNull TimeZoneIdValidator timeZoneIdValidator) {
+ super(threadingDomain, providerName, timeZoneIdValidator);
}
@Override
@@ -308,4 +353,19 @@ public class LocationTimeZoneProviderTest {
recordedStates.get(recordedStates.size() - 1).stateEnum);
}
}
+
+ private static final class FakeTimeZoneIdValidator
+ implements LocationTimeZoneProvider.TimeZoneIdValidator {
+ private final Set<String> mValidTimeZoneIds = new HashSet<>();
+
+ @Override
+ public boolean isValid(@NonNull String timeZoneId) {
+ return mValidTimeZoneIds.contains(timeZoneId);
+ }
+
+ public void validIds(String... timeZoneIdss) {
+ mValidTimeZoneIds.addAll(asList(timeZoneIdss));
+ }
+
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/TestSupport.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/TestSupport.java
index 8280cdcb18c4..16ac1d602de5 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/location/TestSupport.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/TestSupport.java
@@ -44,7 +44,7 @@ final class TestSupport {
@UserIdInt int userId, boolean geoDetectionEnabled) {
return new ConfigurationInternal.Builder(userId)
.setUserConfigAllowed(true)
- .setAutoDetectionFeatureSupported(true)
+ .setTelephonyDetectionFeatureSupported(true)
.setGeoDetectionFeatureSupported(true)
.setAutoDetectionEnabled(true)
.setLocationEnabled(true)
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidatorTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidatorTest.java
new file mode 100644
index 000000000000..5561b2c6a7aa
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneIdValidatorTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.timezonedetector.location;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.TimeZone;
+
+@Presubmit
+public class ZoneInfoDbTimeZoneIdValidatorTest {
+ private final LocationTimeZoneProvider.TimeZoneIdValidator mTzChecker =
+ new ZoneInfoDbTimeZoneIdValidator();
+
+ @Test
+ public void timeZoneIdsFromZoneInfoDbAreValid() {
+ for (String timeZone : TimeZone.getAvailableIDs()) {
+ assertWithMessage("Time zone %s should be supported", timeZone)
+ .that(mTzChecker.isValid(timeZone)).isTrue();
+ }
+ }
+
+ @Test
+ public void nonExistingZones_areNotSupported() {
+ List<String> nonExistingTimeZones = Arrays.asList(
+ "SystemV/HST10", "Atlantic/Atlantis", "EUROPE/LONDON", "Etc/GMT-5:30"
+ );
+
+ for (String timeZone : nonExistingTimeZones) {
+ assertWithMessage(timeZone + " is not a valid time zone")
+ .that(mTzChecker.isValid(timeZone))
+ .isFalse();
+ }
+ }
+}
diff --git a/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS b/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS
new file mode 100644
index 000000000000..72c0a9e6e90c
--- /dev/null
+++ b/services/tests/servicestests/test-apps/SimpleServiceTestApp/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/am/OWNERS
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index 5182b3b69655..b921838e0bfc 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -243,10 +243,18 @@ public class ShortcutManagerTestUtils {
final UserHandle user = getParentUser(context);
List<String> roleHolders = callWithShellPermissionIdentity(
() -> roleManager.getRoleHoldersAsUser(RoleManager.ROLE_HOME, user));
- if (roleHolders.size() == 1) {
+ int size = roleHolders.size();
+ if (size == 1) {
return roleHolders.get(0);
}
- fail("Failed to get the default launcher for user " + context.getUserId());
+
+ if (size > 1) {
+ fail("Too many launchers for user " + user.getIdentifier() + " using role "
+ + RoleManager.ROLE_HOME + ": " + roleHolders);
+ } else {
+ fail("No default launcher for user " + user.getIdentifier() + " using role "
+ + RoleManager.ROLE_HOME);
+ }
return null;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index 2fdd63ed93d5..c98e013479f4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -36,6 +36,8 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMAT
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -208,18 +210,20 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
}
@Test
- public void testZeroAnimations() {
+ public void testZeroAnimations() throws Exception {
mController.goodToGo(TRANSIT_OLD_NONE);
- verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+ verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
+ verify(mMockRunner).onAnimationCancelled();
}
@Test
- public void testNotReallyStarted() {
+ public void testNotReallyStarted() throws Exception {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
mController.createRemoteAnimationRecord(win.mActivityRecord,
new Point(50, 100), null, new Rect(50, 100, 150, 150), null);
mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
- verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+ verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
+ verify(mMockRunner).onAnimationCancelled();
}
@Test
@@ -250,7 +254,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
}
@Test
- public void testRemovedBeforeStarted() {
+ public void testRemovedBeforeStarted() throws Exception {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter;
@@ -258,7 +262,8 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
mFinishedCallback);
win.mActivityRecord.removeImmediately();
mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
- verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+ verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
+ verify(mMockRunner).onAnimationCancelled();
verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
eq(adapter));
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 2f1d7eb404ad..36cf9c9fb0cf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -40,6 +40,8 @@ import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.Task.ActivityState.STOPPED;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -117,18 +119,19 @@ public class SizeCompatTests extends WindowTestsBase {
@Test
public void testKeepBoundsWhenChangingFromFreeformToFullscreen() {
removeGlobalMinSizeRestriction();
- // create freeform display and a freeform app
+ // Create landscape freeform display and a freeform app.
DisplayContent display = new TestDisplayContent.Builder(mAtm, 2000, 1000)
.setCanRotate(false)
.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM).build();
setUpApp(display);
- // Put app window into freeform and then make it a compat app.
+ // Put app window into portrait freeform and then make it a compat app.
final Rect bounds = new Rect(100, 100, 400, 600);
mTask.setBounds(bounds);
-
prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
assertEquals(bounds, mActivity.getBounds());
+ // Activity is not yet in size compat mode; it is filling the freeform window.
+ assertMaxBoundsInheritDisplayAreaBounds();
// The activity should be able to accept negative x position [-150, 100 - 150, 600].
final int dx = bounds.left + bounds.width() / 2;
@@ -137,7 +140,7 @@ public class SizeCompatTests extends WindowTestsBase {
final int density = mActivity.getConfiguration().densityDpi;
- // change display configuration to fullscreen
+ // Change display configuration to fullscreen.
Configuration c = new Configuration(display.getRequestedOverrideConfiguration());
c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
display.onRequestedOverrideConfigurationChanged(c);
@@ -147,6 +150,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(bounds.width(), mActivity.getBounds().width());
assertEquals(bounds.height(), mActivity.getBounds().height());
assertEquals(density, mActivity.getConfiguration().densityDpi);
+ // Size compat mode is sandboxed at the activity level.
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -172,6 +177,12 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(appBounds.height(), appBounds.width() * aspectRatio, 0.5f /* delta */);
// The decor height should be a part of the effective bounds.
assertEquals(mActivity.getBounds().height(), appBounds.height() + notchHeight);
+ // Activity max bounds should be sandboxed; activity is letterboxed due to aspect ratio.
+ assertActivityMaxBoundsSandboxed();
+ // Activity max bounds ignore notch, since an app can be shown past the notch (although app
+ // is currently limited by the notch).
+ assertThat(mActivity.getWindowConfiguration().getMaxBounds().height())
+ .isEqualTo(displayBounds.height());
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
assertFitted();
@@ -181,9 +192,17 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */);
// The notch is no longer on top.
assertEquals(appBounds, mActivity.getBounds());
+ // Activity max bounds are sandboxed.
+ assertActivityMaxBoundsSandboxed();
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
assertFitted();
+ // Activity max bounds should be sandboxed; activity is letterboxed due to aspect ratio.
+ assertActivityMaxBoundsSandboxed();
+ // Activity max bounds ignore notch, since an app can be shown past the notch (although app
+ // is currently limited by the notch).
+ assertThat(mActivity.getWindowConfiguration().getMaxBounds().height())
+ .isEqualTo(displayBounds.height());
}
@Test
@@ -206,6 +225,9 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(originalBounds.width(), mActivity.getBounds().width());
assertEquals(originalBounds.height(), mActivity.getBounds().height());
assertEquals(originalDpi, mActivity.getConfiguration().densityDpi);
+ // Activity is sandboxed; it is in size compat mode since it is not resizable and has a
+ // max aspect ratio.
+ assertActivityMaxBoundsSandboxed();
assertScaled();
}
@@ -213,11 +235,13 @@ public class SizeCompatTests extends WindowTestsBase {
public void testFixedScreenBoundsWhenDisplaySizeChanged() {
setUpDisplaySizeWithApp(1000, 2500);
prepareUnresizable(mActivity, -1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+ final DisplayContent display = mActivity.mDisplayContent;
assertFitted();
+ // Activity inherits bounds from TaskDisplayArea, since not sandboxed.
+ assertMaxBoundsInheritDisplayAreaBounds();
final Rect origBounds = new Rect(mActivity.getBounds());
final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
- final DisplayContent display = mActivity.mDisplayContent;
// Change the size of current display.
resizeDisplay(display, 1000, 2000);
@@ -234,6 +258,8 @@ public class SizeCompatTests extends WindowTestsBase {
// The position of configuration bounds should be the same as compat bounds.
assertEquals(mActivity.getBounds().left, currentBounds.left);
assertEquals(mActivity.getBounds().top, currentBounds.top);
+ // Activity is sandboxed to the offset size compat bounds.
+ assertActivityMaxBoundsSandboxed();
// Change display size to a different orientation
resizeDisplay(display, 2000, 1000);
@@ -242,6 +268,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(origBounds.height(), currentBounds.height());
assertEquals(ORIENTATION_LANDSCAPE, display.getConfiguration().orientation);
assertEquals(Configuration.ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation);
+ // Activity is sandboxed to the offset size compat bounds.
+ assertActivityMaxBoundsSandboxed();
// The previous resize operation doesn't consider the rotation change after size changed.
// These setups apply the requested orientation to rotation as real case that the top fixed
@@ -261,6 +289,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(origBounds.height(), currentBounds.height());
assertEquals(offsetX, currentBounds.left);
assertScaled();
+ // Activity is sandboxed due to size compat mode.
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -276,6 +306,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(bounds.width(), bounds.height() * maxAspect, 0.0001f /* delta */);
// The position should be horizontal centered.
assertEquals((displayWidth - bounds.width()) / 2, bounds.left);
+ // Activity max bounds should be sandboxed since it is letterboxed.
+ assertActivityMaxBoundsSandboxed();
mActivity.mDisplayContent.setImeLayeringTarget(addWindowToActivity(mActivity));
// Make sure IME cannot attach to the app, otherwise IME window will also be shifted.
@@ -287,6 +319,8 @@ public class SizeCompatTests extends WindowTestsBase {
// It should keep non-attachable because the resolved bounds will be computed according to
// the aspect ratio that won't match its parent bounds.
assertFalse(mActivity.mDisplayContent.isImeAttachedToApp());
+ // Activity max bounds should be sandboxed since it is letterboxed.
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -312,14 +346,13 @@ public class SizeCompatTests extends WindowTestsBase {
}
@Test
- public void testMoveToDifferentOrientDisplay() {
+ public void testMoveToDifferentOrientationDisplay() {
setUpDisplaySizeWithApp(1000, 2500);
prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
assertFitted();
- final Rect configBounds = mActivity.getWindowConfiguration().getBounds();
- final int origWidth = configBounds.width();
- final int origHeight = configBounds.height();
+ final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
+ final Rect originalBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
final int notchHeight = 100;
final DisplayContent newDisplay = new TestDisplayContent.Builder(mAtm, 2000, 1000)
@@ -328,37 +361,45 @@ public class SizeCompatTests extends WindowTestsBase {
// Move the non-resizable activity to the new display.
mTask.reparent(newDisplay.getDefaultTaskDisplayArea(), true /* onTop */);
// The configuration bounds [820, 0 - 1820, 2500] should keep the same.
- assertEquals(origWidth, configBounds.width());
- assertEquals(origHeight, configBounds.height());
+ assertEquals(originalBounds.width(), currentBounds.width());
+ assertEquals(originalBounds.height(), currentBounds.height());
assertScaled();
+ // Activity max bounds are sandboxed due to size compat mode on the new display.
+ assertActivityMaxBoundsSandboxed();
final Rect newDisplayBounds = newDisplay.getWindowConfiguration().getBounds();
// The scaled bounds should exclude notch area (1000 - 100 == 360 * 2500 / 1000 = 900).
assertEquals(newDisplayBounds.height() - notchHeight,
- (int) ((float) mActivity.getBounds().width() * origHeight / origWidth));
+ (int) ((float) mActivity.getBounds().width() * originalBounds.height()
+ / originalBounds.width()));
// Recompute the natural configuration in the new display.
mActivity.clearSizeCompatMode();
mActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
// Because the display cannot rotate, the portrait activity will fit the short side of
// display with keeping portrait bounds [200, 0 - 700, 1000] in center.
- assertEquals(newDisplayBounds.height(), configBounds.height());
- assertEquals(configBounds.height() * newDisplayBounds.height() / newDisplayBounds.width(),
- configBounds.width());
+ assertEquals(newDisplayBounds.height(), currentBounds.height());
+ assertEquals(currentBounds.height() * newDisplayBounds.height() / newDisplayBounds.width(),
+ currentBounds.width());
assertFitted();
// The appBounds should be [200, 100 - 700, 1000].
final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
- assertEquals(configBounds.width(), appBounds.width());
- assertEquals(configBounds.height() - notchHeight, appBounds.height());
+ assertEquals(currentBounds.width(), appBounds.width());
+ assertEquals(currentBounds.height() - notchHeight, appBounds.height());
+ // Activity max bounds are sandboxed due to letterboxing from orientation mismatch with
+ // display.
+ assertActivityMaxBoundsSandboxed();
}
@Test
- public void testFixedOrientRotateCutoutDisplay() {
+ public void testFixedOrientationRotateCutoutDisplay() {
// Create a display with a notch/cutout
final int notchHeight = 60;
- setUpApp(new TestDisplayContent.Builder(mAtm, 1000, 2500)
+ final int width = 1000;
+ setUpApp(new TestDisplayContent.Builder(mAtm, width, 2500)
.setNotch(notchHeight).build());
- // Bounds=[0, 0 - 1000, 1460], AppBounds=[0, 60 - 1000, 1460].
+ // Bounds=[0, 0 - 1000, 1400], AppBounds=[0, 60 - 1000, 1460].
+ final float maxAspect = 1.4f;
prepareUnresizable(mActivity, 1.4f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
@@ -366,6 +407,11 @@ public class SizeCompatTests extends WindowTestsBase {
final Rect origBounds = new Rect(currentBounds);
final Rect origAppBounds = new Rect(appBounds);
+ // Activity is sandboxed, and bounds include the area consumed by the notch.
+ assertActivityMaxBoundsSandboxed();
+ assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds().height())
+ .isEqualTo(Math.round(width * maxAspect) + notchHeight);
+
// Although the activity is fixed orientation, force rotate the display.
rotateDisplay(mActivity.mDisplayContent, ROTATION_270);
assertEquals(ROTATION_270, mTask.getWindowConfiguration().getRotation());
@@ -381,10 +427,13 @@ public class SizeCompatTests extends WindowTestsBase {
// The position in configuration should be global coordinates.
assertEquals(mActivity.getBounds().left, currentBounds.left);
assertEquals(mActivity.getBounds().top, currentBounds.top);
+
+ // Activity max bounds are sandboxed due to size compat mode.
+ assertActivityMaxBoundsSandboxed();
}
@Test
- public void testFixedAspOrientChangeOrient() {
+ public void testFixedAspectRatioOrientationChangeOrientation() {
setUpDisplaySizeWithApp(1000, 2500);
final float maxAspect = 1.4f;
@@ -396,6 +445,8 @@ public class SizeCompatTests extends WindowTestsBase {
final Rect originalAppBounds = new Rect(mActivity.getWindowConfiguration().getAppBounds());
assertEquals((int) (originalBounds.width() * maxAspect), originalBounds.height());
+ // Activity is sandboxed due to fixed aspect ratio.
+ assertActivityMaxBoundsSandboxed();
// Change the fixed orientation.
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
@@ -407,6 +458,8 @@ public class SizeCompatTests extends WindowTestsBase {
mActivity.getWindowConfiguration().getAppBounds().height());
assertEquals(originalAppBounds.height(),
mActivity.getWindowConfiguration().getAppBounds().width());
+ // Activity is sandboxed due to fixed aspect ratio.
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -455,6 +508,8 @@ public class SizeCompatTests extends WindowTestsBase {
// restarted and the override configuration won't be cleared.
verify(mActivity, never()).restartProcessIfVisible();
assertScaled();
+ // Activity max bounds are sandboxed due to size compat mode, even if is not visible.
+ assertActivityMaxBoundsSandboxed();
// Change display density
display.mBaseDisplayDensity = (int) (0.7f * display.mBaseDisplayDensity);
@@ -550,13 +605,13 @@ public class SizeCompatTests extends WindowTestsBase {
}
@Test
- public void testShouldUseSizeCompatModeOnResizableTask() {
+ public void testShouldCreateCompatDisplayInsetsOnResizeableTask() {
setUpDisplaySizeWithApp(1000, 2500);
// Make the task root resizable.
mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
- // Create a size compat activity on the same task.
+ // Create an activity on the same task.
final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(mTask)
.setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
@@ -568,26 +623,112 @@ public class SizeCompatTests extends WindowTestsBase {
// in multi-window mode.
mTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
assertFalse(activity.shouldCreateCompatDisplayInsets());
+ // Activity should not be sandboxed.
+ assertMaxBoundsInheritDisplayAreaBounds();
// The non-resizable activity should not be size compat because the display support
// changing windowing mode from fullscreen to freeform.
mTask.mDisplayContent.setDisplayWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
mTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
assertFalse(activity.shouldCreateCompatDisplayInsets());
+ // Activity should not be sandboxed.
+ assertMaxBoundsInheritDisplayAreaBounds();
+ }
+
+ @Test
+ public void testShouldCreateCompatDisplayInsetsWhenUnresizeableAndSupportsSizeChangesTrue() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+ .setSupportsSizeChanges(true)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertFalse(activity.shouldCreateCompatDisplayInsets());
+ }
+
+ @Test
+ public void testShouldCreateCompatDisplayInsetsWhenUnresizeableAndSupportsSizeChangesFalse() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+ .setSupportsSizeChanges(false)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertTrue(activity.shouldCreateCompatDisplayInsets());
+ }
+
+ @Test
+ public void testShouldCreateCompatDisplayInsetsWhenResizeableAndSupportsSizeChangesFalse() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_RESIZEABLE)
+ .setSupportsSizeChanges(false)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertFalse(activity.shouldCreateCompatDisplayInsets());
+ }
+
+ @Test
+ public void
+ testShouldCreateCompatDisplayInsetsWhenUnfixedOrientationSupportsSizeChangesFalse() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+ .setSupportsSizeChanges(false)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertFalse(activity.shouldCreateCompatDisplayInsets());
}
@Test
@EnableCompatChanges({ActivityInfo.FORCE_RESIZE_APP})
- public void testNoSizeCompatWhenPerAppOverrideSet() {
+ public void testShouldCreateCompatDisplayInsetsWhenForceResizeAppOverrideSet() {
setUpDisplaySizeWithApp(1000, 2500);
// Make the task root resizable.
mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
- // Create a size compat activity on the same task.
+ // Create an activity on the same task.
final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(mTask)
.setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
+ .setSupportsSizeChanges(false)
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
.setComponent(ComponentName.createRelative(mContext,
SizeCompatTests.class.getName()))
@@ -597,6 +738,48 @@ public class SizeCompatTests extends WindowTestsBase {
}
@Test
+ @EnableCompatChanges({ActivityInfo.FORCE_NON_RESIZE_APP})
+ public void testShouldCreateCompatDisplayInsetsWhenForceNonResizeOverrideSet() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_RESIZEABLE)
+ .setSupportsSizeChanges(true)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertTrue(activity.shouldCreateCompatDisplayInsets());
+ }
+
+ @Test
+ @EnableCompatChanges({ActivityInfo.FORCE_NON_RESIZE_APP})
+ public void testShouldCreateCompatDisplayInsetsWhenForceNonResizeSetAndUnfixedOrientation() {
+ setUpDisplaySizeWithApp(1000, 2500);
+
+ // Make the task root resizable.
+ mActivity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+
+ // Create an activity on the same task.
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setResizeMode(ActivityInfo.RESIZE_MODE_RESIZEABLE)
+ .setSupportsSizeChanges(true)
+ .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+ assertTrue(activity.shouldCreateCompatDisplayInsets());
+ }
+
+ @Test
public void testLaunchWithFixedRotationTransform() {
final int dw = 1000;
final int dh = 2500;
@@ -637,6 +820,9 @@ public class SizeCompatTests extends WindowTestsBase {
// be transparent.
assertFalse(displayPolicy.isFullyTransparentAllowed(w, TYPE_STATUS_BAR));
+ // Activity is sandboxed.
+ assertActivityMaxBoundsSandboxed();
+
// Make the activity fill the display.
prepareUnresizable(mActivity, 10 /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
w.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
@@ -646,6 +832,7 @@ public class SizeCompatTests extends WindowTestsBase {
// The letterbox should only cover the notch area, so status bar can be transparent.
assertEquals(new Rect(notchHeight, 0, 0, 0), mActivity.getLetterboxInsets());
assertTrue(displayPolicy.isFullyTransparentAllowed(w, TYPE_STATUS_BAR));
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -668,6 +855,7 @@ public class SizeCompatTests extends WindowTestsBase {
// App should launch in fixed orientation letterbox.
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
// Activity bounds should be 700x1400 with the ratio as the display.
assertEquals(displayBounds.height(), activityBounds.height());
@@ -789,6 +977,7 @@ public class SizeCompatTests extends WindowTestsBase {
assertScaled();
assertEquals(activityBounds.width(), newActivityBounds.width());
assertEquals(activityBounds.height(), newActivityBounds.height());
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -800,29 +989,29 @@ public class SizeCompatTests extends WindowTestsBase {
// Portrait fixed app without max aspect.
prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
- Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
- Rect activityBounds = new Rect(mActivity.getBounds());
-
// App should launch in fullscreen.
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
- assertEquals(displayBounds, activityBounds);
+ // Activity inherits max bounds from TaskDisplayArea.
+ assertMaxBoundsInheritDisplayAreaBounds();
// Rotate display to landscape.
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
- displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
- activityBounds = new Rect(mActivity.getBounds());
- assertTrue(displayBounds.width() > displayBounds.height());
+ final Rect rotatedDisplayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+ final Rect rotatedActivityBounds = new Rect(mActivity.getBounds());
+ assertTrue(rotatedDisplayBounds.width() > rotatedDisplayBounds.height());
// App should be in size compat.
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertScaled();
+ assertThat(mActivity.inSizeCompatMode()).isTrue();
+ assertActivityMaxBoundsSandboxed();
// App bounds should be 700x1400 with the ratio as the display.
- assertEquals(displayBounds.height(), activityBounds.height());
- assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(),
- activityBounds.width());
+ assertEquals(rotatedDisplayBounds.height(), rotatedActivityBounds.height());
+ assertEquals(rotatedDisplayBounds.height() * rotatedDisplayBounds.height()
+ / rotatedDisplayBounds.width(), rotatedActivityBounds.width());
}
@Test
@@ -859,6 +1048,7 @@ public class SizeCompatTests extends WindowTestsBase {
// has 700x1400 bounds with the ratio as the display.
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(newActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
assertEquals(taskBounds, displayBounds);
assertEquals(displayBounds.height(), newActivityBounds.height());
assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(),
@@ -899,6 +1089,11 @@ public class SizeCompatTests extends WindowTestsBase {
// Task bounds should fill parent bounds.
assertEquals(displayBounds, taskBounds);
+ // Prior and new activity max bounds are sandboxed due to letterbox.
+ assertThat(newActivity.getConfiguration().windowConfiguration.getMaxBounds())
+ .isEqualTo(newActivityBounds);
+ assertActivityMaxBoundsSandboxed();
+
// Activity bounds should be (1400 / 1.3 = 1076)x1400 with the app requested ratio.
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(newActivity.inSizeCompatMode());
@@ -927,6 +1122,9 @@ public class SizeCompatTests extends WindowTestsBase {
// App should be in size compat.
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertScaled();
+ assertThat(mActivity.inSizeCompatMode()).isTrue();
+ // Activity max bounds are sandboxed due to size compat mode.
+ assertActivityMaxBoundsSandboxed();
final Rect activityBounds = new Rect(mActivity.getBounds());
mTask.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */);
@@ -936,6 +1134,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertScaled();
assertEquals(activityBounds, mActivity.getBounds());
+ // Activity max bounds are sandboxed due to size compat.
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -951,6 +1151,7 @@ public class SizeCompatTests extends WindowTestsBase {
// In fixed orientation letterbox
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
// Rotate display to portrait.
rotateDisplay(display, ROTATION_90);
@@ -958,13 +1159,15 @@ public class SizeCompatTests extends WindowTestsBase {
// App should be in size compat.
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertScaled();
+ assertActivityMaxBoundsSandboxed();
// Rotate display to landscape.
rotateDisplay(display, ROTATION_180);
- // In Task letterbox
+ // In activity letterbox
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -982,20 +1185,23 @@ public class SizeCompatTests extends WindowTestsBase {
// In fixed orientation letterbox
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
- // Rotate display to portrait.
+ // Rotate display to landscape.
rotateDisplay(display, ROTATION_90);
// App should be in size compat.
assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertScaled();
+ assertActivityMaxBoundsSandboxed();
- // Rotate display to landscape.
+ // Rotate display to portrait.
rotateDisplay(display, ROTATION_180);
// In fixed orientation letterbox
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFalse(mActivity.inSizeCompatMode());
+ assertActivityMaxBoundsSandboxed();
}
@Test
@@ -1012,12 +1218,18 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(ORIENTATION_LANDSCAPE, display.getConfiguration().orientation);
assertEquals(2800, displayBounds.width());
assertEquals(1400, displayBounds.height());
- taskDisplayArea.setBounds(0, 0, 2400, 1000);
+ Rect displayAreaBounds = new Rect(0, 0, 2400, 1000);
+ taskDisplayArea.setBounds(displayAreaBounds);
final Rect activityBounds = new Rect(mActivity.getBounds());
assertFalse(mActivity.inSizeCompatMode());
assertEquals(2400, activityBounds.width());
assertEquals(1000, activityBounds.height());
+ // Task and activity maximum bounds inherit from TaskDisplayArea bounds.
+ assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds())
+ .isEqualTo(displayAreaBounds);
+ assertThat(mTask.getConfiguration().windowConfiguration.getMaxBounds())
+ .isEqualTo(displayAreaBounds);
}
@Test
@@ -1042,6 +1254,7 @@ public class SizeCompatTests extends WindowTestsBase {
assertScaled();
assertEquals(originalBounds,
mActivity.getConfiguration().windowConfiguration.getBounds());
+ assertActivityMaxBoundsSandboxed();
// Recompute the natural configuration of the non-resizable activity and the split screen.
mActivity.clearSizeCompatMode();
@@ -1053,12 +1266,13 @@ public class SizeCompatTests extends WindowTestsBase {
addWindowToActivity(mActivity);
mActivity.mRootWindowContainer.performSurfacePlacement();
- // Split screen is also in portrait [1000,1400], so activty should be in fixed orientation
+ // Split screen is also in portrait [1000,1400], so activity should be in fixed orientation
// letterbox.
assertEquals(ORIENTATION_PORTRAIT, mTask.getConfiguration().orientation);
assertEquals(ORIENTATION_LANDSCAPE, mActivity.getConfiguration().orientation);
assertFitted();
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+ assertActivityMaxBoundsSandboxed();
// Letterbox should fill the gap between the split screen and the letterboxed activity.
final Rect primarySplitBounds = new Rect(organizer.mPrimary.getBounds());
@@ -1165,6 +1379,22 @@ public class SizeCompatTests extends WindowTestsBase {
assertFalse(mActivity.hasSizeCompatBounds());
}
+ /** Asserts the activity max bounds inherit from the TaskDisplayArea. */
+ private void assertMaxBoundsInheritDisplayAreaBounds() {
+ assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds())
+ .isEqualTo(mTask.getDisplayArea().getBounds());
+ }
+
+ /**
+ * Asserts activity-level letterbox or size compat mode size compat mode, so activity max
+ * bounds are sandboxed.
+ */
+ private void assertActivityMaxBoundsSandboxed() {
+ // Activity max bounds are sandboxed due to size compat mode.
+ assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds())
+ .isEqualTo(mActivity.getWindowConfiguration().getBounds());
+ }
+
static Configuration rotateDisplay(DisplayContent display, int rotation) {
final Configuration c = new Configuration();
display.getDisplayRotation().setRotation(rotation);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index ecb8b607a106..dca6b089d66b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -26,6 +26,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
import static com.google.common.truth.Truth.assertThat;
@@ -277,4 +278,15 @@ public class TaskTests extends WindowTestsBase {
// Orientation request from standard activity in multi window will not be handled.
assertFalse(leafTask2.handlesOrientationChangeFromDescendant());
}
+
+ @Test
+ public void testAlwaysOnTop() {
+ final Task task = createTaskStackOnDisplay(mDisplayContent);
+ task.setAlwaysOnTop(true);
+ task.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ assertTrue(task.isAlwaysOnTop());
+
+ task.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, true /* set */);
+ assertFalse(task.isAlwaysOnTop());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index ae85ceb72958..cac69657f5cc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -136,6 +136,7 @@ class TestDisplayContent extends DisplayContent {
final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
mInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
final TestDisplayContent newDisplay = createInternal(display);
+
// disable the normal system decorations
final DisplayPolicy displayPolicy = newDisplay.getDisplayPolicy();
spyOn(displayPolicy);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 8d50a77447da..827ff6c18a68 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -176,6 +176,11 @@ class WindowTestsBase extends SystemServiceTestsBase {
} else {
mDisplayContent = mDefaultDisplay;
}
+
+ // Ensure letterbox aspect ratio is not overridden on any device target.
+ // {@link com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}, is set
+ // on some device form factors.
+ mAtm.mWindowManager.setFixedOrientationLetterboxAspectRatio(0);
}
private void createTestDisplay(UseTestDisplay annotation) {
@@ -704,6 +709,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
private int mLaunchMode;
private int mResizeMode = RESIZE_MODE_RESIZEABLE;
private float mMaxAspectRatio;
+ private boolean mSupportsSizeChanges;
private int mScreenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
private boolean mLaunchTaskBehind = false;
private int mConfigChanges;
@@ -782,6 +788,11 @@ class WindowTestsBase extends SystemServiceTestsBase {
return this;
}
+ ActivityBuilder setSupportsSizeChanges(boolean supportsSizeChanges) {
+ mSupportsSizeChanges = supportsSizeChanges;
+ return this;
+ }
+
ActivityBuilder setScreenOrientation(int screenOrientation) {
mScreenOrientation = screenOrientation;
return this;
@@ -869,6 +880,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
aInfo.launchMode = mLaunchMode;
aInfo.resizeMode = mResizeMode;
aInfo.maxAspectRatio = mMaxAspectRatio;
+ aInfo.supportsSizeChanges = mSupportsSizeChanges;
aInfo.screenOrientation = mScreenOrientation;
aInfo.configChanges |= mConfigChanges;
aInfo.taskAffinity = mAffinity;
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index c189b19c71af..97a06a81072e 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
@@ -1919,6 +1920,7 @@ public abstract class ConnectionService extends Service {
/** {@inheritDoc} */
@Override
public final IBinder onBind(Intent intent) {
+ onBindClient(intent);
return mBinder;
}
@@ -1929,6 +1931,13 @@ public abstract class ConnectionService extends Service {
return super.onUnbind(intent);
}
+ /**
+ * Used for testing to let the test suite know when the connection service has been bound.
+ * @hide
+ */
+ @TestApi
+ public void onBindClient(@Nullable Intent intent) {
+ }
/**
* This can be used by telecom to either create a new outgoing conference call or attach
diff --git a/telephony/java/android/telephony/CarrierBandwidth.java b/telephony/java/android/telephony/CarrierBandwidth.java
index b153fefce6e3..9e1dee0162b9 100644
--- a/telephony/java/android/telephony/CarrierBandwidth.java
+++ b/telephony/java/android/telephony/CarrierBandwidth.java
@@ -101,7 +101,7 @@ public final class CarrierBandwidth implements Parcelable {
}
/**
- * Retrieves the upstream bandwidth for the primary network in Kbps. This always only refers to
+ * Retrieves the upstream bandwidth for the primary network in kbps. This always only refers to
* the estimated first hop transport bandwidth.
* This will be {@link #INVALID} if the network is not connected
*
@@ -112,7 +112,7 @@ public final class CarrierBandwidth implements Parcelable {
}
/**
- * Retrieves the downstream bandwidth for the primary network in Kbps. This always only refers
+ * Retrieves the downstream bandwidth for the primary network in kbps. This always only refers
* to the estimated first hop transport bandwidth.
* This will be {@link #INVALID} if the network is not connected
*
@@ -123,7 +123,7 @@ public final class CarrierBandwidth implements Parcelable {
}
/**
- * Retrieves the upstream bandwidth for the secondary network in Kbps. This always only refers
+ * Retrieves the upstream bandwidth for the secondary network in kbps. This always only refers
* to the estimated first hop transport bandwidth.
* <p/>
* This will be {@link #INVALID} if either are the case:
@@ -143,7 +143,7 @@ public final class CarrierBandwidth implements Parcelable {
}
/**
- * Retrieves the downstream bandwidth for the secondary network in Kbps. This always only
+ * Retrieves the downstream bandwidth for the secondary network in kbps. This always only
* refers to the estimated first hop transport bandwidth.
* <p/>
* This will be {@link #INVALID} if either are the case:
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index b52f49190679..705e93f8883c 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -35,7 +35,6 @@ import android.telecom.TelecomManager;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.ImsSsData;
-import android.telephony.ims.SipDelegateManager;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.feature.RcsFeature;
@@ -1341,6 +1340,38 @@ public class CarrierConfigManager {
"support_ims_conference_event_package_on_peer_bool";
/**
+ * Indicates whether the carrier supports the use of RFC8285 compliant RTP header extensions for
+ * the purpose of device to device communication while in a call.
+ * <p>
+ * See also {@link #KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL}.
+ */
+ public static final String KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL =
+ "supports_device_to_device_communication_using_rtp_bool";
+
+ /**
+ * Indicates whether the carrier supports the negotiations of RFC8285 compliant RTP header
+ * extensions supported on a call during the Session Description Protocol (SDP). This option
+ * is only used when {@link #KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL} is
+ * {@code true}.
+ * <p>
+ * When {@code true}, the RTP header extensions the platform uses for device to device
+ * communication will be offered to the remote end during the SDP negotiation process.
+ * When {@code false}, the RTP header extensions will not be negotiated during the SDP
+ * negotiation process and the platform will send RTP header extensions without prior
+ * negotiation if {@link #KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL} is
+ * {@code true}.
+ */
+ public static final String KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL =
+ "supports_sdp_negotiation_of_d2d_rtp_header_extensions_bool";
+
+ /**
+ * Indicates whether the carrier supports the use of DTMF digits A-D for the purpose of device
+ * to device communication while in a call.
+ */
+ public static final String KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_DTMF_BOOL =
+ "supports_device_to_device_communication_using_dtmf_bool";
+
+ /**
* Determines whether High Definition audio property is displayed in the dialer UI.
* If {@code false}, remove the HD audio property from the connection so that HD audio related
* UI is not displayed. If {@code true}, keep HD audio property as it is configured.
@@ -1537,15 +1568,13 @@ public class CarrierConfigManager {
"wfc_carrier_name_override_by_pnn_bool";
/**
- * Value for {#CROSS_SIM_SPN_FORMAT_CARRIER_NAME_WITH_BRANDING} cnfig.
- * specifies SPN format of displaying carrier name only.
+ * Specifies SPN format of displaying carrier name only.
*
*/
public static final int CROSS_SIM_SPN_FORMAT_CARRIER_NAME_ONLY = 0;
/**
- * Value for {#CROSS_SIM_SPN_FORMAT_CARRIER_NAME_WITH_BRANDING} cnfig.
- * specifies SPN format of displaying carrier name along with "Cross-SIM calling".
+ * Specifies SPN format of displaying carrier name along with "Cross-SIM calling".
*/
public static final int CROSS_SIM_SPN_FORMAT_CARRIER_NAME_WITH_BRANDING = 1;
@@ -1554,8 +1583,8 @@ public class CarrierConfigManager {
*
* <p>Available options are:
* <ul>
- * <li> {#CROSS_SIM_SPN_FORMAT_CARRIER_NAME_ONLY}: %s</li>
- * <li> {#CROSS_SIM_SPN_FORMAT_CARRIER_NAME_WITH_BRANDING}: %s Cross-SIM Calling</li>
+ * <li> {@link #CROSS_SIM_SPN_FORMAT_CARRIER_NAME_ONLY}: %s</li>
+ * <li> {@link #CROSS_SIM_SPN_FORMAT_CARRIER_NAME_WITH_BRANDING}: %s Cross-SIM Calling</li>
* </ul>
* %s will be filled with carrier name
*/
@@ -5011,6 +5040,9 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_SUPPORT_MANAGE_IMS_CONFERENCE_CALL_BOOL, true);
sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL, true);
sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_ON_PEER_BOOL, true);
+ sDefaults.putBoolean(KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL, false);
+ sDefaults.putBoolean(KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL, false);
+ sDefaults.putBoolean(KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_DTMF_BOOL, false);
sDefaults.putBoolean(KEY_SUPPORT_VIDEO_CONFERENCE_CALL_BOOL, false);
sDefaults.putBoolean(KEY_IS_IMS_CONFERENCE_SIZE_ENFORCED_BOOL, false);
sDefaults.putInt(KEY_IMS_CONFERENCE_SIZE_LIMIT_INT, 5);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c48bd211fac2..3cb72b5e0c0d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -14618,12 +14618,11 @@ public class TelephonyManager {
* {@link #NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
* </ol>
* @return operation result.
- * <p>Requires Permission:
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
* @throws IllegalStateException if the Telephony process is not currently available.
* @hide
*/
@SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public @EnableNrDualConnectivityResult int setNrDualConnectivityState(
@NrDualConnectivityState int nrDualConnectivityState) {
try {
diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index ca1f861f9808..363e47a6d242 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -254,15 +254,15 @@ public class DataServiceCallback {
}
/**
- * The APN is throttled for the duration specified in
- * {@link DataCallResponse#getRetryDurationMillis}. Calling this method unthrottles that
- * APN.
+ * Unthrottles the APN on the current transport. There is no matching "APN throttle" method.
+ * Instead, the APN is throttled for the time specified in
+ * {@link DataCallResponse#getRetryDurationMillis}.
* <p/>
* see: {@link DataCallResponse#getRetryDurationMillis}
*
* @param apn Access Point Name defined by the carrier.
*/
- public void onApnUnthrottled(@NonNull String apn) {
+ public void onApnUnthrottled(final @NonNull String apn) {
if (mCallback != null) {
try {
if (DBG) Rlog.d(TAG, "onApnUnthrottled");
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 20e4b88ff13b..6985b360c9cc 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -17,25 +17,12 @@
package com.android.server.wm.flicker.rotation
import android.platform.test.annotations.Presubmit
-import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.endRotation
-import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.noUncoveredRegions
-import com.android.server.wm.flicker.startRotation
-import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
-import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -66,24 +53,6 @@ class ChangeAppRotationTest(
@Presubmit
@Test
- fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible()
-
- @Presubmit
- @Test
- fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible()
-
- @Presubmit
- @Test
- fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- testSpec.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
- @Presubmit
- @Test
- fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation,
- testSpec.config.endRotation, allStates = false)
-
- @Presubmit
- @Test
fun screenshotLayerBecomesInvisible() {
testSpec.assertLayers {
this.isVisible(testApp.getPackage())
@@ -94,49 +63,6 @@ class ChangeAppRotationTest(
}
}
- @FlakyTest(bugId = 140855415)
- @Test
- fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible()
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible()
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales(
- testSpec.config.startRotation, testSpec.config.endRotation)
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales(
- testSpec.config.startRotation, testSpec.config.endRotation)
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- testSpec.visibleLayersShownMoreThanOneConsecutiveEntry()
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun appLayerRotates_StartingPos() {
- testSpec.assertLayersStart {
- this.coversExactly(startingPos, testApp.getPackage())
- }
- }
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun appLayerRotates_EndingPos() {
- testSpec.assertLayersEnd {
- this.coversExactly(endingPos, testApp.getPackage())
- }
- }
-
- @FlakyTest(bugId = 151179149)
- @Test
- fun focusDoesNotChange() = testSpec.focusDoesNotChange()
-
companion object {
private const val SCREENSHOT_LAYER = "RotationLayer"
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
index c391112a53ec..9d78eb86539a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
@@ -17,17 +17,30 @@
package com.android.server.wm.flicker.rotation
import android.app.Instrumentation
+import android.platform.test.annotations.Presubmit
+import androidx.test.filters.FlakyTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.FlickerBuilderProvider
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.endRotation
+import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
import com.android.server.wm.flicker.repetitions
import com.android.server.wm.flicker.startRotation
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
+import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
+import org.junit.Test
abstract class RotationTransition(protected val testSpec: FlickerTestParameter) {
protected abstract val testApp: StandardAppHelper
@@ -63,4 +76,82 @@ abstract class RotationTransition(protected val testSpec: FlickerTestParameter)
transition(testSpec.config)
}
}
+
+ @Presubmit
+ @Test
+ open fun navBarWindowIsAlwaysVisible() {
+ testSpec.navBarWindowIsAlwaysVisible()
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun navBarLayerIsAlwaysVisible() {
+ testSpec.navBarLayerIsAlwaysVisible()
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun navBarLayerRotatesAndScales() {
+ testSpec.navBarLayerRotatesAndScales(
+ testSpec.config.startRotation, testSpec.config.endRotation)
+ }
+
+ @Presubmit
+ @Test
+ open fun statusBarWindowIsAlwaysVisible() {
+ testSpec.statusBarWindowIsAlwaysVisible()
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun statusBarLayerIsAlwaysVisible() {
+ testSpec.statusBarLayerIsAlwaysVisible()
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun statusBarLayerRotatesScales() {
+ testSpec.statusBarLayerRotatesScales(
+ testSpec.config.startRotation, testSpec.config.endRotation)
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun visibleLayersShownMoreThanOneConsecutiveEntry() =
+ testSpec.visibleLayersShownMoreThanOneConsecutiveEntry()
+
+ @Presubmit
+ @Test
+ open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
+ testSpec.visibleWindowsShownMoreThanOneConsecutiveEntry()
+ }
+
+ @Presubmit
+ @Test
+ open fun noUncoveredRegions() {
+ testSpec.noUncoveredRegions(testSpec.config.startRotation,
+ testSpec.config.endRotation, allStates = false)
+ }
+
+ @FlakyTest(bugId = 151179149)
+ @Test
+ open fun focusDoesNotChange() {
+ testSpec.focusDoesNotChange()
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun appLayerRotates_StartingPos() {
+ testSpec.assertLayersStart {
+ this.coversExactly(startingPos, testApp.getPackage())
+ }
+ }
+
+ @FlakyTest(bugId = 140855415)
+ @Test
+ open fun appLayerRotates_EndingPos() {
+ testSpec.assertLayersEnd {
+ this.coversExactly(endingPos, testApp.getPackage())
+ }
+ }
} \ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index fc5bcc7eef1b..45d3006b9481 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -24,21 +24,9 @@ import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.appWindowAlwaysVisibleOnTop
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.endRotation
-import com.android.server.wm.flicker.focusDoesNotChange
import com.android.server.wm.flicker.helpers.SeamlessRotationAppHelper
import com.android.server.wm.flicker.layerAlwaysVisible
-import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
-import com.android.server.wm.flicker.noUncoveredRegions
-import com.android.server.wm.flicker.startRotation
-import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.flicker.visibleLayersShownMoreThanOneConsecutiveEntry
-import com.android.server.wm.flicker.visibleWindowsShownMoreThanOneConsecutiveEntry
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -71,54 +59,25 @@ class SeamlessAppRotationTest(
}
}
- @Presubmit
- @Test
- fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
- testSpec.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
- @Presubmit
- @Test
- fun appWindowAlwaysVisibleOnTop() = testSpec.appWindowAlwaysVisibleOnTop(testApp.`package`)
-
- @Presubmit
- @Test
- fun layerAlwaysVisible() = testSpec.layerAlwaysVisible(testApp.`package`)
-
@FlakyTest(bugId = 140855415)
@Test
- fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible()
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
@FlakyTest(bugId = 140855415)
@Test
- fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible()
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible()
-
- @FlakyTest(bugId = 140855415)
- @Test
- fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible()
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
@FlakyTest(bugId = 147659548)
@Test
- fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation,
- testSpec.config.endRotation, allStates = false)
-
- @FlakyTest
- @Test
- fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales(
- testSpec.config.startRotation, testSpec.config.endRotation)
+ override fun noUncoveredRegions() = super.noUncoveredRegions()
- @FlakyTest
+ @Presubmit
@Test
- fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales(
- testSpec.config.startRotation, testSpec.config.endRotation)
+ fun appWindowAlwaysVisibleOnTop() = testSpec.appWindowAlwaysVisibleOnTop(testApp.`package`)
- @FlakyTest
+ @Presubmit
@Test
- fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- testSpec.visibleLayersShownMoreThanOneConsecutiveEntry()
+ fun layerAlwaysVisible() = testSpec.layerAlwaysVisible(testApp.`package`)
@FlakyTest(bugId = 147659548)
@Test
@@ -128,10 +87,6 @@ class SeamlessAppRotationTest(
}
}
- @FlakyTest(bugId = 151179149)
- @Test
- fun focusDoesNotChange() = testSpec.focusDoesNotChange()
-
companion object {
private val testFactory = FlickerTestParameterFactory.getInstance()
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index 81224957b2c7..7f0318a135dc 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -70,7 +70,7 @@ android_test {
"mockito-target-minus-junit4",
"net-tests-utils",
"platform-test-annotations",
- "service-connectivity",
+ "service-connectivity-pre-jarjar",
"services.core",
"services.net",
],
diff --git a/tests/net/TEST_MAPPING b/tests/net/TEST_MAPPING
index 89fc6ea2c47b..d659688700d3 100644
--- a/tests/net/TEST_MAPPING
+++ b/tests/net/TEST_MAPPING
@@ -9,6 +9,23 @@
"name": "FrameworksNetDeflakeTest"
}
],
+ "auto-postsubmit": [
+ // Test tag for automotive targets. These are only running in postsubmit so as to harden the
+ // automotive targets to avoid introducing additional test flake and build time. The plan for
+ // presubmit testing for auto is to augment the existing tests to cover auto use cases as well.
+ // Additionally, this tag is used in targeted test suites to limit resource usage on the test
+ // infra during the hardening phase.
+ // TODO: this tag to be removed once the above is no longer an issue.
+ {
+ "name": "FrameworksNetTests"
+ },
+ {
+ "name": "FrameworksNetIntegrationTests"
+ },
+ {
+ "name": "FrameworksNetDeflakeTest"
+ }
+ ],
"imports": [
{
"path": "cts/tests/tests/net"
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 5d0e016d50fa..e84b992a1379 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -68,6 +68,7 @@ import android.util.ArraySet;
import androidx.test.runner.AndroidJUnit4;
import com.android.modules.utils.build.SdkLevel;
+import com.android.testutils.CompatUtil;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -211,7 +212,7 @@ public class NetworkCapabilitiesTest {
nc1 = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI);
nc2 = new NetworkCapabilities()
.addTransportType(TRANSPORT_WIFI)
- .setNetworkSpecifier(new StringNetworkSpecifier("specs"));
+ .setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier("eth42"));
assertNotEquals("", nc1.describeImmutableDifferences(nc2));
assertEquals("", nc1.describeImmutableDifferences(nc1));
}
@@ -671,7 +672,7 @@ public class NetworkCapabilitiesTest {
NetworkCapabilities nc1 = new NetworkCapabilities();
nc1.addTransportType(TRANSPORT_CELLULAR).addTransportType(TRANSPORT_WIFI);
try {
- nc1.setNetworkSpecifier(new StringNetworkSpecifier("specs"));
+ nc1.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier("eth0"));
fail("Cannot set NetworkSpecifier on a NetworkCapability with multiple transports!");
} catch (IllegalStateException expected) {
// empty
@@ -680,7 +681,7 @@ public class NetworkCapabilitiesTest {
// Sequence 2: Transport + NetworkSpecifier + Transport
NetworkCapabilities nc2 = new NetworkCapabilities();
nc2.addTransportType(TRANSPORT_CELLULAR).setNetworkSpecifier(
- new StringNetworkSpecifier("specs"));
+ CompatUtil.makeEthernetNetworkSpecifier("testtap3"));
try {
nc2.addTransportType(TRANSPORT_WIFI);
fail("Cannot set a second TransportType of a network which has a NetworkSpecifier!");
diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt
index bcc907285e35..340e6f963137 100644
--- a/tests/net/common/java/android/net/NetworkProviderTest.kt
+++ b/tests/net/common/java/android/net/NetworkProviderTest.kt
@@ -27,6 +27,7 @@ import android.os.HandlerThread
import android.os.Looper
import androidx.test.InstrumentationRegistry
import com.android.net.module.util.ArrayTrackRecord
+import com.android.testutils.CompatUtil
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
import com.android.testutils.isDevSdkInRange
@@ -102,7 +103,8 @@ class NetworkProviderTest {
mCm.registerNetworkProvider(provider)
assertNotEquals(provider.getProviderId(), NetworkProvider.ID_NONE)
- val specifier = StringNetworkSpecifier(UUID.randomUUID().toString())
+ val specifier = CompatUtil.makeTestNetworkSpecifier(
+ UUID.randomUUID().toString())
val nr: NetworkRequest = NetworkRequest.Builder()
.addTransportType(TRANSPORT_TEST)
.setNetworkSpecifier(specifier)
@@ -183,7 +185,8 @@ class NetworkProviderTest {
mCm.registerNetworkProvider(provider)
- val specifier = StringNetworkSpecifier(UUID.randomUUID().toString())
+ val specifier = CompatUtil.makeTestNetworkSpecifier(
+ UUID.randomUUID().toString())
val nr: NetworkRequest = NetworkRequest.Builder()
.addTransportType(TRANSPORT_TEST)
.setNetworkSpecifier(specifier)
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index e1da3d0ae2b3..01d8186c7d1b 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -64,6 +64,7 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
private final HandlerThread mHandlerThread;
private final Context mContext;
private final String mLogTag;
+ private final NetworkAgentConfig mNetworkAgentConfig;
private final ConditionVariable mDisconnected = new ConditionVariable();
private final ConditionVariable mPreventReconnectReceived = new ConditionVariable();
@@ -115,13 +116,19 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
mHandlerThread = new HandlerThread(mLogTag);
mHandlerThread.start();
- mNetworkAgent = makeNetworkAgent(linkProperties, type, typeName);
+ // extraInfo is set to "" by default in NetworkAgentConfig.
+ final String extraInfo = (transport == TRANSPORT_CELLULAR) ? "internet.apn" : "";
+ mNetworkAgentConfig = new NetworkAgentConfig.Builder()
+ .setLegacyType(type)
+ .setLegacyTypeName(typeName)
+ .setLegacyExtraInfo(extraInfo)
+ .build();
+ mNetworkAgent = makeNetworkAgent(linkProperties, mNetworkAgentConfig);
}
protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties,
- final int type, final String typeName)
- throws Exception {
- return new InstrumentedNetworkAgent(this, linkProperties, type, typeName);
+ final NetworkAgentConfig nac) throws Exception {
+ return new InstrumentedNetworkAgent(this, linkProperties, nac);
}
public static class InstrumentedNetworkAgent extends NetworkAgent {
@@ -129,11 +136,9 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
private static final String PROVIDER_NAME = "InstrumentedNetworkAgentProvider";
public InstrumentedNetworkAgent(NetworkAgentWrapper wrapper, LinkProperties lp,
- final int type, final String typeName) {
+ NetworkAgentConfig nac) {
super(wrapper.mContext, wrapper.mHandlerThread.getLooper(), wrapper.mLogTag,
- wrapper.mNetworkCapabilities, lp, wrapper.mScore,
- new NetworkAgentConfig.Builder()
- .setLegacyType(type).setLegacyTypeName(typeName).build(),
+ wrapper.mNetworkCapabilities, lp, wrapper.mScore, nac,
new NetworkProvider(wrapper.mContext, wrapper.mHandlerThread.getLooper(),
PROVIDER_NAME));
mWrapper = wrapper;
@@ -301,6 +306,14 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
return mNetworkCapabilities;
}
+ public int getLegacyType() {
+ return mNetworkAgentConfig.getLegacyType();
+ }
+
+ public String getExtraInfo() {
+ return mNetworkAgentConfig.getLegacyExtraInfo();
+ }
+
public @NonNull ArrayTrackRecord<CallbackType>.ReadHead getCallbackHistory() {
return mCallbackHistory;
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index cc1ac61c2ab9..3102b9917fe7 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -72,6 +72,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
@@ -265,7 +266,6 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.app.IBatteryStats;
import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnProfile;
import com.android.internal.util.ArrayUtils;
@@ -427,7 +427,6 @@ public class ConnectivityServiceTest {
@Mock DeviceIdleInternal mDeviceIdleInternal;
@Mock INetworkManagementService mNetworkManagementService;
@Mock NetworkStatsManager mStatsManager;
- @Mock IBatteryStats mBatteryStatsService;
@Mock IDnsResolver mMockDnsResolver;
@Mock INetd mMockNetd;
@Mock NetworkStackClient mNetworkStack;
@@ -719,7 +718,7 @@ public class ConnectivityServiceTest {
@Override
protected InstrumentedNetworkAgent makeNetworkAgent(LinkProperties linkProperties,
- final int type, final String typeName) throws Exception {
+ NetworkAgentConfig nac) throws Exception {
mNetworkMonitor = mock(INetworkMonitor.class);
final Answer validateAnswer = inv -> {
@@ -738,8 +737,8 @@ public class ConnectivityServiceTest {
any() /* name */,
nmCbCaptor.capture());
- final InstrumentedNetworkAgent na = new InstrumentedNetworkAgent(this, linkProperties,
- type, typeName) {
+ final InstrumentedNetworkAgent na =
+ new InstrumentedNetworkAgent(this, linkProperties, nac) {
@Override
public void networkStatus(int status, String redirectUrl) {
mRedirectUrl = redirectUrl;
@@ -1526,12 +1525,12 @@ public class ConnectivityServiceTest {
doReturn(mSystemProperties).when(deps).getSystemProperties();
doReturn(mock(ProxyTracker.class)).when(deps).makeProxyTracker(any(), any());
doReturn(true).when(deps).queryUserAccess(anyInt(), anyInt());
- doReturn(mBatteryStatsService).when(deps).getBatteryStatsService();
doAnswer(inv -> {
mPolicyTracker = new WrappedMultinetworkPolicyTracker(
inv.getArgument(0), inv.getArgument(1), inv.getArgument(2));
return mPolicyTracker;
}).when(deps).makeMultinetworkPolicyTracker(any(), any(), any());
+ doReturn(true).when(deps).getCellular464XlatEnabled();
return deps;
}
@@ -1742,11 +1741,29 @@ public class ConnectivityServiceTest {
return expected;
}
+ private boolean extraInfoInBroadcastHasExpectedNullness(NetworkInfo ni) {
+ final DetailedState state = ni.getDetailedState();
+ if (state == DetailedState.CONNECTED && ni.getExtraInfo() == null) return false;
+ // Expect a null extraInfo if the network is CONNECTING, because a CONNECTIVITY_ACTION
+ // broadcast with a state of CONNECTING only happens due to legacy VPN lockdown, which also
+ // nulls out extraInfo.
+ if (state == DetailedState.CONNECTING && ni.getExtraInfo() != null) return false;
+ // Can't make any assertions about DISCONNECTED broadcasts. When a network actually
+ // disconnects, disconnectAndDestroyNetwork sets its state to DISCONNECTED and its extraInfo
+ // to null. But if the DISCONNECTED broadcast is just simulated by LegacyTypeTracker due to
+ // a network switch, extraInfo will likely be populated.
+ // This is likely a bug in CS, but likely not one we can fix without impacting apps.
+ return true;
+ }
+
private ExpectedBroadcast expectConnectivityAction(int type, NetworkInfo.DetailedState state) {
- return registerConnectivityBroadcastThat(1, intent ->
- type == intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) && state.equals(
- ((NetworkInfo) intent.getParcelableExtra(EXTRA_NETWORK_INFO))
- .getDetailedState()));
+ return registerConnectivityBroadcastThat(1, intent -> {
+ final int actualType = intent.getIntExtra(EXTRA_NETWORK_TYPE, -1);
+ final NetworkInfo ni = intent.getParcelableExtra(EXTRA_NETWORK_INFO);
+ return type == actualType
+ && state == ni.getDetailedState()
+ && extraInfoInBroadcastHasExpectedNullness(ni);
+ });
}
@Test
@@ -5574,7 +5591,7 @@ public class ConnectivityServiceTest {
reset(mStatsManager);
// Temp metered change shouldn't update ifaces
- mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
waitForIdle();
verify(mStatsManager, never()).notifyNetworkStatus(eq(Arrays.asList(onlyCell)),
any(List.class), eq(MOBILE_IFNAME), any(List.class));
@@ -7184,12 +7201,14 @@ public class ConnectivityServiceTest {
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
setUidRulesChanged(RULE_REJECT_ALL);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mCellNetworkAgent);
// ConnectivityService should cache it not to invoke the callback again.
setUidRulesChanged(RULE_REJECT_METERED);
@@ -7200,12 +7219,14 @@ public class ConnectivityServiceTest {
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
setUidRulesChanged(RULE_REJECT_METERED);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mCellNetworkAgent);
// Restrict the network based on UID rule and NOT_METERED capability change.
mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
@@ -7214,6 +7235,7 @@ public class ConnectivityServiceTest {
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
@@ -7222,12 +7244,14 @@ public class ConnectivityServiceTest {
assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mCellNetworkAgent);
setUidRulesChanged(RULE_ALLOW_METERED);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
setUidRulesChanged(RULE_NONE);
cellNetworkCallback.assertNoCallback();
@@ -7238,6 +7262,7 @@ public class ConnectivityServiceTest {
assertNull(mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mCellNetworkAgent);
setRestrictBackgroundChanged(true);
cellNetworkCallback.assertNoCallback();
@@ -7245,12 +7270,14 @@ public class ConnectivityServiceTest {
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
setRestrictBackgroundChanged(false);
cellNetworkCallback.assertNoCallback();
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
mCm.unregisterNetworkCallback(cellNetworkCallback);
}
@@ -7309,6 +7336,15 @@ public class ConnectivityServiceTest {
assertNotNull(ni);
assertEquals(type, ni.getType());
assertEquals(ConnectivityManager.getNetworkTypeName(type), state, ni.getDetailedState());
+ if (state == DetailedState.CONNECTED || state == DetailedState.SUSPENDED) {
+ assertNotNull(ni.getExtraInfo());
+ } else {
+ // Technically speaking, a network that's in CONNECTING state will generally have a
+ // non-null extraInfo. This doesn't actually happen in this test because it never calls
+ // a legacy API while a network is connecting. When a network is in CONNECTING state
+ // because of legacy lockdown VPN, its extraInfo is always null.
+ assertNull(ni.getExtraInfo());
+ }
}
private void assertActiveNetworkInfo(int type, DetailedState state) {
@@ -7318,6 +7354,26 @@ public class ConnectivityServiceTest {
checkNetworkInfo(mCm.getNetworkInfo(type), type, state);
}
+ private void assertExtraInfoFromCm(TestNetworkAgentWrapper network, boolean present) {
+ final NetworkInfo niForNetwork = mCm.getNetworkInfo(network.getNetwork());
+ final NetworkInfo niForType = mCm.getNetworkInfo(network.getLegacyType());
+ if (present) {
+ assertEquals(network.getExtraInfo(), niForNetwork.getExtraInfo());
+ assertEquals(network.getExtraInfo(), niForType.getExtraInfo());
+ } else {
+ assertNull(niForNetwork.getExtraInfo());
+ assertNull(niForType.getExtraInfo());
+ }
+ }
+
+ private void assertExtraInfoFromCmBlocked(TestNetworkAgentWrapper network) {
+ assertExtraInfoFromCm(network, false);
+ }
+
+ private void assertExtraInfoFromCmPresent(TestNetworkAgentWrapper network) {
+ assertExtraInfoFromCm(network, true);
+ }
+
// Checks that each of the |agents| receive a blocked status change callback with the specified
// |blocked| value, in any order. This is needed because when an event affects multiple
// networks, ConnectivityService does not guarantee the order in which callbacks are fired.
@@ -7632,6 +7688,7 @@ public class ConnectivityServiceTest {
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mCellNetworkAgent);
// TODO: it would be nice if we could simply rely on the production code here, and have
// LockdownVpnTracker start the VPN, have the VPN code register its NetworkAgent with
@@ -7660,6 +7717,7 @@ public class ConnectivityServiceTest {
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_WIFI, DetailedState.DISCONNECTED);
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mCellNetworkAgent);
assertTrue(vpnNc.hasTransport(TRANSPORT_VPN));
assertTrue(vpnNc.hasTransport(TRANSPORT_CELLULAR));
assertFalse(vpnNc.hasTransport(TRANSPORT_WIFI));
@@ -7702,6 +7760,7 @@ public class ConnectivityServiceTest {
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_WIFI, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_VPN, DetailedState.BLOCKED);
+ assertExtraInfoFromCmBlocked(mWiFiNetworkAgent);
// The VPN comes up again on wifi.
b1 = expectConnectivityAction(TYPE_VPN, DetailedState.CONNECTED);
@@ -7716,6 +7775,7 @@ public class ConnectivityServiceTest {
assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mWiFiNetworkAgent);
vpnNc = mCm.getNetworkCapabilities(mMockVpn.getNetwork());
assertTrue(vpnNc.hasTransport(TRANSPORT_VPN));
assertTrue(vpnNc.hasTransport(TRANSPORT_WIFI));
@@ -7732,6 +7792,7 @@ public class ConnectivityServiceTest {
assertNetworkInfo(TYPE_MOBILE, DetailedState.DISCONNECTED);
assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_VPN, DetailedState.CONNECTED);
+ assertExtraInfoFromCmPresent(mWiFiNetworkAgent);
b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED);
mWiFiNetworkAgent.disconnect();
@@ -7811,7 +7872,6 @@ public class ConnectivityServiceTest {
verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
cellLp.getInterfaceName(),
new int[] { TRANSPORT_CELLULAR });
- reset(mBatteryStatsService);
final LinkProperties wifiLp = new LinkProperties();
wifiLp.setInterfaceName("wifi0");
@@ -7821,7 +7881,6 @@ public class ConnectivityServiceTest {
verify(mDeps).reportNetworkInterfaceForTransports(mServiceContext,
wifiLp.getInterfaceName(),
new int[] { TRANSPORT_WIFI });
- reset(mBatteryStatsService);
mCellNetworkAgent.disconnect();
mWiFiNetworkAgent.disconnect();
@@ -7904,7 +7963,6 @@ public class ConnectivityServiceTest {
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
reset(mMockDnsResolver);
reset(mMockNetd);
- reset(mBatteryStatsService);
// Connect with ipv6 link properties. Expect prefix discovery to be started.
mCellNetworkAgent.connect(true);
@@ -8267,6 +8325,45 @@ public class ConnectivityServiceTest {
}
@Test
+ public void testWith464XlatDisable() throws Exception {
+ doReturn(false).when(mDeps).getCellular464XlatEnabled();
+
+ final TestNetworkCallback callback = new TestNetworkCallback();
+ final TestNetworkCallback defaultCallback = new TestNetworkCallback();
+ final NetworkRequest networkRequest = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .build();
+ mCm.registerNetworkCallback(networkRequest, callback);
+ mCm.registerDefaultNetworkCallback(defaultCallback);
+
+ // Bring up validated cell.
+ final LinkProperties cellLp = new LinkProperties();
+ cellLp.setInterfaceName(MOBILE_IFNAME);
+ cellLp.addLinkAddress(new LinkAddress("2001:db8:1::1/64"));
+ cellLp.addRoute(new RouteInfo(new IpPrefix("::/0"), null, MOBILE_IFNAME));
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+
+ mCellNetworkAgent.sendLinkProperties(cellLp);
+ mCellNetworkAgent.connect(true);
+ callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ final int cellNetId = mCellNetworkAgent.getNetwork().netId;
+ waitForIdle();
+
+ verify(mMockDnsResolver, never()).startPrefix64Discovery(cellNetId);
+ Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent);
+ assertTrue("Nat464Xlat was not IDLE", !clat.isStarted());
+
+ // This cannot happen because prefix discovery cannot succeed if it is never started.
+ mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
+ makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, "64:ff9b::", 96));
+
+ // ... but still, check that even if it did, clatd would not be started.
+ verify(mMockNetd, never()).clatdStart(anyString(), anyString());
+ assertTrue("Nat464Xlat was not IDLE", !clat.isStarted());
+ }
+
+ @Test
public void testDataActivityTracking() throws Exception {
final TestNetworkCallback networkCallback = new TestNetworkCallback();
final NetworkRequest networkRequest = new NetworkRequest.Builder()
@@ -8972,7 +9069,7 @@ public class ConnectivityServiceTest {
TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE));
return new NetworkAgentInfo(null, new Network(NET_ID), info, new LinkProperties(),
nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0,
- INVALID_UID, mQosCallbackTracker);
+ INVALID_UID, mQosCallbackTracker, new ConnectivityService.Dependencies());
}
@Test
@@ -10652,7 +10749,7 @@ public class ConnectivityServiceTest {
null,
null);
- // default NCs will be unregistered in tearDown
+ // default callbacks will be unregistered in tearDown
}
/**
@@ -10709,7 +10806,7 @@ public class ConnectivityServiceTest {
null,
mService.mNoServiceNetwork.network());
- // default NCs will be unregistered in tearDown
+ // default callbacks will be unregistered in tearDown
}
/**
@@ -10768,7 +10865,7 @@ public class ConnectivityServiceTest {
null,
mService.mNoServiceNetwork.network());
- // default NCs will be unregistered in tearDown
+ // default callbacks will be unregistered in tearDown
}
/**
@@ -10827,7 +10924,28 @@ public class ConnectivityServiceTest {
null,
mService.mNoServiceNetwork.network());
- // default NCs will be unregistered in tearDown
+ // default callbacks will be unregistered in tearDown
+ }
+
+ @Test
+ public void testCapabilityWithOemNetworkPreference() throws Exception {
+ @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+ OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+ setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref);
+ registerDefaultNetworkCallbacks();
+
+ setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+
+ mSystemDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
+ mSystemDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc ->
+ nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+ mDefaultNetworkCallback.expectCapabilitiesThat(mCellNetworkAgent, nc ->
+ nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
+
+ // default callbacks will be unregistered in tearDown
}
@Test
@@ -10908,4 +11026,4 @@ public class ConnectivityServiceTest {
verifyNoNetwork();
mCm.unregisterNetworkCallback(cellCb);
}
-}
+} \ No newline at end of file
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index a913673c2a1e..1c0ba4f8d8f5 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -357,7 +357,7 @@ public class LingerMonitorTest {
NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info,
new LinkProperties(), caps, 50, mCtx, null, new NetworkAgentConfig() /* config */,
mConnService, mNetd, mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(),
- mQosCallbackTracker);
+ mQosCallbackTracker, new ConnectivityService.Dependencies());
nai.everValidated = true;
return nai;
}
diff --git a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
index 950d7163c78a..38f6d7f3172d 100644
--- a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
+++ b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
@@ -46,12 +46,12 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.EthernetNetworkSpecifier;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
import android.net.NetworkTemplate;
-import android.net.StringNetworkSpecifier;
import android.net.TelephonyNetworkSpecifier;
import android.os.Handler;
import android.os.UserHandle;
@@ -240,7 +240,7 @@ public class MultipathPolicyTrackerTest {
NetworkCapabilities capabilities = new NetworkCapabilities()
.addCapability(NET_CAPABILITY_INTERNET)
.addTransportType(TRANSPORT_CELLULAR)
- .setNetworkSpecifier(new StringNetworkSpecifier("234"));
+ .setNetworkSpecifier(new EthernetNetworkSpecifier("eth234"));
if (!roaming) {
capabilities.addCapability(NET_CAPABILITY_NOT_ROAMING);
}
diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
index 5f56e25356c2..9b2a638f8b39 100644
--- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
+++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
@@ -16,11 +16,15 @@
package com.android.server.connectivity;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -34,6 +38,7 @@ import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkAgentConfig;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.test.TestLooper;
@@ -72,11 +77,15 @@ public class Nat464XlatTest {
Handler mHandler;
NetworkAgentConfig mAgentConfig = new NetworkAgentConfig();
- Nat464Xlat makeNat464Xlat() {
- return new Nat464Xlat(mNai, mNetd, mDnsResolver) {
+ Nat464Xlat makeNat464Xlat(boolean isCellular464XlatEnabled) {
+ return new Nat464Xlat(mNai, mNetd, mDnsResolver, new ConnectivityService.Dependencies()) {
@Override protected int getNetId() {
return NETID;
}
+
+ @Override protected boolean isCellular464XlatEnabled() {
+ return isCellular464XlatEnabled;
+ }
};
}
@@ -99,6 +108,7 @@ public class Nat464XlatTest {
mNai.linkProperties.setInterfaceName(BASE_IFACE);
mNai.networkInfo = new NetworkInfo(null);
mNai.networkInfo.setType(ConnectivityManager.TYPE_WIFI);
+ mNai.networkCapabilities = new NetworkCapabilities();
markNetworkConnected();
when(mNai.connService()).thenReturn(mConnectivity);
when(mNai.netAgentConfig()).thenReturn(mAgentConfig);
@@ -110,21 +120,23 @@ public class Nat464XlatTest {
}
private void assertRequiresClat(boolean expected, NetworkAgentInfo nai) {
+ Nat464Xlat nat = makeNat464Xlat(true);
String msg = String.format("requiresClat expected %b for type=%d state=%s skip=%b "
+ "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(),
nai.networkInfo.getDetailedState(),
mAgentConfig.skip464xlat, nai.linkProperties.getNat64Prefix(),
nai.linkProperties.getLinkAddresses());
- assertEquals(msg, expected, Nat464Xlat.requiresClat(nai));
+ assertEquals(msg, expected, nat.requiresClat(nai));
}
private void assertShouldStartClat(boolean expected, NetworkAgentInfo nai) {
+ Nat464Xlat nat = makeNat464Xlat(true);
String msg = String.format("shouldStartClat expected %b for type=%d state=%s skip=%b "
+ "nat64Prefix=%s addresses=%s", expected, nai.networkInfo.getType(),
nai.networkInfo.getDetailedState(),
mAgentConfig.skip464xlat, nai.linkProperties.getNat64Prefix(),
nai.linkProperties.getLinkAddresses());
- assertEquals(msg, expected, Nat464Xlat.shouldStartClat(nai));
+ assertEquals(msg, expected, nat.shouldStartClat(nai));
}
@Test
@@ -194,7 +206,7 @@ public class Nat464XlatTest {
}
private void checkNormalStartAndStop(boolean dueToDisconnect) throws Exception {
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
mNai.linkProperties.addLinkAddress(V6ADDR);
@@ -245,7 +257,7 @@ public class Nat464XlatTest {
}
private void checkStartStopStart(boolean interfaceRemovedFirst) throws Exception {
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
InOrder inOrder = inOrder(mNetd, mConnectivity);
@@ -335,7 +347,7 @@ public class Nat464XlatTest {
@Test
public void testClatdCrashWhileRunning() throws Exception {
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
ArgumentCaptor<LinkProperties> c = ArgumentCaptor.forClass(LinkProperties.class);
nat.setNat64PrefixFromDns(new IpPrefix(NAT64_PREFIX));
@@ -372,7 +384,7 @@ public class Nat464XlatTest {
}
private void checkStopBeforeClatdStarts(boolean dueToDisconnect) throws Exception {
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64"));
@@ -414,7 +426,7 @@ public class Nat464XlatTest {
}
private void checkStopAndClatdNeverStarts(boolean dueToDisconnect) throws Exception {
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
mNai.linkProperties.addLinkAddress(new LinkAddress("2001:db8::1/64"));
@@ -450,7 +462,7 @@ public class Nat464XlatTest {
final IpPrefix prefixFromDns = new IpPrefix(NAT64_PREFIX);
final IpPrefix prefixFromRa = new IpPrefix(OTHER_NAT64_PREFIX);
- Nat464Xlat nat = makeNat464Xlat();
+ Nat464Xlat nat = makeNat464Xlat(true);
final LinkProperties emptyLp = new LinkProperties();
LinkProperties fixedupLp;
@@ -486,10 +498,57 @@ public class Nat464XlatTest {
assertEquals(null, fixedupLp.getNat64Prefix());
}
+ private void checkClatDisabledOnCellular(boolean onCellular) throws Exception {
+ // Disable 464xlat on cellular networks.
+ Nat464Xlat nat = makeNat464Xlat(false);
+ mNai.linkProperties.addLinkAddress(V6ADDR);
+ mNai.networkCapabilities.setTransportType(TRANSPORT_CELLULAR, onCellular);
+ nat.update();
+
+ final IpPrefix nat64Prefix = new IpPrefix(NAT64_PREFIX);
+ if (onCellular) {
+ // Prefix discovery is never started.
+ verify(mDnsResolver, never()).startPrefix64Discovery(eq(NETID));
+ assertIdle(nat);
+
+ // If a NAT64 prefix comes in from an RA, clat is not started either.
+ mNai.linkProperties.setNat64Prefix(nat64Prefix);
+ nat.setNat64PrefixFromRa(nat64Prefix);
+ nat.update();
+ verify(mNetd, never()).clatdStart(anyString(), anyString());
+ assertIdle(nat);
+ } else {
+ // Prefix discovery is started.
+ verify(mDnsResolver).startPrefix64Discovery(eq(NETID));
+ assertIdle(nat);
+
+ // If a NAT64 prefix comes in from an RA, clat is started.
+ mNai.linkProperties.setNat64Prefix(nat64Prefix);
+ nat.setNat64PrefixFromRa(nat64Prefix);
+ nat.update();
+ verify(mNetd).clatdStart(BASE_IFACE, NAT64_PREFIX);
+ assertStarting(nat);
+ }
+ }
+
+ @Test
+ public void testClatDisabledOnCellular() throws Exception {
+ checkClatDisabledOnCellular(true);
+ }
+
+ @Test
+ public void testClatDisabledOnNonCellular() throws Exception {
+ checkClatDisabledOnCellular(false);
+ }
+
static void assertIdle(Nat464Xlat nat) {
assertTrue("Nat464Xlat was not IDLE", !nat.isStarted());
}
+ static void assertStarting(Nat464Xlat nat) {
+ assertTrue("Nat464Xlat was not STARTING", nat.isStarting());
+ }
+
static void assertRunning(Nat464Xlat nat) {
assertTrue("Nat464Xlat was not RUNNING", nat.isRunning());
}
diff --git a/tests/vcn/assets/client-end-cert.pem b/tests/vcn/assets/client-end-cert.pem
new file mode 100644
index 000000000000..e82da85c50ab
--- /dev/null
+++ b/tests/vcn/assets/client-end-cert.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDaDCCAlCgAwIBAgIIcorRI3n29E4wDQYJKoZIhvcNAQELBQAwQTELMAkGA1UE
+BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3R3by5jYS50ZXN0LmFu
+ZHJvaWQubmV0MB4XDTIwMDQxNDA1MDM0OVoXDTIzMDQxNDA1MDM0OVowRTELMAkG
+A1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxJDAiBgNVBAMTG2NsaWVudC50ZXN0
+LmlrZS5hbmRyb2lkLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AK/cK+sIaiQlJYvy5+Dq70sJbgR7PO1uS2qkLRP7Wb3z5SNvz94nQvZRrFn1AFIE
+CpfESh5kUF6gJe7t7NR3mpQ98iEosCRBMDJT8qB+EeHiL4wkrmCE9sYMTyvaApRc
+6Qzozn/9kKma7Qpj/25AvoPluTERqhZ6AQ77BJeb6FNOAoO1Aoe9GJuB1xmRxjRw
+D0mwusL+ciQ/7uKlsFP5VO5XqACcohXSerzO8jcD9necBvka3SDepqqzn1K0NPRC
+25fMmS5kSjddKtKOif7w2NI3OpVsmP3kHv66If73VURsy0lgXPYyKkq8lAMrtmXG
+R7svFGPbEl+Swkpr3b+dzF8CAwEAAaNgMF4wHwYDVR0jBBgwFoAUcqSu1uRYT/DL
+bLoDNUz38nGvCKQwJgYDVR0RBB8wHYIbY2xpZW50LnRlc3QuaWtlLmFuZHJvaWQu
+bmV0MBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQCa53tK
+I9RM9/MutZ5KNG2Gfs2cqaPyv8ZRhs90HDWZhkFVu7prywJAxOd2hxxHPsvgurio
+4bKAxnT4EXevgz5YoCbj2TPIL9TdFYh59zZ97XXMxk+SRdypgF70M6ETqKPs3hDP
+ZRMMoHvvYaqaPvp4StSBX9A44gSyjHxVYJkrjDZ0uffKg5lFL5IPvqfdmSRSpGab
+SyGTP4OLTy0QiNV3pBsJGdl0h5BzuTPR9OTl4xgeqqBQy2bDjmfJBuiYyCSCkPi7
+T3ohDYCymhuSkuktHPNG1aKllUJaw0tuZuNydlgdAveXPYfM36uvK0sfd9qr9pAy
+rmkYV2MAWguFeckh
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/tests/vcn/assets/client-private-key.key b/tests/vcn/assets/client-private-key.key
new file mode 100644
index 000000000000..22736e98e030
--- /dev/null
+++ b/tests/vcn/assets/client-private-key.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCv3CvrCGokJSWL
+8ufg6u9LCW4EezztbktqpC0T+1m98+Ujb8/eJ0L2UaxZ9QBSBAqXxEoeZFBeoCXu
+7ezUd5qUPfIhKLAkQTAyU/KgfhHh4i+MJK5ghPbGDE8r2gKUXOkM6M5//ZCpmu0K
+Y/9uQL6D5bkxEaoWegEO+wSXm+hTTgKDtQKHvRibgdcZkcY0cA9JsLrC/nIkP+7i
+pbBT+VTuV6gAnKIV0nq8zvI3A/Z3nAb5Gt0g3qaqs59StDT0QtuXzJkuZEo3XSrS
+jon+8NjSNzqVbJj95B7+uiH+91VEbMtJYFz2MipKvJQDK7Zlxke7LxRj2xJfksJK
+a92/ncxfAgMBAAECggEAQztaMvW5lm35J8LKsWs/5qEJRX9T8LWs8W0oqq36Riub
+G2wgvR6ndAIPcSjAYZqX7iOl7m6NZ0+0kN63HxdGqovwKIskpAekBGmhpYftED1n
+zh0r6UyMB3UnQ22KdOv8UOokIDxxdNX8728BdUYdT9Ggdkj5jLRB+VcwD0IUlNvo
+zzTpURV9HEd87uiLqd4AAHXSI0lIHI5U43z24HI/J6/YbYHT3Rlh6CIa/LuwO6vL
+gFkgqg0/oy6yJtjrHtzNVA67F0UaH62hR4YFgbC0d955SJnDidWOv/0j2DMpfdCc
+9kFAcPwUSyykvUSLnGIKWSG4D+6gzIeAeUx4oO7kMQKBgQDVNRkX8AGTHyLg+NXf
+spUWWcodwVioXl30Q7h6+4bt8OI61UbhQ7wX61wvJ1cySpa2KOYa2UdagQVhGhhL
+ADu363R77uXF/jZgzVfmjjyJ2nfDqRgHWRTlSkuq/jCOQCz7VIPHRZg5WL/9D4ms
+TAqMjpzqeMfFZI+w4/+xpcJIuQKBgQDTKBy+ZuerWrVT9icWKvLU58o5EVj/2yFy
+GJvKm+wRAAX2WzjNnR4HVd4DmMREVz1BPYby0j5gqjvtDsxYYu39+NT7JvMioLLK
+QPj+7k5geYgNqVgCxB1vP89RhY2X1RLrN9sTXOodgFPeXOQWNYITkGp3eQpx4nTJ
++K/al3oB1wKBgAjnc8nVIyuyxDEjE0OJYMKTM2a0uXAmqMPXxC+Wq5bqVXhhidlE
+i+lv0eTCPtkB1nN7F8kNQ/aaps/cWCFhvBy9P5shagUvzbOTP9WIIS0cq53HRRKh
+fMbqqGhWv05hjb9dUzeSR341n6cA7B3++v3Nwu3j52vt/DZF/1q68nc5AoGAS0SU
+ImbKE/GsizZGLoe2sZ/CHN+LKwCwhlwxRGKaHmE0vuE7eUeVSaYZEo0lAPtb8WJ+
+NRYueASWgeTxgFwbW5mUScZTirdfo+rPFwhZVdhcYApKPgosN9i2DOgfVcz1BnWN
+mPRY25U/0BaqkyQVruWeneG+kGPZn5kPDktKiVcCgYEAkzwU9vCGhm7ZVALvx/zR
+wARz2zsL9ImBc0P4DK1ld8g90FEnHrEgeI9JEwz0zFHOCMLwlk7kG0Xev7vfjZ7G
+xSqtQYOH33Qp6rtBOgdt8hSyDFvakvDl6bqhAw52gelO3MTpAB1+ZsfZ5gFx13Jf
+idNFcaIrC52PtZIH7QCzdDY=
+-----END PRIVATE KEY----- \ No newline at end of file
diff --git a/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java b/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java
index 36f5e41462e8..2333718d0cab 100644
--- a/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnControlPlaneIkeConfigTest.java
@@ -99,6 +99,13 @@ public class VcnControlPlaneIkeConfigTest {
}
@Test
+ public void testPersistableBundle() {
+ final VcnControlPlaneIkeConfig config = buildTestConfig();
+
+ assertEquals(config, new VcnControlPlaneIkeConfig(config.toPersistableBundle()));
+ }
+
+ @Test
public void testConstructConfigWithoutIkeParams() {
try {
new VcnControlPlaneIkeConfig(null, CHILD_PARAMS);
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
new file mode 100644
index 000000000000..546d957d417e
--- /dev/null
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vcn.persistablebundleutils;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.telephony.TelephonyManager.APPTYPE_USIM;
+
+import static org.junit.Assert.assertEquals;
+
+import android.net.InetAddresses;
+import android.net.eap.EapSessionConfig;
+import android.net.ipsec.ike.IkeFqdnIdentification;
+import android.net.ipsec.ike.IkeSessionParams;
+import android.os.PersistableBundle;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.org.bouncycastle.util.io.pem.PemObject;
+import com.android.internal.org.bouncycastle.util.io.pem.PemReader;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IkeSessionParamsUtilsTest {
+ private static IkeSessionParams.Builder createBuilderMinimum() {
+ final InetAddress serverAddress = InetAddresses.parseNumericAddress("192.0.2.100");
+
+ return new IkeSessionParams.Builder()
+ .setServerHostname(serverAddress.getHostAddress())
+ .addSaProposal(SaProposalUtilsTest.buildTestIkeSaProposal())
+ .setLocalIdentification(new IkeFqdnIdentification("client.test.android.net"))
+ .setRemoteIdentification(new IkeFqdnIdentification("server.test.android.net"))
+ .setAuthPsk("psk".getBytes());
+ }
+
+ private static void verifyPersistableBundleEncodeDecodeIsLossless(IkeSessionParams params) {
+ final PersistableBundle bundle = IkeSessionParamsUtils.toPersistableBundle(params);
+ final IkeSessionParams result = IkeSessionParamsUtils.fromPersistableBundle(bundle);
+
+ assertEquals(result, params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithLifetimes() throws Exception {
+ final int hardLifetime = (int) TimeUnit.HOURS.toSeconds(20L);
+ final int softLifetime = (int) TimeUnit.HOURS.toSeconds(10L);
+ final IkeSessionParams params =
+ createBuilderMinimum().setLifetimeSeconds(hardLifetime, softLifetime).build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithDpdDelay() throws Exception {
+ final int dpdDelay = (int) TimeUnit.MINUTES.toSeconds(10L);
+ final IkeSessionParams params = createBuilderMinimum().setDpdDelaySeconds(dpdDelay).build();
+
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithNattKeepalive() throws Exception {
+ final int nattKeepAliveDelay = (int) TimeUnit.MINUTES.toSeconds(5L);
+ final IkeSessionParams params =
+ createBuilderMinimum().setNattKeepAliveDelaySeconds(nattKeepAliveDelay).build();
+
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithRetransmissionTimeouts() throws Exception {
+ final int[] retransmissionTimeout = new int[] {500, 500, 500, 500, 500, 500};
+ final IkeSessionParams params =
+ createBuilderMinimum()
+ .setRetransmissionTimeoutsMillis(retransmissionTimeout)
+ .build();
+
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithConfigRequests() throws Exception {
+ final Inet4Address ipv4Address =
+ (Inet4Address) InetAddresses.parseNumericAddress("192.0.2.100");
+ final Inet6Address ipv6Address =
+ (Inet6Address) InetAddresses.parseNumericAddress("2001:db8::1");
+
+ final IkeSessionParams params =
+ createBuilderMinimum()
+ .addPcscfServerRequest(AF_INET)
+ .addPcscfServerRequest(AF_INET6)
+ .addPcscfServerRequest(ipv4Address)
+ .addPcscfServerRequest(ipv6Address)
+ .build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithAuthPsk() throws Exception {
+ final IkeSessionParams params = createBuilderMinimum().setAuthPsk("psk".getBytes()).build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithIkeOptions() throws Exception {
+ final IkeSessionParams params =
+ createBuilderMinimum()
+ .addIkeOption(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID)
+ .addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)
+ .build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ private static InputStream openAssetsFile(String fileName) throws Exception {
+ return InstrumentationRegistry.getContext().getResources().getAssets().open(fileName);
+ }
+
+ private static X509Certificate createCertFromPemFile(String fileName) throws Exception {
+ final CertificateFactory factory = CertificateFactory.getInstance("X.509");
+ return (X509Certificate) factory.generateCertificate(openAssetsFile(fileName));
+ }
+
+ private static RSAPrivateKey createRsaPrivateKeyFromKeyFile(String fileName) throws Exception {
+ final PemObject pemObject =
+ new PemReader(new InputStreamReader(openAssetsFile(fileName))).readPemObject();
+ return (RSAPrivateKey) CertUtils.privateKeyFromByteArray(pemObject.getContent());
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithDigitalSignAuth() throws Exception {
+ final X509Certificate serverCaCert = createCertFromPemFile("self-signed-ca.pem");
+ final X509Certificate clientEndCert = createCertFromPemFile("client-end-cert.pem");
+ final RSAPrivateKey clientPrivateKey =
+ createRsaPrivateKeyFromKeyFile("client-private-key.key");
+
+ final IkeSessionParams params =
+ createBuilderMinimum()
+ .setAuthDigitalSignature(serverCaCert, clientEndCert, clientPrivateKey)
+ .build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+
+ @Test
+ public void testEncodeRecodeParamsWithEapAuth() throws Exception {
+ final X509Certificate serverCaCert = createCertFromPemFile("self-signed-ca.pem");
+
+ final byte[] eapId = "test@android.net".getBytes(StandardCharsets.US_ASCII);
+ final int subId = 1;
+ final EapSessionConfig eapConfig =
+ new EapSessionConfig.Builder()
+ .setEapIdentity(eapId)
+ .setEapSimConfig(subId, APPTYPE_USIM)
+ .setEapAkaConfig(subId, APPTYPE_USIM)
+ .build();
+
+ final IkeSessionParams params =
+ createBuilderMinimum().setAuthEap(serverCaCert, eapConfig).build();
+ verifyPersistableBundleEncodeDecodeIsLossless(params);
+ }
+}
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
index 8ae8692b4f75..664044a9e7d4 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
@@ -32,21 +32,25 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class SaProposalUtilsTest {
+ /** Package private so that IkeSessionParamsUtilsTest can use it */
+ static IkeSaProposal buildTestIkeSaProposal() {
+ return new IkeSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_3DES, SaProposal.KEY_LEN_UNUSED)
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256)
+ .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+ .addDhGroup(SaProposal.DH_GROUP_3072_BIT_MODP)
+ .build();
+ }
+
@Test
public void testPersistableBundleEncodeDecodeIsLosslessIkeProposal() throws Exception {
- final IkeSaProposal proposal =
- new IkeSaProposal.Builder()
- .addEncryptionAlgorithm(
- SaProposal.ENCRYPTION_ALGORITHM_3DES, SaProposal.KEY_LEN_UNUSED)
- .addEncryptionAlgorithm(
- SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
- .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
- .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
- .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
- .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256)
- .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
- .addDhGroup(SaProposal.DH_GROUP_3072_BIT_MODP)
- .build();
+ final IkeSaProposal proposal = buildTestIkeSaProposal();
final PersistableBundle bundle = IkeSaProposalUtils.toPersistableBundle(proposal);
final SaProposal resultProposal = IkeSaProposalUtils.fromPersistableBundle(bundle);
diff --git a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
index 1d459a347526..1ef1a61f17ea 100644
--- a/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java
@@ -194,29 +194,35 @@ public class UnderlyingNetworkTrackerTest {
}
private NetworkRequest getWifiRequest() {
- return getExpectedRequestBase()
+ return getExpectedRequestBase(true)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build();
}
private NetworkRequest getCellRequestForSubId(int subId) {
- return getExpectedRequestBase()
+ return getExpectedRequestBase(false)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId))
.build();
}
private NetworkRequest getRouteSelectionRequest() {
- return getExpectedRequestBase().build();
+ return getExpectedRequestBase(true).build();
}
- private NetworkRequest.Builder getExpectedRequestBase() {
- return new NetworkRequest.Builder()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
- .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ private NetworkRequest.Builder getExpectedRequestBase(boolean requireVcnManaged) {
+ final NetworkRequest.Builder builder =
+ new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+
+ if (requireVcnManaged) {
+ builder.addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+ }
+
+ return builder;
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 69b2fb135a8d..0e5f5e43f282 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -73,7 +73,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
mGatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1);
- mIkeSession = mGatewayConnection.buildIkeSession();
+ mIkeSession = mGatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_1.network);
mGatewayConnection.setIkeSession(mIkeSession);
mGatewayConnection.transitionTo(mGatewayConnection.mConnectedState);
@@ -241,7 +241,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
verify(mGatewayStatusCallback)
.onGatewayConnectionError(
- eq(mConfig.getRequiredUnderlyingCapabilities()),
+ eq(mConfig.getExposedCapabilities()),
eq(VCN_ERROR_CODE_INTERNAL_ERROR),
any(),
any());
@@ -275,10 +275,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
verify(mGatewayStatusCallback)
.onGatewayConnectionError(
- eq(mConfig.getRequiredUnderlyingCapabilities()),
- eq(expectedErrorType),
- any(),
- any());
+ eq(mConfig.getExposedCapabilities()), eq(expectedErrorType), any(), any());
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
index d07d2cf4f1bb..7afa4494ee8b 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
@@ -25,12 +25,15 @@ import static org.mockito.Matchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.net.ipsec.ike.IkeSessionParams;
+
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
/** Tests for VcnGatewayConnection.ConnectingState */
@RunWith(AndroidJUnit4.class)
@@ -51,7 +54,12 @@ public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectio
@Test
public void testEnterStateCreatesNewIkeSession() throws Exception {
- verify(mDeps).newIkeSession(any(), any(), any(), any(), any());
+ final ArgumentCaptor<IkeSessionParams> paramsCaptor =
+ ArgumentCaptor.forClass(IkeSessionParams.class);
+ verify(mDeps).newIkeSession(any(), paramsCaptor.capture(), any(), any(), any());
+ assertEquals(
+ TEST_UNDERLYING_NETWORK_RECORD_1.network,
+ paramsCaptor.getValue().getConfiguredNetwork());
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
index 661e03af4f84..99feffdebc8e 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
@@ -38,7 +38,8 @@ public class VcnGatewayConnectionDisconnectingStateTest extends VcnGatewayConnec
public void setUp() throws Exception {
super.setUp();
- mGatewayConnection.setIkeSession(mGatewayConnection.buildIkeSession());
+ mGatewayConnection.setIkeSession(
+ mGatewayConnection.buildIkeSession(TEST_UNDERLYING_NETWORK_RECORD_2.network));
// ensure that mGatewayConnection has an underlying Network before entering
// DisconnectingState
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index 748c7924685d..d08af9dd3370 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -18,6 +18,7 @@ package com.android.server.vcn;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
@@ -87,6 +88,7 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
private void verifyBuildNetworkCapabilitiesCommon(int transportType) {
final NetworkCapabilities underlyingCaps = new NetworkCapabilities();
underlyingCaps.addTransportType(transportType);
+ underlyingCaps.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
underlyingCaps.addCapability(NET_CAPABILITY_NOT_METERED);
underlyingCaps.addCapability(NET_CAPABILITY_NOT_ROAMING);