summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk5
-rw-r--r--api/current.txt273
-rw-r--r--api/system-current.txt280
-rw-r--r--core/java/android/animation/AnimatorInflater.java2
-rw-r--r--core/java/android/app/Activity.java25
-rw-r--r--core/java/android/app/BackStackRecord.java1
-rw-r--r--core/java/android/app/Dialog.java22
-rw-r--r--core/java/android/app/IUserSwitchObserver.aidl1
-rw-r--r--core/java/android/app/KeyguardManager.java26
-rw-r--r--core/java/android/app/SharedElementCallback.java46
-rw-r--r--core/java/android/app/admin/DeviceInitializerStatus.java177
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java204
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl10
-rw-r--r--core/java/android/app/admin/OtaPolicy.java179
-rw-r--r--core/java/android/app/backup/BackupTransport.java7
-rw-r--r--core/java/android/app/trust/ITrustManager.aidl1
-rw-r--r--core/java/android/content/Intent.java8
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java6
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java18
-rw-r--r--core/java/android/hardware/location/GeofenceHardwareImpl.java27
-rw-r--r--core/java/android/hardware/location/GeofenceHardwareService.java11
-rw-r--r--core/java/android/hardware/location/IFusedLocationHardware.aidl29
-rw-r--r--core/java/android/hardware/location/IFusedLocationHardwareSink.aidl16
-rw-r--r--core/java/android/net/IpPrefix.java15
-rw-r--r--core/java/android/net/RouteInfo.java8
-rw-r--r--core/java/android/os/UserManager.java4
-rw-r--r--core/java/android/provider/Settings.java9
-rw-r--r--core/java/android/provider/VoicemailContract.java5
-rw-r--r--core/java/android/security/keymaster/KeyCharacteristics.java55
-rw-r--r--core/java/android/security/keymaster/KeymasterArguments.java9
-rw-r--r--core/java/android/service/chooser/ChooserTarget.java139
-rw-r--r--core/java/android/service/chooser/ChooserTargetService.java25
-rw-r--r--core/java/android/service/dreams/DreamService.java7
-rw-r--r--core/java/android/service/notification/ZenModeConfig.java11
-rw-r--r--core/java/android/view/PhoneWindow.java11
-rw-r--r--core/java/android/view/SearchEvent.java40
-rw-r--r--core/java/android/view/View.java68
-rw-r--r--core/java/android/view/ViewGroup.java98
-rw-r--r--core/java/android/view/Window.java9
-rw-r--r--core/java/android/view/WindowCallbackWrapper.java5
-rw-r--r--core/java/android/widget/ActionMenuPresenter.java67
-rwxr-xr-xcore/java/android/widget/DatePickerCalendarDelegate.java12
-rw-r--r--core/java/android/widget/DayPickerView.java92
-rw-r--r--core/java/android/widget/SimpleMonthView.java18
-rw-r--r--core/java/android/widget/TextView.java1
-rw-r--r--core/java/android/widget/YearPickerView.java27
-rw-r--r--core/java/com/android/internal/app/AlertController.java59
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java392
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java469
-rw-r--r--core/java/com/android/internal/backup/LocalTransport.java53
-rw-r--r--core/java/com/android/internal/logging/MetricsLogger.java3
-rw-r--r--core/java/com/android/internal/os/PowerProfile.java2
-rw-r--r--core/java/com/android/internal/transition/ActionBarTransition.java58
-rw-r--r--core/java/com/android/internal/widget/ActionBarView.java11
-rw-r--r--core/java/com/android/internal/widget/DialogViewAnimator.java141
-rw-r--r--core/java/com/android/internal/widget/ViewPager.java2
-rw-r--r--core/jni/android/graphics/BitmapFactory.cpp2
-rw-r--r--core/jni/android/graphics/BitmapRegionDecoder.cpp2
-rw-r--r--core/jni/android/graphics/Graphics.cpp17
-rw-r--r--core/jni/android/graphics/GraphicsJNI.h4
-rw-r--r--core/jni/android/graphics/pdf/PdfRenderer.cpp19
-rw-r--r--core/jni/android/opengl/util.cpp18
-rw-r--r--core/jni/android_view_PointerIcon.cpp5
-rw-r--r--core/jni/com_google_android_gles_jni_EGLImpl.cpp13
-rw-r--r--core/res/AndroidManifest.xml8
-rw-r--r--core/res/res/anim/date_picker_fade_in_material.xml22
-rw-r--r--core/res/res/anim/date_picker_fade_out_material.xml22
-rw-r--r--core/res/res/layout/chooser_grid.xml107
-rw-r--r--core/res/res/layout/date_picker_material.xml4
-rw-r--r--core/res/res/layout/date_picker_view_animator_material.xml18
-rw-r--r--core/res/res/layout/resolve_grid_item.xml60
-rw-r--r--core/res/res/layout/select_dialog_multichoice_material.xml12
-rw-r--r--core/res/res/layout/select_dialog_singlechoice_material.xml12
-rw-r--r--core/res/res/values-af/strings.xml2
-rw-r--r--core/res/res/values-am/strings.xml2
-rw-r--r--core/res/res/values-ar/strings.xml2
-rw-r--r--core/res/res/values-bg/strings.xml8
-rw-r--r--core/res/res/values-bn-rBD/strings.xml2
-rw-r--r--core/res/res/values-ca/strings.xml2
-rw-r--r--core/res/res/values-cs/strings.xml8
-rw-r--r--core/res/res/values-da/strings.xml2
-rw-r--r--core/res/res/values-de/strings.xml2
-rw-r--r--core/res/res/values-el/strings.xml23
-rw-r--r--core/res/res/values-en-rAU/strings.xml23
-rw-r--r--core/res/res/values-en-rGB/strings.xml23
-rw-r--r--core/res/res/values-en-rIN/strings.xml23
-rw-r--r--core/res/res/values-es-rUS/strings.xml2
-rw-r--r--core/res/res/values-es/strings.xml2
-rw-r--r--core/res/res/values-et-rEE/strings.xml8
-rw-r--r--core/res/res/values-eu-rES/strings.xml8
-rw-r--r--core/res/res/values-fa/strings.xml2
-rw-r--r--core/res/res/values-fi/strings.xml8
-rw-r--r--core/res/res/values-fr-rCA/strings.xml2
-rw-r--r--core/res/res/values-fr/strings.xml2
-rw-r--r--core/res/res/values-gl-rES/strings.xml2
-rw-r--r--core/res/res/values-hi/strings.xml2
-rw-r--r--core/res/res/values-hr/strings.xml8
-rw-r--r--core/res/res/values-hu/strings.xml2
-rw-r--r--core/res/res/values-hy-rAM/strings.xml8
-rw-r--r--core/res/res/values-in/strings.xml23
-rw-r--r--core/res/res/values-is-rIS/strings.xml2
-rw-r--r--core/res/res/values-it/strings.xml2
-rw-r--r--core/res/res/values-iw/strings.xml29
-rw-r--r--core/res/res/values-ja/strings.xml8
-rw-r--r--core/res/res/values-ka-rGE/strings.xml8
-rw-r--r--core/res/res/values-kk-rKZ/strings.xml8
-rw-r--r--core/res/res/values-km-rKH/strings.xml8
-rw-r--r--core/res/res/values-kn-rIN/strings.xml2
-rw-r--r--core/res/res/values-ko/strings.xml8
-rw-r--r--core/res/res/values-ky-rKG/strings.xml8
-rw-r--r--core/res/res/values-lo-rLA/strings.xml29
-rw-r--r--core/res/res/values-lt/strings.xml2
-rw-r--r--core/res/res/values-lv/strings.xml8
-rw-r--r--core/res/res/values-mk-rMK/strings.xml2
-rw-r--r--core/res/res/values-ml-rIN/strings.xml2
-rw-r--r--core/res/res/values-mn-rMN/strings.xml8
-rw-r--r--core/res/res/values-mr-rIN/strings.xml2
-rw-r--r--core/res/res/values-ms-rMY/strings.xml2
-rw-r--r--core/res/res/values-my-rMM/strings.xml23
-rw-r--r--core/res/res/values-nb/strings.xml2
-rw-r--r--core/res/res/values-ne-rNP/strings.xml29
-rw-r--r--core/res/res/values-nl/strings.xml8
-rw-r--r--core/res/res/values-pl/strings.xml2
-rw-r--r--core/res/res/values-pt-rPT/strings.xml2
-rw-r--r--core/res/res/values-pt/strings.xml2
-rw-r--r--core/res/res/values-ro/strings.xml2
-rw-r--r--core/res/res/values-ru/strings.xml2
-rw-r--r--core/res/res/values-si-rLK/strings.xml8
-rw-r--r--core/res/res/values-sk/strings.xml8
-rw-r--r--core/res/res/values-sl/strings.xml8
-rw-r--r--core/res/res/values-sr/strings.xml8
-rw-r--r--core/res/res/values-sv/strings.xml2
-rw-r--r--core/res/res/values-sw/strings.xml4
-rw-r--r--core/res/res/values-sw360dp/dimens.xml (renamed from core/java/android/os/IHardwareService.aidl)21
-rw-r--r--core/res/res/values-ta-rIN/strings.xml2
-rw-r--r--core/res/res/values-te-rIN/strings.xml2
-rw-r--r--core/res/res/values-th/strings.xml8
-rw-r--r--core/res/res/values-tl/strings.xml29
-rw-r--r--core/res/res/values-tr/strings.xml8
-rw-r--r--core/res/res/values-uk/strings.xml2
-rw-r--r--core/res/res/values-ur-rPK/strings.xml8
-rw-r--r--core/res/res/values-uz-rUZ/strings.xml29
-rw-r--r--core/res/res/values-vi/strings.xml8
-rw-r--r--core/res/res/values-zh-rCN/strings.xml2
-rw-r--r--core/res/res/values-zh-rHK/strings.xml8
-rw-r--r--core/res/res/values-zh-rTW/strings.xml8
-rw-r--r--core/res/res/values-zu/strings.xml23
-rw-r--r--core/res/res/values/attrs.xml5
-rwxr-xr-xcore/res/res/values/config.xml1
-rw-r--r--core/res/res/values/dimens.xml1
-rw-r--r--core/res/res/values/dimens_material.xml3
-rw-r--r--core/res/res/values/strings.xml6
-rwxr-xr-xcore/res/res/values/symbols.xml3
-rw-r--r--core/tests/coretests/src/android/net/IpPrefixTest.java32
-rw-r--r--core/tests/coretests/src/android/net/RouteInfoTest.java1
-rw-r--r--docs/html-ndk/ndk/downloads/downloads_toc.cs21
-rw-r--r--docs/html-ndk/ndk/downloads/index.jd4
-rw-r--r--docs/html-ndk/ndk/guides/guides_toc.cs22
-rw-r--r--docs/html-ndk/ndk/guides/index.jd4
-rw-r--r--docs/html-ndk/ndk/guides/md_1__concepts__concepts.html4
-rw-r--r--docs/html-ndk/ndk/index.jd15
-rw-r--r--docs/html-ndk/ndk/reference/index.jd4
-rw-r--r--docs/html-ndk/ndk/reference/reference_toc.cs21
-rw-r--r--docs/html-ndk/ndk/samples/index.jd4
-rw-r--r--docs/html-ndk/ndk/samples/samples_toc.cs21
-rw-r--r--docs/html/distribute/googleplay/families/about.jd67
-rw-r--r--docs/html/distribute/googleplay/families/faq.jd336
-rw-r--r--docs/html/distribute/googleplay/families/start.jd114
-rw-r--r--docs/html/distribute/googleplay/googleplay_toc.cs26
-rw-r--r--docs/html/distribute/googleplay/index.jd2
-rw-r--r--docs/html/distribute/images/about-dff-sm.jpgbin0 -> 84913 bytes
-rw-r--r--docs/html/images/gp-dff-appinfo.pngbin0 -> 85204 bytes
-rw-r--r--docs/html/images/gp-dff-optin.pngbin0 -> 27643 bytes
-rw-r--r--docs/html/jd_collections.js3
-rw-r--r--docs/html/tools/debugging/debugging-memory.jd328
-rw-r--r--docs/html/tools/extras/oem-usb.jd26
-rw-r--r--docs/html/tools/help/adb.jd1
-rw-r--r--docs/html/tools/help/systrace.jd3
-rw-r--r--docs/html/training/articles/keystore.jd21
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java227
-rw-r--r--graphics/java/android/graphics/pdf/PdfRenderer.java4
-rw-r--r--keystore/java/android/security/AndroidKeyStore.java115
-rw-r--r--keystore/java/android/security/ArrayUtils.java62
-rw-r--r--keystore/java/android/security/CryptoOperationException.java2
-rw-r--r--keystore/java/android/security/EcIesParameterSpec.java6
-rw-r--r--keystore/java/android/security/KeyExpiredException.java2
-rw-r--r--keystore/java/android/security/KeyGeneratorSpec.java92
-rw-r--r--keystore/java/android/security/KeyNotYetValidException.java2
-rw-r--r--keystore/java/android/security/KeyPairGeneratorSpec.java188
-rw-r--r--keystore/java/android/security/KeyStoreCipherSpi.java55
-rw-r--r--keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java57
-rw-r--r--keystore/java/android/security/KeyStoreHmacSpi.java22
-rw-r--r--keystore/java/android/security/KeyStoreKeyCharacteristics.java63
-rw-r--r--keystore/java/android/security/KeyStoreKeyConstraints.java946
-rw-r--r--keystore/java/android/security/KeyStoreKeyGeneratorSpi.java103
-rw-r--r--keystore/java/android/security/KeyStoreKeyProperties.java281
-rw-r--r--keystore/java/android/security/KeyStoreKeySpec.java74
-rw-r--r--keystore/java/android/security/KeyStoreParameter.java180
-rw-r--r--keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java93
-rw-r--r--keystore/java/android/security/KeymasterUtils.java323
-rw-r--r--keystore/java/android/security/NewFingerprintEnrolledException.java2
-rw-r--r--keystore/java/android/security/UserNotAuthenticatedException.java2
-rw-r--r--location/lib/java/com/android/location/provider/FusedLocationHardware.java79
-rw-r--r--location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java46
-rw-r--r--media/java/android/media/AudioRecord.java8
-rw-r--r--media/java/android/media/AudioTrack.java59
-rw-r--r--media/java/android/media/MediaCodecInfo.java24
-rw-r--r--media/java/android/media/MediaCodecList.java9
-rw-r--r--media/java/android/media/midi/package.html324
-rw-r--r--media/jni/android_media_MediaCodecList.cpp25
-rw-r--r--media/jni/android_media_MediaMetadataRetriever.cpp9
-rw-r--r--native/graphics/jni/bitmap.cpp35
-rw-r--r--packages/DocumentsUI/res/values-el/strings.xml3
-rw-r--r--packages/DocumentsUI/res/values-en-rAU/strings.xml3
-rw-r--r--packages/DocumentsUI/res/values-en-rGB/strings.xml3
-rw-r--r--packages/DocumentsUI/res/values-en-rIN/strings.xml3
-rw-r--r--packages/DocumentsUI/res/values-in/strings.xml3
-rw-r--r--packages/DocumentsUI/res/values-iw/strings.xml3
-rw-r--r--packages/DocumentsUI/res/values-lo-rLA/strings.xml3
-rw-r--r--packages/DocumentsUI/res/values-my-rMM/strings.xml3
-rw-r--r--packages/DocumentsUI/res/values-ne-rNP/strings.xml3
-rw-r--r--packages/DocumentsUI/res/values-tl/strings.xml3
-rw-r--r--packages/DocumentsUI/res/values-uz-rUZ/strings.xml3
-rw-r--r--packages/DocumentsUI/res/values-zu/strings.xml3
-rw-r--r--packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml2
-rw-r--r--packages/Keyguard/res/values-el/strings.xml3
-rw-r--r--packages/Keyguard/res/values-en-rAU/strings.xml3
-rw-r--r--packages/Keyguard/res/values-en-rGB/strings.xml3
-rw-r--r--packages/Keyguard/res/values-en-rIN/strings.xml3
-rw-r--r--packages/Keyguard/res/values-in/strings.xml3
-rw-r--r--packages/Keyguard/res/values-iw/strings.xml3
-rw-r--r--packages/Keyguard/res/values-lo-rLA/strings.xml3
-rw-r--r--packages/Keyguard/res/values-my-rMM/strings.xml3
-rw-r--r--packages/Keyguard/res/values-ne-rNP/strings.xml3
-rw-r--r--packages/Keyguard/res/values-tl/strings.xml3
-rw-r--r--packages/Keyguard/res/values-uz-rUZ/strings.xml3
-rw-r--r--packages/Keyguard/res/values-zh-rCN/strings.xml3
-rw-r--r--packages/Keyguard/res/values-zu/strings.xml3
-rw-r--r--packages/Keyguard/res/values/strings.xml2
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java4
-rw-r--r--packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml29
-rw-r--r--packages/SystemUI/res/values-el/strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml3
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml3
-rw-r--r--packages/SystemUI/res/values-in/strings.xml3
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml3
-rw-r--r--packages/SystemUI/res/values-lo-rLA/strings.xml3
-rw-r--r--packages/SystemUI/res/values-my-rMM/strings.xml3
-rw-r--r--packages/SystemUI/res/values-ne-rNP/strings.xml3
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml3
-rw-r--r--packages/SystemUI/res/values-uz-rUZ/strings.xml3
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java82
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java5
-rw-r--r--preloaded-classes1
-rw-r--r--rs/jni/android_renderscript_RenderScript.cpp25
-rw-r--r--services/core/java/com/android/server/InputMethodManagerService.java5
-rw-r--r--services/core/java/com/android/server/LockSettingsService.java1
-rw-r--r--services/core/java/com/android/server/TextServicesManagerService.java5
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java21
-rw-r--r--services/core/java/com/android/server/content/AppIdleMonitor.java89
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java65
-rw-r--r--services/core/java/com/android/server/content/SyncOperation.java3
-rw-r--r--services/core/java/com/android/server/display/DisplayBlanker.java2
-rw-r--r--services/core/java/com/android/server/display/DisplayDevice.java4
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java48
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java6
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerState.java39
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java97
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java2
-rw-r--r--services/core/java/com/android/server/lights/LightsService.java48
-rw-r--r--services/core/java/com/android/server/location/FlpHardwareProvider.java55
-rw-r--r--services/core/java/com/android/server/location/FusedLocationHardwareSecure.java6
-rw-r--r--services/core/java/com/android/server/notification/ConditionProviders.java14
-rw-r--r--services/core/java/com/android/server/notification/CountdownConditionProvider.java2
-rw-r--r--services/core/java/com/android/server/notification/ScheduleConditionProvider.java2
-rw-r--r--services/core/java/com/android/server/notification/ZenModeConditions.java78
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java149
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java14
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java5
-rw-r--r--services/core/jni/com_android_server_location_FlpHardwareProvider.cpp72
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java30
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java143
-rw-r--r--services/java/com/android/server/SystemServer.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java10
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java4
-rw-r--r--tools/layoutlib/bridge/src/android/view/WindowCallback.java5
290 files changed, 7088 insertions, 3082 deletions
diff --git a/Android.mk b/Android.mk
index 3e049f7..64a8b89 100644
--- a/Android.mk
+++ b/Android.mk
@@ -195,7 +195,6 @@ LOCAL_SRC_FILES += \
core/java/android/os/IBatteryPropertiesListener.aidl \
core/java/android/os/IBatteryPropertiesRegistrar.aidl \
core/java/android/os/ICancellationSignal.aidl \
- core/java/android/os/IHardwareService.aidl \
core/java/android/os/IMessenger.aidl \
core/java/android/os/INetworkActivityListener.aidl \
core/java/android/os/INetworkManagementService.aidl \
@@ -1018,13 +1017,13 @@ LOCAL_STATIC_JAVA_LIBRARIES:=$(framework_docs_LOCAL_STATIC_JAVA_LIBRARIES)
LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES)
LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
-LOCAL_DROIDDOC_HTML_DIR:=$(framework_docs_LOCAL_DROIDDOC_HTML_DIR)
+LOCAL_DROIDDOC_HTML_DIR:=docs/html-ndk
LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_ADDITIONAL_JAVA_DIR)
LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
# specify a second html input dir and an output path relative to OUT_DIR)
LOCAL_ADDITIONAL_HTML_DIR:=docs/html-intl/intl /
-LOCAL_MODULE := ndk
+LOCAL_MODULE := online-ndk
LOCAL_DROIDDOC_OPTIONS:= \
$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
diff --git a/api/current.txt b/api/current.txt
index ee6a667..ea4aaf9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3353,6 +3353,7 @@ package android.app {
method public android.content.SharedPreferences getPreferences(int);
method public android.net.Uri getReferrer();
method public int getRequestedOrientation();
+ method public final android.view.SearchEvent getSearchEvent();
method public int getTaskId();
method public final java.lang.CharSequence getTitle();
method public final int getTitleColor();
@@ -3435,6 +3436,7 @@ package android.app {
method public deprecated java.lang.Object onRetainNonConfigurationInstance();
method protected void onSaveInstanceState(android.os.Bundle);
method public void onSaveInstanceState(android.os.Bundle, android.os.PersistableBundle);
+ method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method protected void onStart();
method protected void onStop();
@@ -4112,6 +4114,7 @@ package android.app {
method public android.view.View getCurrentFocus();
method public android.view.LayoutInflater getLayoutInflater();
method public final android.app.Activity getOwnerActivity();
+ method public final android.view.SearchEvent getSearchEvent();
method public final int getVolumeControlStream();
method public android.view.Window getWindow();
method public void hide();
@@ -4145,6 +4148,7 @@ package android.app {
method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
method public void onRestoreInstanceState(android.os.Bundle);
method public android.os.Bundle onSaveInstanceState();
+ method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method protected void onStart();
method protected void onStop();
@@ -4592,6 +4596,7 @@ package android.app {
method public deprecated void exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult);
method public boolean inKeyguardRestrictedInputMode();
method public boolean isDeviceLocked();
+ method public boolean isDeviceSecure();
method public boolean isKeyguardLocked();
method public boolean isKeyguardSecure();
method public deprecated android.app.KeyguardManager.KeyguardLock newKeyguardLock(java.lang.String);
@@ -5611,6 +5616,26 @@ package android.app.admin {
field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
}
+ public class DeviceInitializerStatus {
+ method public static boolean isCustomStatus(int);
+ method public static boolean isErrorStatus(int);
+ method public static boolean isHighPriority(int);
+ field public static final int FLAG_STATUS_CUSTOM = 33554432; // 0x2000000
+ field public static final int FLAG_STATUS_ERROR = 16777216; // 0x1000000
+ field public static final int FLAG_STATUS_HIGH_PRIORITY = 134217728; // 0x8000000
+ field public static final int FLAG_STATUS_RESERVED = 67108864; // 0x4000000
+ field public static final int STATUS_ERROR_CONNECT_WIFI = 16777237; // 0x1000015
+ field public static final int STATUS_ERROR_DELETE_APPS = 16777242; // 0x100001a
+ field public static final int STATUS_ERROR_DOUBLE_BUMP = 16777246; // 0x100001e
+ field public static final int STATUS_ERROR_DOWNLOAD_PACKAGE = 16777239; // 0x1000017
+ field public static final int STATUS_ERROR_INSTALL_PACKAGE = 16777240; // 0x1000018
+ field public static final int STATUS_ERROR_RESET_PROTECTION_BLOCKING_PROVISIONING = 16777238; // 0x1000016
+ field public static final int STATUS_ERROR_SET_DEVICE_POLICY = 16777241; // 0x1000019
+ field public static final int STATUS_STATE_CONNECT_BLUETOOTH_PROXY = 134217736; // 0x8000008
+ field public static final int STATUS_STATE_DEVICE_PROVISIONED = 134217738; // 0x800000a
+ field public static final int STATUS_STATE_DISCONNECT_BLUETOOTH_PROXY = 134217737; // 0x8000009
+ }
+
public class DevicePolicyManager {
method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -5629,6 +5654,7 @@ package android.app.admin {
method public java.util.List<android.content.ComponentName> getActiveAdmins();
method public android.os.Bundle getApplicationRestrictions(android.content.ComponentName, java.lang.String);
method public boolean getAutoTimeRequired();
+ method public boolean getBluetoothContactSharingDisabled(android.content.ComponentName);
method public boolean getCameraDisabled(android.content.ComponentName);
method public java.lang.String getCertInstallerPackage(android.content.ComponentName) throws java.lang.SecurityException;
method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
@@ -5638,6 +5664,7 @@ package android.app.admin {
method public int getKeyguardDisabledFeatures(android.content.ComponentName);
method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
method public long getMaximumTimeToLock(android.content.ComponentName);
+ method public android.app.admin.OtaPolicy getOtaPolicy();
method public long getPasswordExpiration(android.content.ComponentName);
method public long getPasswordExpirationTimeout(android.content.ComponentName);
method public int getPasswordHistoryLength(android.content.ComponentName);
@@ -5674,20 +5701,24 @@ package android.app.admin {
method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
method public boolean resetPassword(java.lang.String, int);
+ method public void sendDeviceInitializerStatus(int, java.lang.String);
method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void setAutoTimeRequired(android.content.ComponentName, boolean);
+ method public void setBluetoothContactSharingDisabled(android.content.ComponentName, boolean);
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
method public boolean setDeviceInitializer(android.content.ComponentName, android.content.ComponentName, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
+ method public boolean setKeyguardEnabledState(android.content.ComponentName, boolean);
method public void setLockTaskPackages(android.content.ComponentName, java.lang.String[]) throws java.lang.SecurityException;
method public void setMasterVolumeMuted(android.content.ComponentName, boolean);
method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
method public void setMaximumTimeToLock(android.content.ComponentName, long);
+ method public void setOtaPolicy(android.content.ComponentName, android.app.admin.OtaPolicy);
method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
method public void setPasswordHistoryLength(android.content.ComponentName, int);
method public void setPasswordMinimumLength(android.content.ComponentName, int);
@@ -5717,6 +5748,7 @@ package android.app.admin {
method public void wipeData(int);
field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
+ field public static final java.lang.String ACTION_OTA_POLICY_CHANGED = "android.app.action.OTA_POLICY_CHANGED";
field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE";
field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
@@ -5784,6 +5816,23 @@ package android.app.admin {
field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
}
+ public class OtaPolicy {
+ ctor public OtaPolicy();
+ method public int getInstallWindowEnd();
+ method public int getInstallWindowStart();
+ method public int getPolicyType();
+ method public void setAutomaticInstallPolicy();
+ method public void setPostponeInstallPolicy();
+ method public void setWindowedInstallPolicy(int, int) throws android.app.admin.OtaPolicy.InvalidWindowException;
+ field public static final int TYPE_INSTALL_AUTOMATIC = 1; // 0x1
+ field public static final int TYPE_INSTALL_WINDOWED = 2; // 0x2
+ field public static final int TYPE_POSTPONE = 3; // 0x3
+ }
+
+ public static class OtaPolicy.InvalidWindowException extends java.lang.Exception {
+ ctor public OtaPolicy.InvalidWindowException(java.lang.String);
+ }
+
}
package android.app.backup {
@@ -8132,6 +8181,7 @@ package android.content {
field public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list";
field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
+ field public static final java.lang.String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
field public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";
@@ -14774,7 +14824,7 @@ package android.media {
method public static float getMaxVolume();
method public static int getMinBufferSize(int, int, int);
method public static float getMinVolume();
- method protected deprecated int getNativeFrameCount();
+ method public int getNativeFrameCount() throws java.lang.IllegalStateException;
method public static int getNativeOutputSampleRate(int);
method public int getNotificationMarkerPosition();
method public int getPlayState();
@@ -15159,6 +15209,7 @@ package android.media {
method public android.media.MediaCodecInfo.AudioCapabilities getAudioCapabilities();
method public android.media.MediaFormat getDefaultFormat();
method public android.media.MediaCodecInfo.EncoderCapabilities getEncoderCapabilities();
+ method public int getMaxSupportedInstances();
method public java.lang.String getMimeType();
method public android.media.MediaCodecInfo.VideoCapabilities getVideoCapabilities();
method public final boolean isFeatureRequired(java.lang.String);
@@ -18028,6 +18079,7 @@ package android.net {
}
public final class IpPrefix implements android.os.Parcelable {
+ method public boolean contains(java.net.InetAddress);
method public int describeContents();
method public java.net.InetAddress getAddress();
method public int getPrefixLength();
@@ -23427,7 +23479,7 @@ package android.os {
method public android.os.Bundle getApplicationRestrictions(java.lang.String);
method public long getSerialNumberForUser(android.os.UserHandle);
method public int getUserCount();
- method public long getUserCreationTime(int);
+ method public long getUserCreationTime(android.os.UserHandle);
method public android.os.UserHandle getUserForSerialNumber(long);
method public java.lang.String getUserName();
method public java.util.List<android.os.UserHandle> getUserProfiles();
@@ -28036,6 +28088,43 @@ package android.sax {
package android.security {
+ public class CryptoOperationException extends java.lang.RuntimeException {
+ ctor public CryptoOperationException();
+ ctor public CryptoOperationException(java.lang.String);
+ ctor public CryptoOperationException(java.lang.String, java.lang.Throwable);
+ ctor public CryptoOperationException(java.lang.Throwable);
+ }
+
+ public class EcIesParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+ method public int getDemCipherKeySize();
+ method public java.lang.String getDemCipherTransformation();
+ method public java.lang.String getDemMacAlgorithm();
+ method public int getDemMacKeySize();
+ method public java.lang.String getKemKdfAlgorithm();
+ method public int getKemPointFormat();
+ field public static final android.security.EcIesParameterSpec DEFAULT;
+ }
+
+ public static class EcIesParameterSpec.Builder {
+ ctor public EcIesParameterSpec.Builder();
+ method public android.security.EcIesParameterSpec build();
+ method public android.security.EcIesParameterSpec.Builder setDemCipherKeySize(int);
+ method public android.security.EcIesParameterSpec.Builder setDemCipherTransformation(java.lang.String);
+ method public android.security.EcIesParameterSpec.Builder setDemMacAlgorithm(java.lang.String);
+ method public android.security.EcIesParameterSpec.Builder setDemMacKeySize(int);
+ method public android.security.EcIesParameterSpec.Builder setKemKdfAlgorithm(java.lang.String);
+ method public android.security.EcIesParameterSpec.Builder setKemPointFormat(int);
+ }
+
+ public static abstract class EcIesParameterSpec.PointFormat {
+ field public static final int COMPRESSED = 1; // 0x1
+ field public static final int UNCOMPRESSED = 0; // 0x0
+ field public static final int UNSPECIFIED = -1; // 0xffffffff
+ }
+
+ public static abstract class EcIesParameterSpec.PointFormatEnum implements java.lang.annotation.Annotation {
+ }
+
public final class KeyChain {
ctor public KeyChain();
method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int, java.lang.String);
@@ -28062,17 +28151,77 @@ package android.security {
ctor public KeyChainException(java.lang.Throwable);
}
+ public class KeyExpiredException extends android.security.CryptoOperationException {
+ ctor public KeyExpiredException();
+ ctor public KeyExpiredException(java.lang.String);
+ ctor public KeyExpiredException(java.lang.String, java.lang.Throwable);
+ }
+
+ public class KeyGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
+ method public java.lang.String[] getBlockModes();
+ method public android.content.Context getContext();
+ method public java.lang.String[] getEncryptionPaddings();
+ method public int getKeySize();
+ method public java.util.Date getKeyValidityForConsumptionEnd();
+ method public java.util.Date getKeyValidityForOriginationEnd();
+ method public java.util.Date getKeyValidityStart();
+ method public java.lang.String getKeystoreAlias();
+ method public int getPurposes();
+ method public int getUserAuthenticationValidityDurationSeconds();
+ method public int getUserAuthenticators();
+ method public boolean isEncryptionRequired();
+ method public boolean isInvalidatedOnNewFingerprintEnrolled();
+ method public boolean isRandomizedEncryptionRequired();
+ }
+
+ public static class KeyGeneratorSpec.Builder {
+ ctor public KeyGeneratorSpec.Builder(android.content.Context);
+ method public android.security.KeyGeneratorSpec build();
+ method public android.security.KeyGeneratorSpec.Builder setAlias(java.lang.String);
+ method public android.security.KeyGeneratorSpec.Builder setBlockModes(java.lang.String...);
+ method public android.security.KeyGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
+ method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired(boolean);
+ method public android.security.KeyGeneratorSpec.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
+ method public android.security.KeyGeneratorSpec.Builder setKeySize(int);
+ method public android.security.KeyGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
+ method public android.security.KeyGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
+ method public android.security.KeyGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date);
+ method public android.security.KeyGeneratorSpec.Builder setKeyValidityStart(java.util.Date);
+ method public android.security.KeyGeneratorSpec.Builder setPurposes(int);
+ method public android.security.KeyGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean);
+ method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
+ method public android.security.KeyGeneratorSpec.Builder setUserAuthenticators(int);
+ }
+
+ public class KeyNotYetValidException extends android.security.CryptoOperationException {
+ ctor public KeyNotYetValidException();
+ ctor public KeyNotYetValidException(java.lang.String);
+ ctor public KeyNotYetValidException(java.lang.String, java.lang.Throwable);
+ }
+
public final class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec();
+ method public java.lang.String[] getBlockModes();
method public android.content.Context getContext();
+ method public java.lang.String[] getDigests();
+ method public java.lang.String[] getEncryptionPaddings();
method public java.util.Date getEndDate();
method public int getKeySize();
method public java.lang.String getKeyType();
+ method public java.util.Date getKeyValidityForConsumptionEnd();
+ method public java.util.Date getKeyValidityForOriginationEnd();
+ method public java.util.Date getKeyValidityStart();
method public java.lang.String getKeystoreAlias();
+ method public int getPurposes();
method public java.math.BigInteger getSerialNumber();
+ method public java.lang.String[] getSignaturePaddings();
method public java.util.Date getStartDate();
method public javax.security.auth.x500.X500Principal getSubjectDN();
+ method public int getUserAuthenticationValidityDurationSeconds();
+ method public int getUserAuthenticators();
method public boolean isEncryptionRequired();
+ method public boolean isInvalidatedOnNewFingerprintEnrolled();
+ method public boolean isRandomizedEncryptionRequired();
}
public static final class KeyPairGeneratorSpec.Builder {
@@ -28080,23 +28229,110 @@ package android.security {
method public android.security.KeyPairGeneratorSpec build();
method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String);
+ method public android.security.KeyPairGeneratorSpec.Builder setBlockModes(java.lang.String...);
+ method public android.security.KeyPairGeneratorSpec.Builder setDigests(java.lang.String...);
+ method public android.security.KeyPairGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired();
method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int);
method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException;
+ method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityStart(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setPurposes(int);
+ method public android.security.KeyPairGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean);
method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger);
+ method public android.security.KeyPairGeneratorSpec.Builder setSignaturePaddings(java.lang.String...);
method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
+ method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
+ method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticators(int);
+ }
+
+ public abstract class KeyStoreKeyProperties {
+ }
+
+ public static abstract class KeyStoreKeyProperties.Origin {
+ field public static final int GENERATED = 1; // 0x1
+ field public static final int IMPORTED = 2; // 0x2
+ }
+
+ public static abstract class KeyStoreKeyProperties.OriginEnum implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class KeyStoreKeyProperties.Purpose {
+ field public static final int DECRYPT = 2; // 0x2
+ field public static final int ENCRYPT = 1; // 0x1
+ field public static final int SIGN = 4; // 0x4
+ field public static final int VERIFY = 8; // 0x8
+ }
+
+ public static abstract class KeyStoreKeyProperties.PurposeEnum implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class KeyStoreKeyProperties.UserAuthenticator {
+ field public static final int FINGERPRINT_READER = 2; // 0x2
+ field public static final int LOCK_SCREEN = 1; // 0x1
+ }
+
+ public static abstract class KeyStoreKeyProperties.UserAuthenticatorEnum implements java.lang.annotation.Annotation {
+ }
+
+ public class KeyStoreKeySpec implements java.security.spec.KeySpec {
+ method public java.lang.String[] getBlockModes();
+ method public java.lang.String[] getDigests();
+ method public java.lang.String[] getEncryptionPaddings();
+ method public int getKeySize();
+ method public java.util.Date getKeyValidityForConsumptionEnd();
+ method public java.util.Date getKeyValidityForOriginationEnd();
+ method public java.util.Date getKeyValidityStart();
+ method public java.lang.String getKeystoreAlias();
+ method public int getOrigin();
+ method public int getPurposes();
+ method public java.lang.String[] getSignaturePaddings();
+ method public int getTeeEnforcedUserAuthenticators();
+ method public int getUserAuthenticationValidityDurationSeconds();
+ method public int getUserAuthenticators();
+ method public boolean isInvalidatedOnNewFingerprintEnrolled();
+ method public boolean isTeeBacked();
}
public final class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter {
+ method public java.lang.String[] getBlockModes();
+ method public java.lang.String[] getDigests();
+ method public java.lang.String[] getEncryptionPaddings();
+ method public java.util.Date getKeyValidityForConsumptionEnd();
+ method public java.util.Date getKeyValidityForOriginationEnd();
+ method public java.util.Date getKeyValidityStart();
+ method public int getPurposes();
+ method public java.lang.String[] getSignaturePaddings();
+ method public int getUserAuthenticationValidityDurationSeconds();
+ method public int getUserAuthenticators();
+ method public boolean isDigestsSpecified();
method public boolean isEncryptionRequired();
+ method public boolean isInvalidatedOnNewFingerprintEnrolled();
+ method public boolean isRandomizedEncryptionRequired();
}
public static final class KeyStoreParameter.Builder {
ctor public KeyStoreParameter.Builder(android.content.Context);
method public android.security.KeyStoreParameter build();
+ method public android.security.KeyStoreParameter.Builder setBlockModes(java.lang.String...);
+ method public android.security.KeyStoreParameter.Builder setDigests(java.lang.String...);
+ method public android.security.KeyStoreParameter.Builder setEncryptionPaddings(java.lang.String...);
method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean);
+ method public android.security.KeyStoreParameter.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
+ method public android.security.KeyStoreParameter.Builder setKeyValidityEnd(java.util.Date);
+ method public android.security.KeyStoreParameter.Builder setKeyValidityForConsumptionEnd(java.util.Date);
+ method public android.security.KeyStoreParameter.Builder setKeyValidityForOriginationEnd(java.util.Date);
+ method public android.security.KeyStoreParameter.Builder setKeyValidityStart(java.util.Date);
+ method public android.security.KeyStoreParameter.Builder setPurposes(int);
+ method public android.security.KeyStoreParameter.Builder setRandomizedEncryptionRequired(boolean);
+ method public android.security.KeyStoreParameter.Builder setSignaturePaddings(java.lang.String...);
+ method public android.security.KeyStoreParameter.Builder setUserAuthenticationValidityDurationSeconds(int);
+ method public android.security.KeyStoreParameter.Builder setUserAuthenticators(int);
}
public class NetworkSecurityPolicy {
@@ -28104,6 +28340,17 @@ package android.security {
method public boolean isCleartextTrafficPermitted();
}
+ public class NewFingerprintEnrolledException extends android.security.CryptoOperationException {
+ ctor public NewFingerprintEnrolledException();
+ ctor public NewFingerprintEnrolledException(java.lang.String);
+ }
+
+ public class UserNotAuthenticatedException extends android.security.CryptoOperationException {
+ ctor public UserNotAuthenticatedException();
+ ctor public UserNotAuthenticatedException(java.lang.String);
+ ctor public UserNotAuthenticatedException(java.lang.String, java.lang.Throwable);
+ }
+
}
package android.service.carrier {
@@ -28163,8 +28410,10 @@ package android.service.chooser {
public final class ChooserTarget implements android.os.Parcelable {
ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.app.PendingIntent);
ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.content.IntentSender);
+ ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.content.Intent);
method public int describeContents();
method public android.graphics.Bitmap getIcon();
+ method public android.content.Intent getIntent();
method public android.content.IntentSender getIntentSender();
method public float getScore();
method public java.lang.CharSequence getTitle();
@@ -28177,6 +28426,8 @@ package android.service.chooser {
ctor public ChooserTargetService();
method public android.os.IBinder onBind(android.content.Intent);
method public abstract java.util.List<android.service.chooser.ChooserTarget> onGetChooserTargets(android.content.ComponentName, android.content.IntentFilter);
+ field public static final java.lang.String BIND_PERMISSION = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
+ field public static final java.lang.String META_DATA_NAME = "android.service.chooser.chooser_target_service";
field public static final java.lang.String SERVICE_INTERFACE = "android.service.chooser.ChooserTargetService";
}
@@ -28214,6 +28465,7 @@ package android.service.dreams {
method public boolean onMenuOpened(int, android.view.Menu);
method public void onPanelClosed(int, android.view.Menu);
method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
+ method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method public void onWakeUp();
method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
@@ -34556,6 +34808,10 @@ package android.view {
method public void onScaleEnd(android.view.ScaleGestureDetector);
}
+ public class SearchEvent {
+ method public android.view.InputDevice getInputDevice();
+ }
+
public class SoundEffectConstants {
method public static int getContantForFocusDirection(int);
field public static final int CLICK = 0; // 0x0
@@ -35608,10 +35864,10 @@ package android.view {
method public int indexOfChild(android.view.View);
method public final void invalidateChild(android.view.View, android.graphics.Rect);
method public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
- method public boolean isAlwaysDrawnWithCacheEnabled();
- method public boolean isAnimationCacheEnabled();
+ method public deprecated boolean isAlwaysDrawnWithCacheEnabled();
+ method public deprecated boolean isAnimationCacheEnabled();
method protected boolean isChildrenDrawingOrderEnabled();
- method protected boolean isChildrenDrawnWithCacheEnabled();
+ method protected deprecated boolean isChildrenDrawnWithCacheEnabled();
method public boolean isMotionEventSplittingEnabled();
method public boolean isTransitionGroup();
method public final void layout(int, int, int, int);
@@ -35650,11 +35906,11 @@ package android.view {
method public void requestTransparentRegion(android.view.View);
method public void scheduleLayoutAnimation();
method public void setAddStatesFromChildren(boolean);
- method public void setAlwaysDrawnWithCacheEnabled(boolean);
- method public void setAnimationCacheEnabled(boolean);
+ method public deprecated void setAlwaysDrawnWithCacheEnabled(boolean);
+ method public deprecated void setAnimationCacheEnabled(boolean);
method protected void setChildrenDrawingCacheEnabled(boolean);
method protected void setChildrenDrawingOrderEnabled(boolean);
- method protected void setChildrenDrawnWithCacheEnabled(boolean);
+ method protected deprecated void setChildrenDrawnWithCacheEnabled(boolean);
method public void setClipChildren(boolean);
method public void setClipToPadding(boolean);
method public void setDescendantFocusability(int);
@@ -36078,6 +36334,7 @@ package android.view {
method public abstract void onPanelClosed(int, android.view.Menu);
method public abstract boolean onPreparePanel(int, android.view.View, android.view.Menu);
method public abstract boolean onSearchRequested();
+ method public abstract boolean onSearchRequested(android.view.SearchEvent);
method public abstract void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
method public abstract void onWindowFocusChanged(boolean);
method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback);
diff --git a/api/system-current.txt b/api/system-current.txt
index ee076c2..1a28546 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3435,6 +3435,7 @@ package android.app {
method public android.content.SharedPreferences getPreferences(int);
method public android.net.Uri getReferrer();
method public int getRequestedOrientation();
+ method public final android.view.SearchEvent getSearchEvent();
method public int getTaskId();
method public final java.lang.CharSequence getTitle();
method public final int getTitleColor();
@@ -3519,6 +3520,7 @@ package android.app {
method public deprecated java.lang.Object onRetainNonConfigurationInstance();
method protected void onSaveInstanceState(android.os.Bundle);
method public void onSaveInstanceState(android.os.Bundle, android.os.PersistableBundle);
+ method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method protected void onStart();
method protected void onStop();
@@ -4203,6 +4205,7 @@ package android.app {
method public android.view.View getCurrentFocus();
method public android.view.LayoutInflater getLayoutInflater();
method public final android.app.Activity getOwnerActivity();
+ method public final android.view.SearchEvent getSearchEvent();
method public final int getVolumeControlStream();
method public android.view.Window getWindow();
method public void hide();
@@ -4236,6 +4239,7 @@ package android.app {
method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
method public void onRestoreInstanceState(android.os.Bundle);
method public android.os.Bundle onSaveInstanceState();
+ method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method protected void onStart();
method protected void onStop();
@@ -4683,6 +4687,7 @@ package android.app {
method public deprecated void exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult);
method public boolean inKeyguardRestrictedInputMode();
method public boolean isDeviceLocked();
+ method public boolean isDeviceSecure();
method public boolean isKeyguardLocked();
method public boolean isKeyguardSecure();
method public deprecated android.app.KeyguardManager.KeyguardLock newKeyguardLock(java.lang.String);
@@ -5706,6 +5711,26 @@ package android.app.admin {
field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
}
+ public class DeviceInitializerStatus {
+ method public static boolean isCustomStatus(int);
+ method public static boolean isErrorStatus(int);
+ method public static boolean isHighPriority(int);
+ field public static final int FLAG_STATUS_CUSTOM = 33554432; // 0x2000000
+ field public static final int FLAG_STATUS_ERROR = 16777216; // 0x1000000
+ field public static final int FLAG_STATUS_HIGH_PRIORITY = 134217728; // 0x8000000
+ field public static final int FLAG_STATUS_RESERVED = 67108864; // 0x4000000
+ field public static final int STATUS_ERROR_CONNECT_WIFI = 16777237; // 0x1000015
+ field public static final int STATUS_ERROR_DELETE_APPS = 16777242; // 0x100001a
+ field public static final int STATUS_ERROR_DOUBLE_BUMP = 16777246; // 0x100001e
+ field public static final int STATUS_ERROR_DOWNLOAD_PACKAGE = 16777239; // 0x1000017
+ field public static final int STATUS_ERROR_INSTALL_PACKAGE = 16777240; // 0x1000018
+ field public static final int STATUS_ERROR_RESET_PROTECTION_BLOCKING_PROVISIONING = 16777238; // 0x1000016
+ field public static final int STATUS_ERROR_SET_DEVICE_POLICY = 16777241; // 0x1000019
+ field public static final int STATUS_STATE_CONNECT_BLUETOOTH_PROXY = 134217736; // 0x8000008
+ field public static final int STATUS_STATE_DEVICE_PROVISIONED = 134217738; // 0x800000a
+ field public static final int STATUS_STATE_DISCONNECT_BLUETOOTH_PROXY = 134217737; // 0x8000009
+ }
+
public class DevicePolicyManager {
method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -5725,6 +5750,7 @@ package android.app.admin {
method public java.util.List<android.content.ComponentName> getActiveAdmins();
method public android.os.Bundle getApplicationRestrictions(android.content.ComponentName, java.lang.String);
method public boolean getAutoTimeRequired();
+ method public boolean getBluetoothContactSharingDisabled(android.content.ComponentName);
method public boolean getCameraDisabled(android.content.ComponentName);
method public java.lang.String getCertInstallerPackage(android.content.ComponentName) throws java.lang.SecurityException;
method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
@@ -5737,6 +5763,7 @@ package android.app.admin {
method public int getKeyguardDisabledFeatures(android.content.ComponentName);
method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
method public long getMaximumTimeToLock(android.content.ComponentName);
+ method public android.app.admin.OtaPolicy getOtaPolicy();
method public long getPasswordExpiration(android.content.ComponentName);
method public long getPasswordExpirationTimeout(android.content.ComponentName);
method public int getPasswordHistoryLength(android.content.ComponentName);
@@ -5777,21 +5804,25 @@ package android.app.admin {
method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
method public boolean resetPassword(java.lang.String, int);
+ method public void sendDeviceInitializerStatus(int, java.lang.String);
method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
method public deprecated boolean setActiveProfileOwner(android.content.ComponentName, java.lang.String) throws java.lang.IllegalArgumentException;
method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void setAutoTimeRequired(android.content.ComponentName, boolean);
+ method public void setBluetoothContactSharingDisabled(android.content.ComponentName, boolean);
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
method public boolean setDeviceInitializer(android.content.ComponentName, android.content.ComponentName, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
+ method public boolean setKeyguardEnabledState(android.content.ComponentName, boolean);
method public void setLockTaskPackages(android.content.ComponentName, java.lang.String[]) throws java.lang.SecurityException;
method public void setMasterVolumeMuted(android.content.ComponentName, boolean);
method public void setMaximumFailedPasswordsForWipe(android.content.ComponentName, int);
method public void setMaximumTimeToLock(android.content.ComponentName, long);
+ method public void setOtaPolicy(android.content.ComponentName, android.app.admin.OtaPolicy);
method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
method public void setPasswordHistoryLength(android.content.ComponentName, int);
method public void setPasswordMinimumLength(android.content.ComponentName, int);
@@ -5821,7 +5852,9 @@ package android.app.admin {
method public void wipeData(int);
field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
+ field public static final java.lang.String ACTION_OTA_POLICY_CHANGED = "android.app.action.OTA_POLICY_CHANGED";
field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE";
+ field public static final java.lang.String ACTION_SEND_DEVICE_INITIALIZER_STATUS = "android.app.action.SEND_DEVICE_INITIALIZER_STATUS";
field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
field public static final java.lang.String ACTION_SET_PROFILE_OWNER = "android.app.action.SET_PROFILE_OWNER";
field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
@@ -5832,6 +5865,8 @@ package android.app.admin {
field public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0; // 0x0
field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION";
field public static final java.lang.String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
+ field public static final java.lang.String EXTRA_DEVICE_INITIALIZER_STATUS_CODE = "android.app.extra.DEVICE_INITIALIZER_STATUS_CODE";
+ field public static final java.lang.String EXTRA_DEVICE_INITIALIZER_STATUS_DESCRIPTION = "android.app.extra.DEVICE_INITIALIZER_STATUS_DESCRIPTION";
field public static final java.lang.String EXTRA_PROFILE_OWNER_NAME = "android.app.extra.PROFILE_OWNER_NAME";
field public static final java.lang.String EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE = "android.app.extra.PROVISIONING_ACCOUNT_TO_MIGRATE";
field public static final java.lang.String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE = "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
@@ -5890,6 +5925,23 @@ package android.app.admin {
field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
}
+ public class OtaPolicy {
+ ctor public OtaPolicy();
+ method public int getInstallWindowEnd();
+ method public int getInstallWindowStart();
+ method public int getPolicyType();
+ method public void setAutomaticInstallPolicy();
+ method public void setPostponeInstallPolicy();
+ method public void setWindowedInstallPolicy(int, int) throws android.app.admin.OtaPolicy.InvalidWindowException;
+ field public static final int TYPE_INSTALL_AUTOMATIC = 1; // 0x1
+ field public static final int TYPE_INSTALL_WINDOWED = 2; // 0x2
+ field public static final int TYPE_POSTPONE = 3; // 0x3
+ }
+
+ public static class OtaPolicy.InvalidWindowException extends java.lang.Exception {
+ ctor public OtaPolicy.InvalidWindowException(java.lang.String);
+ }
+
}
package android.app.backup {
@@ -8355,6 +8407,7 @@ package android.content {
field public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list";
field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
+ field public static final java.lang.String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
field public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";
@@ -15983,7 +16036,7 @@ package android.media {
method public static float getMaxVolume();
method public static int getMinBufferSize(int, int, int);
method public static float getMinVolume();
- method protected deprecated int getNativeFrameCount();
+ method public int getNativeFrameCount() throws java.lang.IllegalStateException;
method public static int getNativeOutputSampleRate(int);
method public int getNotificationMarkerPosition();
method public int getPlayState();
@@ -16368,6 +16421,7 @@ package android.media {
method public android.media.MediaCodecInfo.AudioCapabilities getAudioCapabilities();
method public android.media.MediaFormat getDefaultFormat();
method public android.media.MediaCodecInfo.EncoderCapabilities getEncoderCapabilities();
+ method public int getMaxSupportedInstances();
method public java.lang.String getMimeType();
method public android.media.MediaCodecInfo.VideoCapabilities getVideoCapabilities();
method public final boolean isFeatureRequired(java.lang.String);
@@ -19479,6 +19533,7 @@ package android.net {
}
public final class IpPrefix implements android.os.Parcelable {
+ method public boolean contains(java.net.InetAddress);
method public int describeContents();
method public java.net.InetAddress getAddress();
method public int getPrefixLength();
@@ -25319,7 +25374,7 @@ package android.os {
method public android.os.Bundle getApplicationRestrictions(java.lang.String);
method public long getSerialNumberForUser(android.os.UserHandle);
method public int getUserCount();
- method public long getUserCreationTime(int);
+ method public long getUserCreationTime(android.os.UserHandle);
method public android.os.UserHandle getUserForSerialNumber(long);
method public java.lang.String getUserName();
method public java.util.List<android.os.UserHandle> getUserProfiles();
@@ -28969,7 +29024,6 @@ package android.provider {
public static final class VoicemailContract.Status implements android.provider.BaseColumns {
method public static android.net.Uri buildSourceUri(java.lang.String);
- method public static void setStatus(android.content.Context, android.telecom.PhoneAccountHandle, int, int, int);
field public static final java.lang.String CONFIGURATION_STATE = "configuration_state";
field public static final int CONFIGURATION_STATE_CAN_BE_CONFIGURED = 2; // 0x2
field public static final int CONFIGURATION_STATE_NOT_CONFIGURED = 1; // 0x1
@@ -28993,9 +29047,6 @@ package android.provider {
public static final class VoicemailContract.Voicemails implements android.provider.BaseColumns android.provider.OpenableColumns {
method public static android.net.Uri buildSourceUri(java.lang.String);
- method public static int deleteAll(android.content.Context);
- method public static android.net.Uri insert(android.content.Context, android.telecom.Voicemail);
- method public static int insert(android.content.Context, java.util.List<android.telecom.Voicemail>);
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String DATE = "date";
field public static final java.lang.String DELETED = "deleted";
@@ -30036,6 +30087,43 @@ package android.sax {
package android.security {
+ public class CryptoOperationException extends java.lang.RuntimeException {
+ ctor public CryptoOperationException();
+ ctor public CryptoOperationException(java.lang.String);
+ ctor public CryptoOperationException(java.lang.String, java.lang.Throwable);
+ ctor public CryptoOperationException(java.lang.Throwable);
+ }
+
+ public class EcIesParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+ method public int getDemCipherKeySize();
+ method public java.lang.String getDemCipherTransformation();
+ method public java.lang.String getDemMacAlgorithm();
+ method public int getDemMacKeySize();
+ method public java.lang.String getKemKdfAlgorithm();
+ method public int getKemPointFormat();
+ field public static final android.security.EcIesParameterSpec DEFAULT;
+ }
+
+ public static class EcIesParameterSpec.Builder {
+ ctor public EcIesParameterSpec.Builder();
+ method public android.security.EcIesParameterSpec build();
+ method public android.security.EcIesParameterSpec.Builder setDemCipherKeySize(int);
+ method public android.security.EcIesParameterSpec.Builder setDemCipherTransformation(java.lang.String);
+ method public android.security.EcIesParameterSpec.Builder setDemMacAlgorithm(java.lang.String);
+ method public android.security.EcIesParameterSpec.Builder setDemMacKeySize(int);
+ method public android.security.EcIesParameterSpec.Builder setKemKdfAlgorithm(java.lang.String);
+ method public android.security.EcIesParameterSpec.Builder setKemPointFormat(int);
+ }
+
+ public static abstract class EcIesParameterSpec.PointFormat {
+ field public static final int COMPRESSED = 1; // 0x1
+ field public static final int UNCOMPRESSED = 0; // 0x0
+ field public static final int UNSPECIFIED = -1; // 0xffffffff
+ }
+
+ public static abstract class EcIesParameterSpec.PointFormatEnum implements java.lang.annotation.Annotation {
+ }
+
public final class KeyChain {
ctor public KeyChain();
method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int, java.lang.String);
@@ -30062,17 +30150,77 @@ package android.security {
ctor public KeyChainException(java.lang.Throwable);
}
+ public class KeyExpiredException extends android.security.CryptoOperationException {
+ ctor public KeyExpiredException();
+ ctor public KeyExpiredException(java.lang.String);
+ ctor public KeyExpiredException(java.lang.String, java.lang.Throwable);
+ }
+
+ public class KeyGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
+ method public java.lang.String[] getBlockModes();
+ method public android.content.Context getContext();
+ method public java.lang.String[] getEncryptionPaddings();
+ method public int getKeySize();
+ method public java.util.Date getKeyValidityForConsumptionEnd();
+ method public java.util.Date getKeyValidityForOriginationEnd();
+ method public java.util.Date getKeyValidityStart();
+ method public java.lang.String getKeystoreAlias();
+ method public int getPurposes();
+ method public int getUserAuthenticationValidityDurationSeconds();
+ method public int getUserAuthenticators();
+ method public boolean isEncryptionRequired();
+ method public boolean isInvalidatedOnNewFingerprintEnrolled();
+ method public boolean isRandomizedEncryptionRequired();
+ }
+
+ public static class KeyGeneratorSpec.Builder {
+ ctor public KeyGeneratorSpec.Builder(android.content.Context);
+ method public android.security.KeyGeneratorSpec build();
+ method public android.security.KeyGeneratorSpec.Builder setAlias(java.lang.String);
+ method public android.security.KeyGeneratorSpec.Builder setBlockModes(java.lang.String...);
+ method public android.security.KeyGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
+ method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired(boolean);
+ method public android.security.KeyGeneratorSpec.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
+ method public android.security.KeyGeneratorSpec.Builder setKeySize(int);
+ method public android.security.KeyGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
+ method public android.security.KeyGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
+ method public android.security.KeyGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date);
+ method public android.security.KeyGeneratorSpec.Builder setKeyValidityStart(java.util.Date);
+ method public android.security.KeyGeneratorSpec.Builder setPurposes(int);
+ method public android.security.KeyGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean);
+ method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
+ method public android.security.KeyGeneratorSpec.Builder setUserAuthenticators(int);
+ }
+
+ public class KeyNotYetValidException extends android.security.CryptoOperationException {
+ ctor public KeyNotYetValidException();
+ ctor public KeyNotYetValidException(java.lang.String);
+ ctor public KeyNotYetValidException(java.lang.String, java.lang.Throwable);
+ }
+
public final class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec();
+ method public java.lang.String[] getBlockModes();
method public android.content.Context getContext();
+ method public java.lang.String[] getDigests();
+ method public java.lang.String[] getEncryptionPaddings();
method public java.util.Date getEndDate();
method public int getKeySize();
method public java.lang.String getKeyType();
+ method public java.util.Date getKeyValidityForConsumptionEnd();
+ method public java.util.Date getKeyValidityForOriginationEnd();
+ method public java.util.Date getKeyValidityStart();
method public java.lang.String getKeystoreAlias();
+ method public int getPurposes();
method public java.math.BigInteger getSerialNumber();
+ method public java.lang.String[] getSignaturePaddings();
method public java.util.Date getStartDate();
method public javax.security.auth.x500.X500Principal getSubjectDN();
+ method public int getUserAuthenticationValidityDurationSeconds();
+ method public int getUserAuthenticators();
method public boolean isEncryptionRequired();
+ method public boolean isInvalidatedOnNewFingerprintEnrolled();
+ method public boolean isRandomizedEncryptionRequired();
}
public static final class KeyPairGeneratorSpec.Builder {
@@ -30080,23 +30228,110 @@ package android.security {
method public android.security.KeyPairGeneratorSpec build();
method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String);
+ method public android.security.KeyPairGeneratorSpec.Builder setBlockModes(java.lang.String...);
+ method public android.security.KeyPairGeneratorSpec.Builder setDigests(java.lang.String...);
+ method public android.security.KeyPairGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired();
method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int);
method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException;
+ method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityStart(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setPurposes(int);
+ method public android.security.KeyPairGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean);
method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger);
+ method public android.security.KeyPairGeneratorSpec.Builder setSignaturePaddings(java.lang.String...);
method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
+ method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
+ method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticators(int);
+ }
+
+ public abstract class KeyStoreKeyProperties {
+ }
+
+ public static abstract class KeyStoreKeyProperties.Origin {
+ field public static final int GENERATED = 1; // 0x1
+ field public static final int IMPORTED = 2; // 0x2
+ }
+
+ public static abstract class KeyStoreKeyProperties.OriginEnum implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class KeyStoreKeyProperties.Purpose {
+ field public static final int DECRYPT = 2; // 0x2
+ field public static final int ENCRYPT = 1; // 0x1
+ field public static final int SIGN = 4; // 0x4
+ field public static final int VERIFY = 8; // 0x8
+ }
+
+ public static abstract class KeyStoreKeyProperties.PurposeEnum implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class KeyStoreKeyProperties.UserAuthenticator {
+ field public static final int FINGERPRINT_READER = 2; // 0x2
+ field public static final int LOCK_SCREEN = 1; // 0x1
+ }
+
+ public static abstract class KeyStoreKeyProperties.UserAuthenticatorEnum implements java.lang.annotation.Annotation {
+ }
+
+ public class KeyStoreKeySpec implements java.security.spec.KeySpec {
+ method public java.lang.String[] getBlockModes();
+ method public java.lang.String[] getDigests();
+ method public java.lang.String[] getEncryptionPaddings();
+ method public int getKeySize();
+ method public java.util.Date getKeyValidityForConsumptionEnd();
+ method public java.util.Date getKeyValidityForOriginationEnd();
+ method public java.util.Date getKeyValidityStart();
+ method public java.lang.String getKeystoreAlias();
+ method public int getOrigin();
+ method public int getPurposes();
+ method public java.lang.String[] getSignaturePaddings();
+ method public int getTeeEnforcedUserAuthenticators();
+ method public int getUserAuthenticationValidityDurationSeconds();
+ method public int getUserAuthenticators();
+ method public boolean isInvalidatedOnNewFingerprintEnrolled();
+ method public boolean isTeeBacked();
}
public final class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter {
+ method public java.lang.String[] getBlockModes();
+ method public java.lang.String[] getDigests();
+ method public java.lang.String[] getEncryptionPaddings();
+ method public java.util.Date getKeyValidityForConsumptionEnd();
+ method public java.util.Date getKeyValidityForOriginationEnd();
+ method public java.util.Date getKeyValidityStart();
+ method public int getPurposes();
+ method public java.lang.String[] getSignaturePaddings();
+ method public int getUserAuthenticationValidityDurationSeconds();
+ method public int getUserAuthenticators();
+ method public boolean isDigestsSpecified();
method public boolean isEncryptionRequired();
+ method public boolean isInvalidatedOnNewFingerprintEnrolled();
+ method public boolean isRandomizedEncryptionRequired();
}
public static final class KeyStoreParameter.Builder {
ctor public KeyStoreParameter.Builder(android.content.Context);
method public android.security.KeyStoreParameter build();
+ method public android.security.KeyStoreParameter.Builder setBlockModes(java.lang.String...);
+ method public android.security.KeyStoreParameter.Builder setDigests(java.lang.String...);
+ method public android.security.KeyStoreParameter.Builder setEncryptionPaddings(java.lang.String...);
method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean);
+ method public android.security.KeyStoreParameter.Builder setInvalidatedOnNewFingerprintEnrolled(boolean);
+ method public android.security.KeyStoreParameter.Builder setKeyValidityEnd(java.util.Date);
+ method public android.security.KeyStoreParameter.Builder setKeyValidityForConsumptionEnd(java.util.Date);
+ method public android.security.KeyStoreParameter.Builder setKeyValidityForOriginationEnd(java.util.Date);
+ method public android.security.KeyStoreParameter.Builder setKeyValidityStart(java.util.Date);
+ method public android.security.KeyStoreParameter.Builder setPurposes(int);
+ method public android.security.KeyStoreParameter.Builder setRandomizedEncryptionRequired(boolean);
+ method public android.security.KeyStoreParameter.Builder setSignaturePaddings(java.lang.String...);
+ method public android.security.KeyStoreParameter.Builder setUserAuthenticationValidityDurationSeconds(int);
+ method public android.security.KeyStoreParameter.Builder setUserAuthenticators(int);
}
public class NetworkSecurityPolicy {
@@ -30104,6 +30339,17 @@ package android.security {
method public boolean isCleartextTrafficPermitted();
}
+ public class NewFingerprintEnrolledException extends android.security.CryptoOperationException {
+ ctor public NewFingerprintEnrolledException();
+ ctor public NewFingerprintEnrolledException(java.lang.String);
+ }
+
+ public class UserNotAuthenticatedException extends android.security.CryptoOperationException {
+ ctor public UserNotAuthenticatedException();
+ ctor public UserNotAuthenticatedException(java.lang.String);
+ ctor public UserNotAuthenticatedException(java.lang.String, java.lang.Throwable);
+ }
+
}
package android.service.carrier {
@@ -30163,8 +30409,10 @@ package android.service.chooser {
public final class ChooserTarget implements android.os.Parcelable {
ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.app.PendingIntent);
ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.content.IntentSender);
+ ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.content.Intent);
method public int describeContents();
method public android.graphics.Bitmap getIcon();
+ method public android.content.Intent getIntent();
method public android.content.IntentSender getIntentSender();
method public float getScore();
method public java.lang.CharSequence getTitle();
@@ -30177,6 +30425,8 @@ package android.service.chooser {
ctor public ChooserTargetService();
method public android.os.IBinder onBind(android.content.Intent);
method public abstract java.util.List<android.service.chooser.ChooserTarget> onGetChooserTargets(android.content.ComponentName, android.content.IntentFilter);
+ field public static final java.lang.String BIND_PERMISSION = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
+ field public static final java.lang.String META_DATA_NAME = "android.service.chooser.chooser_target_service";
field public static final java.lang.String SERVICE_INTERFACE = "android.service.chooser.ChooserTargetService";
}
@@ -30214,6 +30464,7 @@ package android.service.dreams {
method public boolean onMenuOpened(int, android.view.Menu);
method public void onPanelClosed(int, android.view.Menu);
method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
+ method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method public void onWakeUp();
method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
@@ -37178,6 +37429,10 @@ package android.view {
method public void onScaleEnd(android.view.ScaleGestureDetector);
}
+ public class SearchEvent {
+ method public android.view.InputDevice getInputDevice();
+ }
+
public class SoundEffectConstants {
method public static int getContantForFocusDirection(int);
field public static final int CLICK = 0; // 0x0
@@ -38230,10 +38485,10 @@ package android.view {
method public int indexOfChild(android.view.View);
method public final void invalidateChild(android.view.View, android.graphics.Rect);
method public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
- method public boolean isAlwaysDrawnWithCacheEnabled();
- method public boolean isAnimationCacheEnabled();
+ method public deprecated boolean isAlwaysDrawnWithCacheEnabled();
+ method public deprecated boolean isAnimationCacheEnabled();
method protected boolean isChildrenDrawingOrderEnabled();
- method protected boolean isChildrenDrawnWithCacheEnabled();
+ method protected deprecated boolean isChildrenDrawnWithCacheEnabled();
method public boolean isMotionEventSplittingEnabled();
method public boolean isTransitionGroup();
method public final void layout(int, int, int, int);
@@ -38272,11 +38527,11 @@ package android.view {
method public void requestTransparentRegion(android.view.View);
method public void scheduleLayoutAnimation();
method public void setAddStatesFromChildren(boolean);
- method public void setAlwaysDrawnWithCacheEnabled(boolean);
- method public void setAnimationCacheEnabled(boolean);
+ method public deprecated void setAlwaysDrawnWithCacheEnabled(boolean);
+ method public deprecated void setAnimationCacheEnabled(boolean);
method protected void setChildrenDrawingCacheEnabled(boolean);
method protected void setChildrenDrawingOrderEnabled(boolean);
- method protected void setChildrenDrawnWithCacheEnabled(boolean);
+ method protected deprecated void setChildrenDrawnWithCacheEnabled(boolean);
method public void setClipChildren(boolean);
method public void setClipToPadding(boolean);
method public void setDescendantFocusability(int);
@@ -38701,6 +38956,7 @@ package android.view {
method public abstract void onPanelClosed(int, android.view.Menu);
method public abstract boolean onPreparePanel(int, android.view.View, android.view.Menu);
method public abstract boolean onSearchRequested();
+ method public abstract boolean onSearchRequested(android.view.SearchEvent);
method public abstract void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
method public abstract void onWindowFocusChanged(boolean);
method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback);
diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java
index df5a4cb..224e8e9 100644
--- a/core/java/android/animation/AnimatorInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -698,7 +698,7 @@ public class AnimatorInflater {
int ordering = a.getInt(R.styleable.AnimatorSet_ordering, TOGETHER);
createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering,
pixelSize);
- final int hint = a.getInt(R.styleable.Animator_durationScaleHint,
+ final int hint = a.getInt(R.styleable.AnimatorSet_durationScaleHint,
HINT_NO_SCALE);
anim.setDurationScaleHint(hint, res);
a.recycle();
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a0d59d9..6cf6481 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -89,6 +89,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.PhoneWindow;
+import android.view.SearchEvent;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
@@ -787,6 +788,8 @@ public class Activity extends ContextThemeWrapper
private TranslucentConversionListener mTranslucentCallback;
private boolean mChangeCanvasToTranslucent;
+ private SearchEvent mSearchEvent;
+
private boolean mTitleReady = false;
private int mActionModeTypeStarting = ActionMode.TYPE_PRIMARY;
@@ -3547,12 +3550,23 @@ public class Activity extends ContextThemeWrapper
* implementation changes to simply return false and you must supply your own custom
* implementation if you want to support search.</p>
*
+ * @param searchEvent The {@link SearchEvent} that signaled this search.
* @return Returns {@code true} if search launched, and {@code false} if the activity does
* not respond to search. The default implementation always returns {@code true}, except
* when in {@link Configuration#UI_MODE_TYPE_TELEVISION} mode where it returns false.
*
* @see android.app.SearchManager
*/
+ public boolean onSearchRequested(@Nullable SearchEvent searchEvent) {
+ mSearchEvent = searchEvent;
+ boolean result = onSearchRequested();
+ mSearchEvent = null;
+ return result;
+ }
+
+ /**
+ * @see #onSearchRequested(SearchEvent)
+ */
public boolean onSearchRequested() {
if ((getResources().getConfiguration().uiMode&Configuration.UI_MODE_TYPE_MASK)
!= Configuration.UI_MODE_TYPE_TELEVISION) {
@@ -3564,6 +3578,17 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * During the onSearchRequested() callbacks, this function will return the
+ * {@link SearchEvent} that triggered the callback, if it exists.
+ *
+ * @return SearchEvent The SearchEvent that triggered the {@link
+ * #onSearchRequested} callback.
+ */
+ public final SearchEvent getSearchEvent() {
+ return mSearchEvent;
+ }
+
+ /**
* This hook is called to launch the search UI.
*
* <p>It is typically called from onSearchRequested(), either directly from
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 83451aa..8fb048b 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -1368,7 +1368,6 @@ final class BackStackRecord extends FragmentTransaction implements
public boolean onPreDraw() {
sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
if (enterTransition != null) {
- enterTransition.removeTarget(nonExistingView);
removeTargets(enterTransition, enteringViews);
}
if (exitTransition != null) {
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 786a52f..d049104 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -49,6 +49,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.PhoneWindow;
+import android.view.SearchEvent;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
@@ -123,6 +124,8 @@ public class Dialog implements DialogInterface, Window.Callback,
private Handler mListenersHandler;
+ private SearchEvent mSearchEvent;
+
private ActionMode mActionMode;
private int mActionModeTypeStarting = ActionMode.TYPE_PRIMARY;
@@ -995,6 +998,14 @@ public class Dialog implements DialogInterface, Window.Callback,
/**
* This hook is called when the user signals the desire to start a search.
*/
+ public boolean onSearchRequested(SearchEvent searchEvent) {
+ mSearchEvent = searchEvent;
+ return onSearchRequested();
+ }
+
+ /**
+ * This hook is called when the user signals the desire to start a search.
+ */
public boolean onSearchRequested() {
final SearchManager searchManager = (SearchManager) mContext
.getSystemService(Context.SEARCH_SERVICE);
@@ -1011,6 +1022,17 @@ public class Dialog implements DialogInterface, Window.Callback,
}
/**
+ * During the onSearchRequested() callbacks, this function will return the
+ * {@link SearchEvent} that triggered the callback, if it exists.
+ *
+ * @return SearchEvent The SearchEvent that triggered the {@link
+ * #onSearchRequested} callback.
+ */
+ public final SearchEvent getSearchEvent() {
+ return mSearchEvent;
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
diff --git a/core/java/android/app/IUserSwitchObserver.aidl b/core/java/android/app/IUserSwitchObserver.aidl
index 845897b..caee14f 100644
--- a/core/java/android/app/IUserSwitchObserver.aidl
+++ b/core/java/android/app/IUserSwitchObserver.aidl
@@ -22,4 +22,5 @@ import android.os.IRemoteCallback;
oneway interface IUserSwitchObserver {
void onUserSwitching(int newUserId, IRemoteCallback reply);
void onUserSwitchComplete(int newUserId);
+ void onForegroundProfileSwitch(int newProfileId);
}
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index ddd21e6..56cd53e 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -253,6 +253,32 @@ public class KeyguardManager {
}
/**
+ * Returns whether the device is secured with a PIN, pattern or
+ * password.
+ *
+ * @return true if a PIN, pattern or password was set.
+ */
+ public boolean isDeviceSecure() {
+ return isDeviceSecure(UserHandle.getCallingUserId());
+ }
+
+ /**
+ * Returns whether the device is secured with a PIN, pattern or
+ * password.
+ *
+ * @param userId the user for which the secure state should be reported.
+ * @return true if a PIN, pattern or password was set.
+ * @hide
+ */
+ public boolean isDeviceSecure(int userId) {
+ try {
+ return mTrustManager.isDeviceSecure(userId);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
* @deprecated Use {@link android.view.WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD}
* and/or {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED}
* instead; this allows you to seamlessly hide the keyguard as your application
diff --git a/core/java/android/app/SharedElementCallback.java b/core/java/android/app/SharedElementCallback.java
index e58b7fb..bac84a4 100644
--- a/core/java/android/app/SharedElementCallback.java
+++ b/core/java/android/app/SharedElementCallback.java
@@ -51,9 +51,23 @@ public abstract class SharedElementCallback {
};
/**
- * Called immediately after the start state is set for the shared element.
- * The shared element will start at the size and position of the shared element
- * in the launching Activity or Fragment.
+ * In Activity Transitions, onSharedElementStart is called immediately before
+ * capturing the start of the shared element state on enter and reenter transitions and
+ * immediately before capturing the end of the shared element state for exit and return
+ * transitions.
+ * <p>
+ * In Fragment Transitions, onSharedElementStart is called immediately before capturing the
+ * start state of all shared element transitions.
+ * <p>
+ * This call can be used to adjust the transition start state by modifying the shared
+ * element Views. Note that no layout step will be executed between onSharedElementStart
+ * and the transition state capture.
+ * <p>
+ * For Activity Transitions, any changes made in {@link #onSharedElementEnd(List, List, List)}
+ * that are not updated during by layout should be corrected in onSharedElementStart for exit and
+ * return transitions. For example, rotation or scale will not be affected by layout and
+ * if changed in {@link #onSharedElementEnd(List, List, List)}, it will also have to be reset
+ * in onSharedElementStart again to correct the end state.
*
* @param sharedElementNames The names of the shared elements that were accepted into
* the View hierarchy.
@@ -68,17 +82,23 @@ public abstract class SharedElementCallback {
List<View> sharedElements, List<View> sharedElementSnapshots) {}
/**
- * Called after the end state is set for the shared element, but before the end state
- * is captured by the shared element transition.
+ * In Activity Transitions, onSharedElementEnd is called immediately before
+ * capturing the end of the shared element state on enter and reenter transitions and
+ * immediately before capturing the start of the shared element state for exit and return
+ * transitions.
* <p>
- * Any customization done in
- * {@link #onSharedElementStart(java.util.List, java.util.List, java.util.List)}
- * may need to be modified to the final state of the shared element if it is not
- * automatically corrected by layout. For example, rotation or scale will not
- * be affected by layout and if changed in {@link #onSharedElementStart(java.util.List,
- * java.util.List, java.util.List)}, it will also have to be set here again to correct
- * the end state.
- * </p>
+ * In Fragment Transitions, onSharedElementEnd is called immediately before capturing the
+ * end state of all shared element transitions.
+ * <p>
+ * This call can be used to adjust the transition end state by modifying the shared
+ * element Views. Note that no layout step will be executed between onSharedElementEnd
+ * and the transition state capture.
+ * <p>
+ * Any changes made in {@link #onSharedElementStart(List, List, List)} that are not updated
+ * during layout should be corrected in onSharedElementEnd. For example, rotation or scale
+ * will not be affected by layout and if changed in
+ * {@link #onSharedElementStart(List, List, List)}, it will also have to be reset in
+ * onSharedElementEnd again to correct the end state.
*
* @param sharedElementNames The names of the shared elements that were accepted into
* the View hierarchy.
diff --git a/core/java/android/app/admin/DeviceInitializerStatus.java b/core/java/android/app/admin/DeviceInitializerStatus.java
new file mode 100644
index 0000000..b58711c
--- /dev/null
+++ b/core/java/android/app/admin/DeviceInitializerStatus.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+/**
+ * Defines constants designating device provisioning status used with {@link
+ * android.app.admin.DevicePolicyManager#sendDeviceInitializerStatus(int,String)}.
+ *
+ * This class contains flag constants that define special status codes:
+ * <ul>
+ * <li>{@link #FLAG_STATUS_ERROR} is used to define provisioning error status codes
+ * <li>{@link #FLAG_STATUS_CUSTOM} is used to define custom status codes
+ * <li>{@link #FLAG_STATUS_HIGH_PRIORITY} is used to define high priority status codes
+ * </ul>
+ *
+ * <p>Status codes used by ManagedProvisioning are also defined in this class. These status codes
+ * include provisioning errors and status codes.
+ * <ul>
+ * <li>{@link #STATUS_ERROR_CONNECT_WIFI}
+ * <li>{@link #STATUS_ERROR_RESET_PROTECTION_BLOCKING_PROVISIONING}
+ * <li>{@link #STATUS_ERROR_DOWNLOAD_PACKAGE}
+ * <li>{@link #STATUS_ERROR_INSTALL_PACKAGE}
+ * <li>{@link #STATUS_ERROR_SET_DEVICE_POLICY}
+ * <li>{@link #STATUS_ERROR_DELETE_APPS}
+ * <li>{@link #STATUS_ERROR_DOUBLE_BUMP}
+ * <li>{@link #STATUS_STATE_CONNECT_BLUETOOTH_PROXY}
+ * <li>{@link #STATUS_STATE_DISCONNECT_BLUETOOTH_PROXY}
+ * <li>{@link #STATUS_STATE_DEVICE_PROVISIONED}
+ * </ul>
+ */
+public class DeviceInitializerStatus {
+ /**
+ * A flag used to designate an error status.
+ *
+ * <p>This flag is used with {@code statusCode} values sent through
+ * {@link android.app.admin.DevicePolicyManager#sendDeviceInitializerStatus(int,String)}
+ * @see #isErrorStatus(int)
+ */
+ public static final int FLAG_STATUS_ERROR = 0x01000000;
+
+ /**
+ * A flag used to designate a custom status. Custom status codes will be defined by device
+ * initializer agents.
+ *
+ * <p>This flag is used with {@code statusCode} values sent through
+ * {@link android.app.admin.DevicePolicyManager#sendDeviceInitializerStatus(int,String)}
+ * @see #isCustomStatus(int)
+ */
+ public static final int FLAG_STATUS_CUSTOM = 0x02000000;
+
+ /**
+ * A bit flag used to designate a reserved status. Reserved status codes will not be defined
+ * in AOSP.
+ *
+ * <p>This flag is used with {@code statusCode} values sent through
+ * {@link android.app.admin.DevicePolicyManager#sendDeviceInitializerStatus(int,String)}
+ */
+ public static final int FLAG_STATUS_RESERVED = 0x04000000;
+
+ /**
+ * A flag used to indicate that a status message is high priority.
+ *
+ * <p>This flag is used with {@code statusCode} values sent through
+ * {@link android.app.admin.DevicePolicyManager#sendDeviceInitializerStatus(int,String)}
+ * @see #isHighPriority(int)
+ */
+ public static final int FLAG_STATUS_HIGH_PRIORITY = 0x08000000;
+
+ /**
+ * Device provisioning status code that indicates that a device is connecting to establish
+ * a Bluetooth network proxy.
+ */
+ public static final int STATUS_STATE_CONNECT_BLUETOOTH_PROXY = FLAG_STATUS_HIGH_PRIORITY | 8;
+
+ /**
+ * Device provisioning status code that indicates that a connected Bluetooth network proxy
+ * is being shut down.
+ */
+ public static final int STATUS_STATE_DISCONNECT_BLUETOOTH_PROXY = FLAG_STATUS_HIGH_PRIORITY | 9;
+
+ /**
+ * Device provisioning status code that indicates that a device has been successfully
+ * provisioned.
+ */
+ public static final int STATUS_STATE_DEVICE_PROVISIONED = FLAG_STATUS_HIGH_PRIORITY | 10;
+
+ /**
+ * Device provisioning error status code that indicates that a device could not connect to
+ * a Wi-Fi network.
+ */
+ public static final int STATUS_ERROR_CONNECT_WIFI = FLAG_STATUS_ERROR | 21;
+
+ /**
+ * Device provisioning error status indicating that factory reset protection is enabled on
+ * the provisioned device and cannot be disabled with the provided data.
+ */
+ public static final int STATUS_ERROR_RESET_PROTECTION_BLOCKING_PROVISIONING =
+ FLAG_STATUS_ERROR | 22;
+
+ /**
+ * Device provisioning error status indicating that device administrator and device initializer
+ * packages could not be downloaded and verified successfully.
+ */
+ public static final int STATUS_ERROR_DOWNLOAD_PACKAGE = FLAG_STATUS_ERROR | 23;
+
+ /**
+ * Device provisioning error status indicating that device owner and device initializer packages
+ * could not be installed.
+ */
+ public static final int STATUS_ERROR_INSTALL_PACKAGE = FLAG_STATUS_ERROR | 24;
+
+ /**
+ * Device provisioning error status indicating that the device owner or device initializer
+ * components could not be set.
+ */
+ public static final int STATUS_ERROR_SET_DEVICE_POLICY = FLAG_STATUS_ERROR | 25;
+
+ /**
+ * Device provisioning error status indicating that deleting non-required applications during
+ * provisioning failed.
+ */
+ public static final int STATUS_ERROR_DELETE_APPS = FLAG_STATUS_ERROR | 26;
+
+ /**
+ * Device provisioning error status code that indicates that a provisioning attempt has failed
+ * because the device has already been provisioned or that provisioning has already started.
+ */
+ public static final int STATUS_ERROR_DOUBLE_BUMP = FLAG_STATUS_ERROR | 30;
+
+ /**
+ * Determine if the specified status code represents an error status.
+ * @param statusCode status code to check
+ * @return {@code true} if the status code is an error status code
+ */
+ public static boolean isErrorStatus(int statusCode) {
+ return isFlagSet(statusCode, FLAG_STATUS_ERROR);
+ }
+
+ /**
+ * Determine if the specified status code is a custom status. Custom status codes are defined
+ * and sent by device initialization agents.
+ * @param statusCode status code to check
+ * @return {@code true} if the status code is a custom status code
+ */
+ public static boolean isCustomStatus(int statusCode) {
+ return isFlagSet(statusCode, FLAG_STATUS_CUSTOM);
+ }
+
+ /**
+ * Determine if the specified status code is a high priority status code.
+ * @param statusCode status code to check
+ * @return {@code true} if the status code is a high priority status code
+ */
+ public static boolean isHighPriority(int statusCode) {
+ return isFlagSet(statusCode, FLAG_STATUS_HIGH_PRIORITY);
+ }
+
+ private static boolean isFlagSet(int statusCode, int flag) {
+ return (statusCode & flag) != 0;
+ }
+
+ private DeviceInitializerStatus() {}
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 68f4707..a0a6c4c 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -651,6 +651,45 @@ public class DevicePolicyManager {
= "android.app.action.SET_PROFILE_OWNER";
/**
+ * Protected broadcast action that will be sent to managed provisioning to notify it that a
+ * status update has been reported by the device initializer. The status update will be
+ * reported to the remote setup device over Bluetooth.
+ *
+ * <p>Broadcasts with this action must supply a
+ * {@linkplain DeviceInitializerStatus#isCustomStatus(int) custom} status code in the
+ * {@link EXTRA_DEVICE_INITIALIZER_STATUS_CODE} extra.
+ *
+ * <p>Broadcasts may optionally contain a description in the
+ * {@link EXTRA_DEVICE_INITIALIZER_STATUS_DESCRIPTION} extra.
+ * @hide
+ */
+ @SystemApi
+ public static final String ACTION_SEND_DEVICE_INITIALIZER_STATUS
+ = "android.app.action.SEND_DEVICE_INITIALIZER_STATUS";
+
+ /**
+ * An integer extra that contains the status code that defines a status update. This extra must
+ * sent as part of a broadcast with an action of {@code ACTION_SEND_DEVICE_INITIALIZER_STATUS}.
+ *
+ * <p>The status code sent with this extra must be a custom status code as defined by
+ * {@link DeviceInitializerStatus#isCustomStatus(int)}.
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_DEVICE_INITIALIZER_STATUS_CODE
+ = "android.app.extra.DEVICE_INITIALIZER_STATUS_CODE";
+
+ /**
+ * A {@code String} extra that contains an optional description accompanying a status update.
+ * This extra my be sent as part of a broadcast with an action of
+ * {@code ACTION_SEND_DEVICE_INITIALIZER_STATUS}.
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_DEVICE_INITIALIZER_STATUS_DESCRIPTION
+ = "android.app.extra.DEVICE_INITIALIZER_STATUS_DESCRIPTION";
+
+ /**
* @hide
* Name of the profile owner admin that controls the user.
*/
@@ -715,6 +754,14 @@ public class DevicePolicyManager {
public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 0x0002;
/**
+ * Broadcast action: notify that a new local OTA policy has been set by the device owner.
+ * The new policy can be retrieved by {@link #getOtaPolicy()}.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_OTA_POLICY_CHANGED = "android.app.action.OTA_POLICY_CHANGED";
+
+
+ /**
* Return true if the given administrator component is currently
* active (enabled) in the system.
*/
@@ -2170,7 +2217,8 @@ public class DevicePolicyManager {
* Called by a device or profile owner to install a certificate and private key pair. The
* keypair will be visible to all apps within the profile.
*
- * @param who Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param who Which {@link DeviceAdminReceiver} this request is associated with. Use
+ * <code>null</code> if calling from a delegated certificate installer.
* @param privKey The private key to install.
* @param cert The certificate to install.
* @param alias The private key alias under which to install the certificate. If a certificate
@@ -2207,9 +2255,9 @@ public class DevicePolicyManager {
/**
* Called by a profile owner or device owner to grant access to privileged certificate
- * manipulation APIs to a third-party CA certificate installer app. Granted APIs include
+ * manipulation APIs to a third-party certificate installer app. Granted APIs include
* {@link #getInstalledCaCerts}, {@link #hasCaCertInstalled}, {@link #installCaCert},
- * {@link #uninstallCaCert} and {@link #uninstallAllUserCaCerts}.
+ * {@link #uninstallCaCert}, {@link #uninstallAllUserCaCerts} and {@link #installKeyPair}.
* <p>
* Delegated certificate installer is a per-user state. The delegated access is persistent until
* it is later cleared by calling this method with a null value or uninstallling the certificate
@@ -3214,6 +3262,73 @@ public class DevicePolicyManager {
}
/**
+ * Called by a profile owner of a managed profile to set whether bluetooth
+ * devices can access enterprise contacts.
+ * <p>
+ * The calling device admin must be a profile owner. If it is not, a
+ * security exception will be thrown.
+ * <p>
+ * This API works on managed profile only.
+ *
+ * @param who Which {@link DeviceAdminReceiver} this request is associated
+ * with.
+ * @param disabled If true, bluetooth devices cannot access enterprise
+ * contacts.
+ */
+ public void setBluetoothContactSharingDisabled(ComponentName who, boolean disabled) {
+ if (mService != null) {
+ try {
+ mService.setBluetoothContactSharingDisabled(who, disabled);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ }
+
+ /**
+ * Called by a profile owner of a managed profile to determine whether or
+ * not Bluetooth devices cannot access enterprise contacts.
+ * <p>
+ * The calling device admin must be a profile owner. If it is not, a
+ * security exception will be thrown.
+ * <p>
+ * This API works on managed profile only.
+ *
+ * @param who Which {@link DeviceAdminReceiver} this request is associated
+ * with.
+ */
+ public boolean getBluetoothContactSharingDisabled(ComponentName who) {
+ if (mService != null) {
+ try {
+ return mService.getBluetoothContactSharingDisabled(who);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Determine whether or not Bluetooth devices cannot access contacts.
+ * <p>
+ * This API works on managed profile UserHandle only.
+ *
+ * @param userHandle The user for whom to check the caller-id permission
+ * @hide
+ */
+ public boolean getBluetoothContactSharingDisabled(UserHandle userHandle) {
+ if (mService != null) {
+ try {
+ return mService.getBluetoothContactSharingDisabledForUser(userHandle
+ .getIdentifier());
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ return true;
+ }
+
+ /**
* Called by the profile owner of a managed profile so that some intents sent in the managed
* profile can also be resolved in the parent, or vice versa.
* Only activity intents are supported.
@@ -4012,4 +4127,87 @@ public class DevicePolicyManager {
Log.w(TAG, "Could not set the user icon ", re);
}
}
+
+ /**
+ * Called by device initializer to send a provisioning status update to the remote setup device.
+ *
+ * @param statusCode a custom status code value as defined by
+ * {@link DeviceInitializerStatus#isCustomStatus(int)}.
+ * @param description custom description of the status code sent
+ */
+ public void sendDeviceInitializerStatus(int statusCode, String description) {
+ try {
+ mService.sendDeviceInitializerStatus(statusCode, description);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Could not send device initializer status", re);
+ }
+ }
+
+ /*
+ * Called by device owners to set a local OTA update policy. When a new OTA policy is set,
+ * {@link #ACTION_OTA_POLICY_CHANGED} is broadcasted.
+ *
+ * @param who Which {@link DeviceAdminReceiver} this request is associated with. All components
+ * in the device owner package can set OTA policies and the most recent policy takes effect.
+ * @param policy the new OTA policy, or null to clear the current policy.
+ * @see OtaPolicy
+ */
+ public void setOtaPolicy(ComponentName who, OtaPolicy policy) {
+ if (mService != null) {
+ try {
+ if (policy != null) {
+ mService.setOtaPolicy(who, policy.getPolicyBundle());
+ } else {
+ mService.setOtaPolicy(who, null);
+ }
+ } catch (RemoteException re) {
+ Log.w(TAG, "Error calling setOtaPolicy", re);
+ }
+ }
+ }
+
+ /**
+ * Retrieve a local OTA update policy set previously by {@link #setOtaPolicy}.
+ *
+ * @return The current OTA policy object, or null if no policy is set or the system does not
+ * support managed OTA.
+ */
+ public OtaPolicy getOtaPolicy() {
+ if (mService != null) {
+ try {
+ PersistableBundle bundle = mService.getOtaPolicy();
+ if (bundle != null) {
+ return new OtaPolicy(bundle);
+ } else {
+ return null;
+ }
+ } catch (RemoteException re) {
+ Log.w(TAG, "Error calling getOtaPolicy", re);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Called by a device owner to disable the keyguard altogether.
+ *
+ * <p>Setting the keyguard to disabled has the same effect as choosing "None" as the screen
+ * lock type. However, this call has no effect if a password, pin or pattern is currently set.
+ * If a password, pin or pattern is set after the keyguard was disabled, the keyguard stops
+ * being disabled.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param enabled New state of the keyguard.
+ *
+ * @return {@code false} if attempting to disable the keyguard while a lock password was in
+ * place. {@code true} otherwise."
+ */
+ public boolean setKeyguardEnabledState(ComponentName admin, boolean enabled) {
+ try {
+ return mService.setKeyguardEnabledState(admin, enabled);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Failed talking with device policy service", re);
+ return false;
+ }
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index c68311e..131b99c 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -191,6 +191,10 @@ interface IDevicePolicyManager {
boolean getCrossProfileCallerIdDisabledForUser(int userId);
void startManagedQuickContact(String lookupKey, long contactId, in Intent originalIntent);
+ void setBluetoothContactSharingDisabled(in ComponentName who, boolean disabled);
+ boolean getBluetoothContactSharingDisabled(in ComponentName who);
+ boolean getBluetoothContactSharingDisabledForUser(int userId);
+
void setTrustAgentConfiguration(in ComponentName admin, in ComponentName agent,
in PersistableBundle args);
List<PersistableBundle> getTrustAgentConfiguration(in ComponentName admin,
@@ -213,4 +217,10 @@ interface IDevicePolicyManager {
ComponentName getDeviceInitializerComponent();
void setUserIcon(in ComponentName admin, in Bitmap icon);
+
+ void sendDeviceInitializerStatus(int statusCode, String description);
+ void setOtaPolicy(in ComponentName who, in PersistableBundle policy);
+ PersistableBundle getOtaPolicy();
+
+ boolean setKeyguardEnabledState(in ComponentName admin, boolean enabled);
}
diff --git a/core/java/android/app/admin/OtaPolicy.java b/core/java/android/app/admin/OtaPolicy.java
new file mode 100644
index 0000000..98581a7
--- /dev/null
+++ b/core/java/android/app/admin/OtaPolicy.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.IntDef;
+import android.os.PersistableBundle;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A class that represents a local OTA policy set by the device owner.
+ *
+ * @see DevicePolicyManager#setOtaPolicy
+ * @see DevicePolicyManager#getOtaPolicy
+ */
+public class OtaPolicy {
+
+ /** @hide */
+ @IntDef({
+ TYPE_INSTALL_AUTOMATIC,
+ TYPE_INSTALL_WINDOWED,
+ TYPE_POSTPONE})
+ @Retention(RetentionPolicy.SOURCE)
+ @interface OtaPolicyType {}
+
+ /**
+ * Install OTA update automatically as soon as one is available.
+ */
+ public static final int TYPE_INSTALL_AUTOMATIC = 1;
+
+ /**
+ * Install OTA update automatically within a daily maintenance window, for a maximum of two-week
+ * period. After that period the OTA will be installed automatically.
+ */
+ public static final int TYPE_INSTALL_WINDOWED = 2;
+
+ /**
+ * Incoming OTA will be blocked for a maximum of two weeks, after which it will be installed
+ * automatically.
+ */
+ public static final int TYPE_POSTPONE = 3;
+
+ private static final String KEY_POLICY_TYPE = "policy_type";
+ private static final String KEY_INSTALL_WINDOW_START = "install_window_start";
+ private static final String KEY_INSTALL_WINDOW_END = "install_window_end";
+
+ private PersistableBundle mPolicy;
+
+ public OtaPolicy() {
+ mPolicy = new PersistableBundle();
+ }
+
+ /**
+ * Construct an OtaPolicy object from a bundle.
+ * @hide
+ */
+ public OtaPolicy(PersistableBundle in) {
+ mPolicy = new PersistableBundle(in);
+ }
+
+ /**
+ * Retrieve the underlying bundle where the policy is stored.
+ * @hide
+ */
+ public PersistableBundle getPolicyBundle() {
+ return new PersistableBundle(mPolicy);
+ }
+
+ /**
+ * Set the OTA policy to: install OTA update automatically as soon as one is available.
+ */
+ public void setAutomaticInstallPolicy() {
+ mPolicy.clear();
+ mPolicy.putInt(KEY_POLICY_TYPE, TYPE_INSTALL_AUTOMATIC);
+ }
+
+ /**
+ * Set the OTA policy to: new OTA update will only be installed automatically when the system
+ * clock is inside a daily maintenance window. If the start and end times are the same, the
+ * window is considered to include the WHOLE 24 hours, that is, OTAs can install at any time. If
+ * the given window in invalid, a {@link OtaPolicy.InvalidWindowException} will be thrown. If
+ * start time is later than end time, the window is considered spanning midnight, i.e. end time
+ * donates a time on the next day. The maintenance window will last for two weeks, after which
+ * the OTA will be installed automatically.
+ *
+ * @param startTime the start of the maintenance window, measured as the number of minutes from
+ * midnight in the device's local time. Must be in the range of [0, 1440).
+ * @param endTime the end of the maintenance window, measured as the number of minutes from
+ * midnight in the device's local time. Must be in the range of [0, 1440).
+ */
+ public void setWindowedInstallPolicy(int startTime, int endTime) throws InvalidWindowException{
+ if (startTime < 0 || startTime >= 1440 || endTime < 0 || endTime >= 1440) {
+ throw new InvalidWindowException("startTime and endTime must be inside [0, 1440)");
+ }
+ mPolicy.clear();
+ mPolicy.putInt(KEY_POLICY_TYPE, TYPE_INSTALL_WINDOWED);
+ mPolicy.putInt(KEY_INSTALL_WINDOW_START, startTime);
+ mPolicy.putInt(KEY_INSTALL_WINDOW_END, endTime);
+ }
+
+ /**
+ * Set the OTA policy to: block installation for a maximum period of two weeks. After the
+ * block expires the OTA will be installed automatically.
+ */
+ public void setPostponeInstallPolicy() {
+ mPolicy.clear();
+ mPolicy.putInt(KEY_POLICY_TYPE, TYPE_POSTPONE);
+ }
+
+ /**
+ * Returns the type of OTA policy.
+ *
+ * @return an integer, either one of {@link #TYPE_INSTALL_AUTOMATIC},
+ * {@link #TYPE_INSTALL_WINDOWED} and {@link #TYPE_POSTPONE}, or -1 if no policy has been set.
+ */
+ @OtaPolicyType
+ public int getPolicyType() {
+ return mPolicy.getInt(KEY_POLICY_TYPE, -1);
+ }
+
+ /**
+ * Get the start of the maintenance window.
+ *
+ * @return the start of the maintenance window measured as the number of minutes from midnight,
+ * or -1 if the policy does not have a maintenance window.
+ */
+ public int getInstallWindowStart() {
+ if (getPolicyType() == TYPE_INSTALL_WINDOWED) {
+ return mPolicy.getInt(KEY_INSTALL_WINDOW_START, -1);
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Get the end of the maintenance window.
+ *
+ * @return the end of the maintenance window measured as the number of minutes from midnight,
+ * or -1 if the policy does not have a maintenance window.
+ */
+ public int getInstallWindowEnd() {
+ if (getPolicyType() == TYPE_INSTALL_WINDOWED) {
+ return mPolicy.getInt(KEY_INSTALL_WINDOW_END, -1);
+ } else {
+ return -1;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return mPolicy.toString();
+ }
+
+ /**
+ * Exception thrown by {@link OtaPolicy#setWindowedInstallPolicy(int, int)} in case the
+ * specified window is invalid.
+ */
+ public static class InvalidWindowException extends Exception {
+ public InvalidWindowException(String reason) {
+ super(reason);
+ }
+ }
+}
+
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index 1131ff9..9540eb1 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -399,6 +399,13 @@ public class BackupTransport {
* operation will be skipped (and {@link #finishBackup() invoked} with no data for that
* package being passed to {@link #sendBackupData}.
*
+ * <p class="note">The platform does no size-based rejection of full backup attempts on
+ * its own: it is always the responsibility of the transport to implement its own policy.
+ * In particular, even if the preflighted payload size is zero, the platform will still call
+ * this method and will proceed to back up an archive metadata header with no file content
+ * if this method returns TRANSPORT_OK. To avoid storing such payloads the transport
+ * must recognize this case and return TRANSPORT_PACKAGE_REJECTED.
+ *
* Added in MNC (API 23).
*
* @param size The estimated size of the full-data payload for this app. This includes
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index 68ea0aa..17cff5c 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -31,4 +31,5 @@ interface ITrustManager {
void unregisterTrustListener(in ITrustListener trustListener);
void reportKeyguardShowingChanged();
boolean isDeviceLocked(int userId);
+ boolean isDeviceSecure(int userId);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index eea47b7..54fe786 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3311,6 +3311,14 @@ public class Intent implements Parcelable, Cloneable {
public static final String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
/**
+ * A Parcelable[] of {@link android.service.chooser.ChooserTarget ChooserTarget} objects
+ * as set with {@link #putExtra(String, Parcelable[])} representing additional app-specific
+ * targets to place at the front of the list of choices. Shown to the user with
+ * {@link #ACTION_CHOOSER}.
+ */
+ public static final String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
+
+ /**
* A Bundle forming a mapping of potential target package names to different extras Bundles
* to add to the default intent extras in {@link #EXTRA_INTENT} when used with
* {@link #ACTION_CHOOSER}. Each key should be a package name. The package need not
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index f01c540..8f7aed4 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -639,7 +639,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>Whether the camera device supports {@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock}</p>
- * <p>LIMITED or FULL devices will always list <code>true</code></p>
+ * <p>Devices with MANUAL_SENSOR capability or BURST_CAPTURE capability will always
+ * list <code>true</code>. This includes FULL devices.</p>
* <p>This key is available on all devices.</p>
*
* @see CaptureRequest#CONTROL_AE_LOCK
@@ -650,7 +651,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
/**
* <p>Whether the camera device supports {@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock}</p>
- * <p>LIMITED or FULL devices will always list <code>true</code></p>
+ * <p>Devices with MANUAL_POST_PROCESSING capability or BURST_CAPTURE capability will
+ * always list <code>true</code>. This includes FULL devices.</p>
* <p>This key is available on all devices.</p>
*
* @see CaptureRequest#CONTROL_AWB_LOCK
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 2192ab7..4a5bd08 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -347,6 +347,10 @@ public abstract class CameraMetadata<TKey> {
* <li>{@link CaptureRequest#BLACK_LEVEL_LOCK android.blackLevel.lock}</li>
* </ul>
* </li>
+ * <li>Auto exposure lock<ul>
+ * <li>{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock}</li>
+ * </ul>
+ * </li>
* </ul>
* <p>If any of the above 3A algorithms are enabled, then the camera
* device will accurately report the values applied by 3A in the
@@ -358,6 +362,7 @@ public abstract class CameraMetadata<TKey> {
* zero for each supported size-format combination.</p>
*
* @see CaptureRequest#BLACK_LEVEL_LOCK
+ * @see CaptureRequest#CONTROL_AE_LOCK
* @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
* @see CaptureRequest#SENSOR_EXPOSURE_TIME
* @see CaptureRequest#SENSOR_FRAME_DURATION
@@ -403,6 +408,10 @@ public abstract class CameraMetadata<TKey> {
* <li>{@link CameraCharacteristics#COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES android.colorCorrection.availableAberrationModes}</li>
* </ul>
* </li>
+ * <li>Auto white balance lock<ul>
+ * <li>{@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock}</li>
+ * </ul>
+ * </li>
* </ul>
* <p>If auto white balance is enabled, then the camera device
* will accurately report the values applied by AWB in the result.</p>
@@ -413,6 +422,7 @@ public abstract class CameraMetadata<TKey> {
* @see CameraCharacteristics#COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES
* @see CaptureRequest#COLOR_CORRECTION_GAINS
* @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
+ * @see CaptureRequest#CONTROL_AWB_LOCK
* @see CaptureRequest#SHADING_MODE
* @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
* @see CaptureRequest#TONEMAP_CURVE
@@ -530,9 +540,15 @@ public abstract class CameraMetadata<TKey> {
* YUV_420_888 format.</p>
* </blockquote>
* <p>In addition, the {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} field is
- * guaranted to have a value between 0 and 4, inclusive.</p>
+ * guaranted to have a value between 0 and 4, inclusive.
+ * {@link CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE android.control.aeLockAvailable} and
+ * {@link CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE android.control.awbLockAvailable} are also guaranteed
+ * to be <code>true</code> so burst capture with these two locks ON
+ * yields consistent image output.</p>
*
* @see CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES
+ * @see CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE
+ * @see CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE
* @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
* @see CameraCharacteristics#SYNC_MAX_LATENCY
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
diff --git a/core/java/android/hardware/location/GeofenceHardwareImpl.java b/core/java/android/hardware/location/GeofenceHardwareImpl.java
index 4696b2a..5d40e94 100644
--- a/core/java/android/hardware/location/GeofenceHardwareImpl.java
+++ b/core/java/android/hardware/location/GeofenceHardwareImpl.java
@@ -53,6 +53,7 @@ public final class GeofenceHardwareImpl {
private IFusedGeofenceHardware mFusedService;
private IGpsGeofenceHardware mGpsService;
+ private int mCapabilities;
private int[] mSupportedMonitorTypes = new int[GeofenceHardware.NUM_MONITORS];
@@ -89,6 +90,9 @@ public final class GeofenceHardwareImpl {
private static final int RESOLUTION_LEVEL_COARSE = 2;
private static final int RESOLUTION_LEVEL_FINE = 3;
+ // Capability constant corresponding to fused_location.h entry when geofencing supports GNNS.
+ private static final int CAPABILITY_GNSS = 1;
+
public synchronized static GeofenceHardwareImpl getInstance(Context context) {
if (sInstance == null) {
sInstance = new GeofenceHardwareImpl(context);
@@ -141,7 +145,9 @@ public final class GeofenceHardwareImpl {
private void updateFusedHardwareAvailability() {
boolean fusedSupported;
try {
- fusedSupported = (mFusedService != null ? mFusedService.isSupported() : false);
+ fusedSupported = (mFusedService != null
+ ? mFusedService.isSupported() && (mCapabilities & CAPABILITY_GNSS) != 0
+ : false);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling LocationManagerService");
fusedSupported = false;
@@ -166,6 +172,11 @@ public final class GeofenceHardwareImpl {
}
}
+ public void onCapabilities(int capabilities) {
+ mCapabilities = capabilities;
+ updateFusedHardwareAvailability();
+ }
+
public void setFusedGeofenceHardware(IFusedGeofenceHardware service) {
if(mFusedService == null) {
mFusedService = service;
@@ -212,6 +223,20 @@ public final class GeofenceHardwareImpl {
}
}
+ public int getCapabilitiesForMonitoringType(int monitoringType) {
+ switch (mSupportedMonitorTypes[monitoringType]) {
+ case GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE:
+ switch (monitoringType) {
+ case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
+ return CAPABILITY_GNSS;
+ case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
+ return mCapabilities;
+ }
+ break;
+ }
+ return 0;
+ }
+
public boolean addCircularFence(
int monitoringType,
GeofenceHardwareRequestParcelable request,
diff --git a/core/java/android/hardware/location/GeofenceHardwareService.java b/core/java/android/hardware/location/GeofenceHardwareService.java
index 4816c5f..c0bcb27 100644
--- a/core/java/android/hardware/location/GeofenceHardwareService.java
+++ b/core/java/android/hardware/location/GeofenceHardwareService.java
@@ -65,14 +65,17 @@ public class GeofenceHardwareService extends Service {
}
private IBinder mBinder = new IGeofenceHardware.Stub() {
+ @Override
public void setGpsGeofenceHardware(IGpsGeofenceHardware service) {
mGeofenceHardwareImpl.setGpsHardwareGeofence(service);
}
+ @Override
public void setFusedGeofenceHardware(IFusedGeofenceHardware service) {
mGeofenceHardwareImpl.setFusedGeofenceHardware(service);
}
+ @Override
public int[] getMonitoringTypes() {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to access hardware geofence");
@@ -80,12 +83,15 @@ public class GeofenceHardwareService extends Service {
return mGeofenceHardwareImpl.getMonitoringTypes();
}
+ @Override
public int getStatusOfMonitoringType(int monitoringType) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to access hardware geofence");
return mGeofenceHardwareImpl.getStatusOfMonitoringType(monitoringType);
}
+
+ @Override
public boolean addCircularFence(
int monitoringType,
GeofenceHardwareRequestParcelable request,
@@ -96,6 +102,7 @@ public class GeofenceHardwareService extends Service {
return mGeofenceHardwareImpl.addCircularFence(monitoringType, request, callback);
}
+ @Override
public boolean removeGeofence(int id, int monitoringType) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to access hardware geofence");
@@ -104,6 +111,7 @@ public class GeofenceHardwareService extends Service {
return mGeofenceHardwareImpl.removeGeofence(id, monitoringType);
}
+ @Override
public boolean pauseGeofence(int id, int monitoringType) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to access hardware geofence");
@@ -112,6 +120,7 @@ public class GeofenceHardwareService extends Service {
return mGeofenceHardwareImpl.pauseGeofence(id, monitoringType);
}
+ @Override
public boolean resumeGeofence(int id, int monitoringType, int monitorTransitions) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to access hardware geofence");
@@ -120,6 +129,7 @@ public class GeofenceHardwareService extends Service {
return mGeofenceHardwareImpl.resumeGeofence(id, monitoringType, monitorTransitions);
}
+ @Override
public boolean registerForMonitorStateChangeCallback(int monitoringType,
IGeofenceHardwareMonitorCallback callback) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
@@ -130,6 +140,7 @@ public class GeofenceHardwareService extends Service {
callback);
}
+ @Override
public boolean unregisterForMonitorStateChangeCallback(int monitoringType,
IGeofenceHardwareMonitorCallback callback) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
diff --git a/core/java/android/hardware/location/IFusedLocationHardware.aidl b/core/java/android/hardware/location/IFusedLocationHardware.aidl
index 382c12c..3de766a 100644
--- a/core/java/android/hardware/location/IFusedLocationHardware.aidl
+++ b/core/java/android/hardware/location/IFusedLocationHardware.aidl
@@ -32,21 +32,21 @@ interface IFusedLocationHardware {
*
* @param eventSink The sink to register.
*/
- void registerSink(in IFusedLocationHardwareSink eventSink);
+ void registerSink(in IFusedLocationHardwareSink eventSink) = 0;
/**
* Unregisters a sink with the Location Hardware object.
*
* @param eventSink The sink to unregister.
*/
- void unregisterSink(in IFusedLocationHardwareSink eventSink);
+ void unregisterSink(in IFusedLocationHardwareSink eventSink) = 1;
/**
* Provides access to the batch size available in Hardware.
*
* @return The batch size the hardware supports.
*/
- int getSupportedBatchSize();
+ int getSupportedBatchSize() = 2;
/**
* Requests the Hardware to start batching locations.
@@ -56,7 +56,7 @@ interface IFusedLocationHardware {
*
* @throws RuntimeException if the request Id exists.
*/
- void startBatching(in int id, in FusedBatchOptions batchOptions);
+ void startBatching(in int id, in FusedBatchOptions batchOptions) = 3;
/**
* Requests the Hardware to stop batching for the given Id.
@@ -64,7 +64,7 @@ interface IFusedLocationHardware {
* @param id The request that needs to be stopped.
* @throws RuntimeException if the request Id is unknown.
*/
- void stopBatching(in int id);
+ void stopBatching(in int id) = 4;
/**
* Updates a batching operation in progress.
@@ -74,7 +74,7 @@ interface IFusedLocationHardware {
*
* @throws RuntimeException if the Id of the request is unknown.
*/
- void updateBatchingOptions(in int id, in FusedBatchOptions batchOptions);
+ void updateBatchingOptions(in int id, in FusedBatchOptions batchOptions) = 5;
/**
* Requests the most recent locations available in Hardware.
@@ -83,14 +83,14 @@ interface IFusedLocationHardware {
*
* @param batchSizeRequested The number of locations requested.
*/
- void requestBatchOfLocations(in int batchSizeRequested);
+ void requestBatchOfLocations(in int batchSizeRequested) = 6;
/**
* Flags if the Hardware supports injection of diagnostic data.
*
* @return True if data injection is supported, false otherwise.
*/
- boolean supportsDiagnosticDataInjection();
+ boolean supportsDiagnosticDataInjection() = 7;
/**
* Injects diagnostic data into the Hardware subsystem.
@@ -98,14 +98,14 @@ interface IFusedLocationHardware {
* @param data The data to inject.
* @throws RuntimeException if injection is not supported.
*/
- void injectDiagnosticData(in String data);
+ void injectDiagnosticData(in String data) = 8;
/**
* Flags if the Hardware supports injection of device context information.
*
* @return True if device context injection is supported, false otherwise.
*/
- boolean supportsDeviceContextInjection();
+ boolean supportsDeviceContextInjection() = 9;
/**
* Injects device context information into the Hardware subsystem.
@@ -113,5 +113,12 @@ interface IFusedLocationHardware {
* @param deviceEnabledContext The context to inject.
* @throws RuntimeException if injection is not supported.
*/
- void injectDeviceContext(in int deviceEnabledContext);
+ void injectDeviceContext(in int deviceEnabledContext) = 10;
+
+ /**
+ * Requests all batched locations currently available in Hardware
+ * and clears the buffer. Any subsequent calls will not return any
+ * of the locations returned in this call.
+ */
+ void flushBatchedLocations() = 11;
}
diff --git a/core/java/android/hardware/location/IFusedLocationHardwareSink.aidl b/core/java/android/hardware/location/IFusedLocationHardwareSink.aidl
index a11d8ab..c99cb0c 100644
--- a/core/java/android/hardware/location/IFusedLocationHardwareSink.aidl
+++ b/core/java/android/hardware/location/IFusedLocationHardwareSink.aidl
@@ -30,12 +30,24 @@ interface IFusedLocationHardwareSink {
*
* @param locations The batch of location information available.
*/
- void onLocationAvailable(in Location[] locations);
+ void onLocationAvailable(in Location[] locations) = 0;
/**
* Event generated from FLP HAL to provide diagnostic data to the platform.
*
* @param data The diagnostic data provided by FLP HAL.
*/
- void onDiagnosticDataAvailable(in String data);
+ void onDiagnosticDataAvailable(in String data) = 1;
+
+ /**
+ * Event generated from FLP HAL to provide a mask of supported
+ * capabilities. Should be called immediatly after init.
+ */
+ void onCapabilities(int capabilities) = 2;
+
+ /**
+ * Event generated from FLP HAL when the status of location batching
+ * changes (location is successful/unsuccessful).
+ */
+ void onStatusChanged(int status) = 3;
} \ No newline at end of file
diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java
index b268986..6b4f2d5 100644
--- a/core/java/android/net/IpPrefix.java
+++ b/core/java/android/net/IpPrefix.java
@@ -170,6 +170,21 @@ public final class IpPrefix implements Parcelable {
}
/**
+ * Determines whether the prefix contains the specified address.
+ *
+ * @param address An {@link InetAddress} to test.
+ * @return {@code true} if the prefix covers the given address.
+ */
+ public boolean contains(InetAddress address) {
+ byte[] addrBytes = (address == null) ? null : address.getAddress();
+ if (addrBytes == null || addrBytes.length != this.address.length) {
+ return false;
+ }
+ NetworkUtils.maskRawAddress(addrBytes, prefixLength);
+ return Arrays.equals(this.address, addrBytes);
+ }
+
+ /**
* Returns a string representation of this {@code IpPrefix}.
*
* @return a string such as {@code "192.0.2.0/24"} or {@code "2001:db8:1:2::/64"}.
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index cfd20a0..90a2460 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -367,13 +367,7 @@ public final class RouteInfo implements Parcelable {
* @return {@code true} if the destination and prefix length cover the given address.
*/
public boolean matches(InetAddress destination) {
- if (destination == null) return false;
-
- // match the route destination and destination with prefix length
- InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
- mDestination.getPrefixLength());
-
- return mDestination.getAddress().equals(dstNet);
+ return mDestination.contains(destination);
}
/**
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index afd9950..b9e307f 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1327,9 +1327,9 @@ public class UserManager {
* calling user.
* @return creation time in milliseconds since Epoch time.
*/
- public long getUserCreationTime(int userHandle) {
+ public long getUserCreationTime(UserHandle userHandle) {
try {
- return mService.getUserCreationTime(userHandle);
+ return mService.getUserCreationTime(userHandle.getIdentifier());
} catch (RemoteException re) {
Log.w(TAG, "Could not get user creation time", re);
return 0;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3087e1d..9edf6ad 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -889,6 +889,15 @@ public final class Settings {
= "android.settings.ZEN_MODE_SCHEDULE_RULE_SETTINGS";
/**
+ * Activity Action: Show Zen Mode external rule configuration settings.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS
+ = "android.settings.ZEN_MODE_EXTERNAL_RULE_SETTINGS";
+
+ /**
* Activity Action: Show the regulatory information screen for the device.
* <p>
* In some cases, a matching Activity may not exist, so ensure you safeguard
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index 4712f97..879f26c 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -19,7 +19,6 @@ package android.provider;
import android.Manifest;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
@@ -258,7 +257,6 @@ public class VoicemailContract {
*
* @hide
*/
- @SystemApi
public static Uri insert(Context context, Voicemail voicemail) {
ContentResolver contentResolver = context.getContentResolver();
ContentValues contentValues = getContentValues(voicemail);
@@ -274,7 +272,6 @@ public class VoicemailContract {
*
* @hide
*/
- @SystemApi
public static int insert(Context context, List<Voicemail> voicemails) {
ContentResolver contentResolver = context.getContentResolver();
int count = voicemails.size();
@@ -293,7 +290,6 @@ public class VoicemailContract {
*
* @hide
*/
- @SystemApi
public static int deleteAll(Context context) {
return context.getContentResolver().delete(
buildSourceUri(context.getPackageName()), "", new String[0]);
@@ -452,7 +448,6 @@ public class VoicemailContract {
*
* @hide
*/
- @SystemApi
public static void setStatus(Context context, PhoneAccountHandle accountHandle,
int configurationState, int dataChannelState, int notificationChannelState) {
ContentResolver contentResolver = context.getContentResolver();
diff --git a/core/java/android/security/keymaster/KeyCharacteristics.java b/core/java/android/security/keymaster/KeyCharacteristics.java
index 0f1d422..b3a3aad 100644
--- a/core/java/android/security/keymaster/KeyCharacteristics.java
+++ b/core/java/android/security/keymaster/KeyCharacteristics.java
@@ -19,6 +19,10 @@ package android.security.keymaster;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
/**
* @hide
*/
@@ -28,10 +32,12 @@ public class KeyCharacteristics implements Parcelable {
public static final Parcelable.Creator<KeyCharacteristics> CREATOR = new
Parcelable.Creator<KeyCharacteristics>() {
+ @Override
public KeyCharacteristics createFromParcel(Parcel in) {
return new KeyCharacteristics(in);
}
+ @Override
public KeyCharacteristics[] newArray(int length) {
return new KeyCharacteristics[length];
}
@@ -48,6 +54,7 @@ public class KeyCharacteristics implements Parcelable {
return 0;
}
+ @Override
public void writeToParcel(Parcel out, int flags) {
swEnforced.writeToParcel(out, flags);
hwEnforced.writeToParcel(out, flags);
@@ -57,5 +64,53 @@ public class KeyCharacteristics implements Parcelable {
swEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
hwEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
}
+
+ public Integer getInteger(int tag) {
+ if (hwEnforced.containsTag(tag)) {
+ return hwEnforced.getInt(tag, -1);
+ } else if (swEnforced.containsTag(tag)) {
+ return swEnforced.getInt(tag, -1);
+ } else {
+ return null;
+ }
+ }
+
+ public int getInt(int tag, int defaultValue) {
+ Integer result = getInteger(tag);
+ return (result != null) ? result : defaultValue;
+ }
+
+ public List<Integer> getInts(int tag) {
+ List<Integer> result = new ArrayList<Integer>();
+ result.addAll(hwEnforced.getInts(tag));
+ result.addAll(swEnforced.getInts(tag));
+ return result;
+ }
+
+ public Date getDate(int tag) {
+ Date result = hwEnforced.getDate(tag, null);
+ if (result == null) {
+ result = swEnforced.getDate(tag, null);
+ }
+ return result;
+ }
+
+ public Date getDate(int tag, Date defaultValue) {
+ if (hwEnforced.containsTag(tag)) {
+ return hwEnforced.getDate(tag, null);
+ } else if (hwEnforced.containsTag(tag)) {
+ return swEnforced.getDate(tag, null);
+ } else {
+ return defaultValue;
+ }
+ }
+
+ public boolean getBoolean(KeyCharacteristics keyCharacteristics, int tag) {
+ if (keyCharacteristics.hwEnforced.containsTag(tag)) {
+ return keyCharacteristics.hwEnforced.getBoolean(tag, false);
+ } else {
+ return keyCharacteristics.swEnforced.getBoolean(tag, false);
+ }
+ }
}
diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java
index b5fd4bd..8ed288c 100644
--- a/core/java/android/security/keymaster/KeymasterArguments.java
+++ b/core/java/android/security/keymaster/KeymasterArguments.java
@@ -34,9 +34,12 @@ public class KeymasterArguments implements Parcelable {
public static final Parcelable.Creator<KeymasterArguments> CREATOR = new
Parcelable.Creator<KeymasterArguments>() {
+ @Override
public KeymasterArguments createFromParcel(Parcel in) {
return new KeymasterArguments(in);
}
+
+ @Override
public KeymasterArguments[] newArray(int size) {
return new KeymasterArguments[size];
}
@@ -54,6 +57,12 @@ public class KeymasterArguments implements Parcelable {
mArguments.add(new KeymasterIntArgument(tag, value));
}
+ public void addInts(int tag, int... values) {
+ for (int value : values) {
+ addInt(tag, value);
+ }
+ }
+
public void addBoolean(int tag) {
mArguments.add(new KeymasterBooleanArgument(tag));
}
diff --git a/core/java/android/service/chooser/ChooserTarget.java b/core/java/android/service/chooser/ChooserTarget.java
index 7fd1d10..d21cc3c 100644
--- a/core/java/android/service/chooser/ChooserTarget.java
+++ b/core/java/android/service/chooser/ChooserTarget.java
@@ -17,6 +17,7 @@
package android.service.chooser;
+import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -24,8 +25,10 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.graphics.Bitmap;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.UserHandle;
import android.util.Log;
/**
@@ -55,6 +58,12 @@ public final class ChooserTarget implements Parcelable {
private IntentSender mIntentSender;
/**
+ * A raw intent provided in lieu of an IntentSender. Will be filled in and sent
+ * by {@link #sendIntent(Context, Intent)}.
+ */
+ private Intent mIntent;
+
+ /**
* The score given to this item. It can be normalized.
*/
private float mScore;
@@ -135,6 +144,17 @@ public final class ChooserTarget implements Parcelable {
mIntentSender = intentSender;
}
+ public ChooserTarget(CharSequence title, Bitmap icon, float score, Intent intent) {
+ mTitle = title;
+ mIcon = icon;
+ if (score > 1.f || score < 0.f) {
+ throw new IllegalArgumentException("Score " + score + " out of range; "
+ + "must be between 0.0f and 1.0f");
+ }
+ mScore = score;
+ mIntent = intent;
+ }
+
ChooserTarget(Parcel in) {
mTitle = in.readCharSequence();
if (in.readInt() != 0) {
@@ -144,6 +164,9 @@ public final class ChooserTarget implements Parcelable {
}
mScore = in.readFloat();
mIntentSender = IntentSender.readIntentSenderOrNullFromParcel(in);
+ if (in.readInt() != 0) {
+ mIntent = Intent.CREATOR.createFromParcel(in);
+ }
}
/**
@@ -179,6 +202,7 @@ public final class ChooserTarget implements Parcelable {
/**
* Returns the raw IntentSender supplied by the ChooserTarget's creator.
+ * This may be null if the creator specified a regular Intent instead.
*
* <p>To fill in and send the intent, see {@link #sendIntent(Context, Intent)}.</p>
*
@@ -189,6 +213,18 @@ public final class ChooserTarget implements Parcelable {
}
/**
+ * Returns the Intent supplied by the ChooserTarget's creator.
+ * This may be null if the creator specified an IntentSender or PendingIntent instead.
+ *
+ * <p>To fill in and send the intent, see {@link #sendIntent(Context, Intent)}.</p>
+ *
+ * @return the Intent supplied by the ChooserTarget's creator
+ */
+ public Intent getIntent() {
+ return mIntent;
+ }
+
+ /**
* Fill in the IntentSender supplied by the ChooserTarget's creator and send it.
*
* @param context the sending Context; generally the Activity presenting the chooser UI
@@ -200,18 +236,109 @@ public final class ChooserTarget implements Parcelable {
fillInIntent.migrateExtraStreamToClipData();
fillInIntent.prepareToLeaveProcess();
}
- try {
- mIntentSender.sendIntent(context, 0, fillInIntent, null, null);
- return true;
- } catch (IntentSender.SendIntentException e) {
- Log.e(TAG, "sendIntent " + this + " failed", e);
+ if (mIntentSender != null) {
+ try {
+ mIntentSender.sendIntent(context, 0, fillInIntent, null, null);
+ return true;
+ } catch (IntentSender.SendIntentException e) {
+ Log.e(TAG, "sendIntent " + this + " failed", e);
+ return false;
+ }
+ } else if (mIntent != null) {
+ try {
+ final Intent toSend = new Intent(mIntent);
+ toSend.fillIn(fillInIntent, 0);
+ context.startActivity(toSend);
+ return true;
+ } catch (Exception e) {
+ Log.e(TAG, "sendIntent " + this + " failed", e);
+ return false;
+ }
+ } else {
+ Log.e(TAG, "sendIntent " + this + " failed - no IntentSender or Intent to send");
+ return false;
+ }
+ }
+
+ /**
+ * Same as {@link #sendIntent(Context, Intent)}, but offers a userId field to use
+ * for launching the {@link #getIntent() intent} using
+ * {@link Activity#startActivityAsCaller(Intent, Bundle, int)} if the
+ * {@link #getIntentSender() IntentSender} is not present. If the IntentSender is present,
+ * it will be invoked as usual with its own calling identity.
+ *
+ * @hide internal use only.
+ */
+ public boolean sendIntentAsCaller(Activity context, Intent fillInIntent, int userId) {
+ if (fillInIntent != null) {
+ fillInIntent.migrateExtraStreamToClipData();
+ fillInIntent.prepareToLeaveProcess();
+ }
+ if (mIntentSender != null) {
+ try {
+ mIntentSender.sendIntent(context, 0, fillInIntent, null, null);
+ return true;
+ } catch (IntentSender.SendIntentException e) {
+ Log.e(TAG, "sendIntent " + this + " failed", e);
+ return false;
+ }
+ } else if (mIntent != null) {
+ try {
+ final Intent toSend = new Intent(mIntent);
+ toSend.fillIn(fillInIntent, 0);
+ context.startActivityAsCaller(toSend, null, userId);
+ return true;
+ } catch (Exception e) {
+ Log.e(TAG, "sendIntent " + this + " failed", e);
+ return false;
+ }
+ } else {
+ Log.e(TAG, "sendIntent " + this + " failed - no IntentSender or Intent to send");
+ return false;
+ }
+ }
+
+ /**
+ * The UserHandle is only used if we're launching a raw intent. The IntentSender will be
+ * launched with its associated identity.
+ *
+ * @hide Internal use only
+ */
+ public boolean sendIntentAsUser(Activity context, Intent fillInIntent, UserHandle user) {
+ if (fillInIntent != null) {
+ fillInIntent.migrateExtraStreamToClipData();
+ fillInIntent.prepareToLeaveProcess();
+ }
+ if (mIntentSender != null) {
+ try {
+ mIntentSender.sendIntent(context, 0, fillInIntent, null, null);
+ return true;
+ } catch (IntentSender.SendIntentException e) {
+ Log.e(TAG, "sendIntent " + this + " failed", e);
+ return false;
+ }
+ } else if (mIntent != null) {
+ try {
+ final Intent toSend = new Intent(mIntent);
+ toSend.fillIn(fillInIntent, 0);
+ context.startActivityAsUser(toSend, user);
+ return true;
+ } catch (Exception e) {
+ Log.e(TAG, "sendIntent " + this + " failed", e);
+ return false;
+ }
+ } else {
+ Log.e(TAG, "sendIntent " + this + " failed - no IntentSender or Intent to send");
return false;
}
}
@Override
public String toString() {
- return "ChooserTarget{" + mIntentSender.getCreatorPackage() + "'" + mTitle
+ return "ChooserTarget{"
+ + (mIntentSender != null ? mIntentSender.getCreatorPackage() : mIntent)
+ + ", "
+ + "'" + mTitle
+ "', " + mScore + "}";
}
diff --git a/core/java/android/service/chooser/ChooserTargetService.java b/core/java/android/service/chooser/ChooserTargetService.java
index 9188806..699bd0a 100644
--- a/core/java/android/service/chooser/ChooserTargetService.java
+++ b/core/java/android/service/chooser/ChooserTargetService.java
@@ -24,6 +24,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.os.RemoteException;
+import android.util.Log;
import java.util.List;
@@ -77,9 +78,26 @@ public abstract class ChooserTargetService extends Service {
private final String TAG = ChooserTargetService.class.getSimpleName()
+ '[' + getClass().getSimpleName() + ']';
+ private static final boolean DEBUG = false;
+
+ /**
+ * The Intent action that a ChooserTargetService must respond to
+ */
@SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
public static final String SERVICE_INTERFACE = "android.service.chooser.ChooserTargetService";
+ /**
+ * The name of the <code>meta-data</code> element that must be present on an
+ * <code>activity</code> element in a manifest to link it to a ChooserTargetService
+ */
+ public static final String META_DATA_NAME = "android.service.chooser.chooser_target_service";
+
+ /**
+ * The permission that a ChooserTargetService must require in order to bind to it.
+ * If this permission is not enforced the system will skip that ChooserTargetService.
+ */
+ public static final String BIND_PERMISSION = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
+
private IChooserTargetServiceWrapper mWrapper = null;
/**
@@ -105,7 +123,9 @@ public abstract class ChooserTargetService extends Service {
@Override
public IBinder onBind(Intent intent) {
+ if (DEBUG) Log.d(TAG, "onBind " + intent);
if (!SERVICE_INTERFACE.equals(intent.getAction())) {
+ if (DEBUG) Log.d(TAG, "bad intent action " + intent.getAction() + "; returning null");
return null;
}
@@ -121,9 +141,14 @@ public abstract class ChooserTargetService extends Service {
IntentFilter matchedFilter, IChooserTargetResult result) throws RemoteException {
List<ChooserTarget> targets = null;
try {
+ if (DEBUG) {
+ Log.d(TAG, "getChooserTargets calling onGetChooserTargets; "
+ + targetComponentName + " filter: " + matchedFilter);
+ }
targets = onGetChooserTargets(targetComponentName, matchedFilter);
} finally {
result.sendResult(targets);
+ if (DEBUG) Log.d(TAG, "Sent results");
}
}
}
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 822bfcc..29aaf30 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -41,6 +41,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.PhoneWindow;
+import android.view.SearchEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
@@ -332,6 +333,12 @@ public class DreamService extends Service implements Window.Callback {
/** {@inheritDoc} */
@Override
+ public boolean onSearchRequested(SearchEvent event) {
+ return onSearchRequested();
+ }
+
+ /** {@inheritDoc} */
+ @Override
public boolean onSearchRequested() {
return false;
}
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 56eb510..1ed4779 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -654,8 +654,7 @@ public class ZenModeConfig implements Parcelable {
}
String summary = "";
for (ZenRule automaticRule : config.automaticRules.values()) {
- if (automaticRule.enabled && !automaticRule.snoozing
- && automaticRule.isTrueOrUnknown()) {
+ if (automaticRule.isAutomaticActive()) {
if (summary.isEmpty()) {
summary = automaticRule.name;
} else {
@@ -745,9 +744,13 @@ public class ZenModeConfig implements Parcelable {
component);
}
+ public boolean isAutomaticActive() {
+ return enabled && !snoozing && component != null && isTrueOrUnknown();
+ }
+
public boolean isTrueOrUnknown() {
- return condition == null || condition.state == Condition.STATE_TRUE
- || condition.state == Condition.STATE_UNKNOWN;
+ return condition != null && (condition.state == Condition.STATE_TRUE
+ || condition.state == Condition.STATE_UNKNOWN);
}
public static final Parcelable.Creator<ZenRule> CREATOR
diff --git a/core/java/android/view/PhoneWindow.java b/core/java/android/view/PhoneWindow.java
index 38f4d1c..5af2832 100644
--- a/core/java/android/view/PhoneWindow.java
+++ b/core/java/android/view/PhoneWindow.java
@@ -1916,7 +1916,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
break;
}
if (event.isTracking() && !event.isCanceled()) {
- launchDefaultSearch();
+ launchDefaultSearch(event);
}
return true;
}
@@ -4245,14 +4245,19 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
*
* @return true if search window opened
*/
- private boolean launchDefaultSearch() {
+ private boolean launchDefaultSearch(KeyEvent event) {
boolean result;
final Callback cb = getCallback();
if (cb == null || isDestroyed()) {
result = false;
} else {
sendCloseSystemWindows("search");
- result = cb.onSearchRequested();
+ int deviceId = event.getDeviceId();
+ SearchEvent searchEvent = null;
+ if (deviceId != 0) {
+ searchEvent = new SearchEvent(InputDevice.getDevice(deviceId));
+ }
+ result = cb.onSearchRequested(searchEvent);
}
if (!result && (getContext().getResources().getConfiguration().uiMode
& Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
diff --git a/core/java/android/view/SearchEvent.java b/core/java/android/view/SearchEvent.java
new file mode 100644
index 0000000..ef51e7d
--- /dev/null
+++ b/core/java/android/view/SearchEvent.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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 android.view.InputDevice;
+
+/**
+ * Class that contains information about an event that triggers a search.
+ */
+public class SearchEvent {
+
+ private InputDevice mInputDevice;
+
+ /** @hide */
+ public SearchEvent(InputDevice inputDevice) {
+ mInputDevice = inputDevice;
+ }
+
+ /**
+ * Returns the {@link InputDevice} that triggered the search.
+ * @return InputDevice the InputDevice that triggered the search.
+ */
+ public InputDevice getInputDevice() {
+ return mInputDevice;
+ }
+}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 60d2ceb..3fa8c81 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -15087,7 +15087,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Utility function, called by draw(canvas, parent, drawingTime) to handle the less common
* case of an active Animation being run on the view.
*/
- private boolean drawAnimation(ViewGroup parent, long drawingTime,
+ private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime,
Animation a, boolean scalingRequired) {
Transformation invalidationTransform;
final int flags = parent.mGroupFlags;
@@ -15204,23 +15204,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
Transformation transformToApply = null;
boolean concatMatrix = false;
- boolean scalingRequired = false;
- boolean caching;
+ boolean scalingRequired = mAttachInfo != null && mAttachInfo.mScalingRequired;
int layerType = getLayerType();
-
final boolean hardwareAccelerated = canvas.isHardwareAccelerated();
- if ((flags & ViewGroup.FLAG_CHILDREN_DRAWN_WITH_CACHE) != 0 ||
- (flags & ViewGroup.FLAG_ALWAYS_DRAWN_WITH_CACHE) != 0) {
- caching = true;
- // Auto-scaled apps are not hw-accelerated, no need to set scaling flag on DisplayList
- if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired;
- } else {
- caching = (layerType != LAYER_TYPE_NONE) || hardwareAccelerated;
- }
final Animation a = getAnimation();
if (a != null) {
- more = drawAnimation(parent, drawingTime, a, scalingRequired);
+ more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired);
concatMatrix = a.willChangeTransformationMatrix();
if (concatMatrix) {
mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
@@ -15270,34 +15260,32 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
RenderNode renderNode = null;
Bitmap cache = null;
boolean hasDisplayList = false;
- if (caching) {
- if (!hardwareAccelerated) {
- if (layerType != LAYER_TYPE_NONE) {
- layerType = LAYER_TYPE_SOFTWARE;
- buildDrawingCache(true);
- }
- cache = getDrawingCache(true);
- } else {
- switch (layerType) {
- case LAYER_TYPE_SOFTWARE:
- if (usingRenderNodeProperties) {
- hasDisplayList = canHaveDisplayList();
- } else {
- buildDrawingCache(true);
- cache = getDrawingCache(true);
- }
- break;
- case LAYER_TYPE_HARDWARE:
- if (usingRenderNodeProperties) {
- hasDisplayList = canHaveDisplayList();
- }
- break;
- case LAYER_TYPE_NONE:
- // Delay getting the display list until animation-driven alpha values are
- // set up and possibly passed on to the view
+ if (!hardwareAccelerated) {
+ if (layerType != LAYER_TYPE_NONE) {
+ layerType = LAYER_TYPE_SOFTWARE;
+ buildDrawingCache(true);
+ }
+ cache = getDrawingCache(true);
+ } else {
+ switch (layerType) {
+ case LAYER_TYPE_SOFTWARE:
+ if (usingRenderNodeProperties) {
hasDisplayList = canHaveDisplayList();
- break;
- }
+ } else {
+ buildDrawingCache(true);
+ cache = getDrawingCache(true);
+ }
+ break;
+ case LAYER_TYPE_HARDWARE:
+ if (usingRenderNodeProperties) {
+ hasDisplayList = canHaveDisplayList();
+ }
+ break;
+ case LAYER_TYPE_NONE:
+ // Delay getting the display list until animation-driven alpha values are
+ // set up and possibly passed on to the view
+ hasDisplayList = canHaveDisplayList();
+ break;
}
}
usingRenderNodeProperties &= hasDisplayList;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 8d06ce2..98b895d 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -245,8 +245,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// to clip it, even if FLAG_CLIP_TO_PADDING is set
private static final int FLAG_PADDING_NOT_NULL = 0x20;
- // When set, this ViewGroup caches its children in a Bitmap before starting a layout animation
- // Set by default
+ /** @deprecated - functionality removed */
private static final int FLAG_ANIMATION_CACHE = 0x40;
// When set, this ViewGroup converts calls to invalidate(Rect) to invalidate() during a
@@ -292,16 +291,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
private static final int FLAG_ADD_STATES_FROM_CHILDREN = 0x2000;
- /**
- * When set, this ViewGroup tries to always draw its children using their drawing cache.
- */
- static final int FLAG_ALWAYS_DRAWN_WITH_CACHE = 0x4000;
+ /** @deprecated functionality removed */
+ private static final int FLAG_ALWAYS_DRAWN_WITH_CACHE = 0x4000;
- /**
- * When set, and if FLAG_ALWAYS_DRAWN_WITH_CACHE is not set, this ViewGroup will try to
- * draw its children with their drawing cache.
- */
- static final int FLAG_CHILDREN_DRAWN_WITH_CACHE = 0x8000;
+ /** @deprecated functionality removed */
+ private static final int FLAG_CHILDREN_DRAWN_WITH_CACHE = 0x8000;
/**
* When set, this group will go through its list of children to notify them of
@@ -584,8 +578,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
mGroupFlags |= FLAG_CLIP_CHILDREN;
mGroupFlags |= FLAG_CLIP_TO_PADDING;
mGroupFlags |= FLAG_ANIMATION_DONE;
- mGroupFlags |= FLAG_ANIMATION_CACHE;
- mGroupFlags |= FLAG_ALWAYS_DRAWN_WITH_CACHE;
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
mGroupFlags |= FLAG_SPLIT_MOTION_EVENTS;
@@ -3088,44 +3080,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
@Override
- protected void onAnimationStart() {
- super.onAnimationStart();
-
- // When this ViewGroup's animation starts, build the cache for the children
- if ((mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE) {
- final int count = mChildrenCount;
- final View[] children = mChildren;
- final boolean buildCache = !isHardwareAccelerated();
-
- for (int i = 0; i < count; i++) {
- final View child = children[i];
- if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
- child.setDrawingCacheEnabled(true);
- if (buildCache) {
- child.buildDrawingCache(true);
- }
- }
- }
-
- mGroupFlags |= FLAG_CHILDREN_DRAWN_WITH_CACHE;
- }
- }
-
- @Override
- protected void onAnimationEnd() {
- super.onAnimationEnd();
-
- // When this ViewGroup's animation ends, destroy the cache of the children
- if ((mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE) {
- mGroupFlags &= ~FLAG_CHILDREN_DRAWN_WITH_CACHE;
-
- if ((mPersistentDrawingCache & PERSISTENT_ANIMATION_CACHE) == 0) {
- setChildrenDrawingCacheEnabled(false);
- }
- }
- }
-
- @Override
Bitmap createSnapshot(Bitmap.Config quality, int backgroundColor, boolean skipChildren) {
int count = mChildrenCount;
int[] visibilities = null;
@@ -3295,8 +3249,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
int flags = mGroupFlags;
if ((flags & FLAG_RUN_ANIMATION) != 0 && canAnimate()) {
- final boolean cache = (mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE;
-
final boolean buildCache = !isHardwareAccelerated();
for (int i = 0; i < childrenCount; i++) {
final View child = children[i];
@@ -3304,12 +3256,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final LayoutParams params = child.getLayoutParams();
attachLayoutAnimationParameters(child, params, i, childrenCount);
bindLayoutAnimation(child);
- if (cache) {
- child.setDrawingCacheEnabled(true);
- if (buildCache) {
- child.buildDrawingCache(true);
- }
- }
}
}
@@ -3323,10 +3269,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
mGroupFlags &= ~FLAG_RUN_ANIMATION;
mGroupFlags &= ~FLAG_ANIMATION_DONE;
- if (cache) {
- mGroupFlags |= FLAG_CHILDREN_DRAWN_WITH_CACHE;
- }
-
if (mAnimationListener != null) {
mAnimationListener.onAnimationStart(controller.getAnimation());
}
@@ -3504,13 +3446,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
post(end);
}
- if ((mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE) {
- mGroupFlags &= ~FLAG_CHILDREN_DRAWN_WITH_CACHE;
- if ((mPersistentDrawingCache & PERSISTENT_ANIMATION_CACHE) == 0) {
- setChildrenDrawingCacheEnabled(false);
- }
- }
-
invalidate(true);
}
@@ -5278,8 +5213,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*
* @see #setAnimationCacheEnabled(boolean)
* @see View#setDrawingCacheEnabled(boolean)
+ *
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * Caching behavior of children may be controlled through {@link View#setLayerType(int, Paint)}.
*/
- @ViewDebug.ExportedProperty
public boolean isAnimationCacheEnabled() {
return (mGroupFlags & FLAG_ANIMATION_CACHE) == FLAG_ANIMATION_CACHE;
}
@@ -5294,6 +5231,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*
* @see #isAnimationCacheEnabled()
* @see View#setDrawingCacheEnabled(boolean)
+ *
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * Caching behavior of children may be controlled through {@link View#setLayerType(int, Paint)}.
*/
public void setAnimationCacheEnabled(boolean enabled) {
setBooleanFlag(FLAG_ANIMATION_CACHE, enabled);
@@ -5308,8 +5248,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* @see #setAlwaysDrawnWithCacheEnabled(boolean)
* @see #setChildrenDrawnWithCacheEnabled(boolean)
* @see View#setDrawingCacheEnabled(boolean)
+ *
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * Child views may no longer have their caching behavior disabled by parents.
*/
- @ViewDebug.ExportedProperty(category = "drawing")
public boolean isAlwaysDrawnWithCacheEnabled() {
return (mGroupFlags & FLAG_ALWAYS_DRAWN_WITH_CACHE) == FLAG_ALWAYS_DRAWN_WITH_CACHE;
}
@@ -5330,6 +5272,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* @see #setChildrenDrawnWithCacheEnabled(boolean)
* @see View#setDrawingCacheEnabled(boolean)
* @see View#setDrawingCacheQuality(int)
+ *
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * Child views may no longer have their caching behavior disabled by parents.
*/
public void setAlwaysDrawnWithCacheEnabled(boolean always) {
setBooleanFlag(FLAG_ALWAYS_DRAWN_WITH_CACHE, always);
@@ -5343,8 +5288,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*
* @see #setAlwaysDrawnWithCacheEnabled(boolean)
* @see #setChildrenDrawnWithCacheEnabled(boolean)
+ *
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * Child views may no longer be forced to cache their rendering state by their parents.
+ * Use {@link View#setLayerType(int, Paint)} on individual Views instead.
*/
- @ViewDebug.ExportedProperty(category = "drawing")
protected boolean isChildrenDrawnWithCacheEnabled() {
return (mGroupFlags & FLAG_CHILDREN_DRAWN_WITH_CACHE) == FLAG_CHILDREN_DRAWN_WITH_CACHE;
}
@@ -5361,6 +5309,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*
* @see #setAlwaysDrawnWithCacheEnabled(boolean)
* @see #isChildrenDrawnWithCacheEnabled()
+ *
+ * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored.
+ * Child views may no longer be forced to cache their rendering state by their parents.
+ * Use {@link View#setLayerType(int, Paint)} on individual Views instead.
*/
protected void setChildrenDrawnWithCacheEnabled(boolean enabled) {
setBooleanFlag(FLAG_CHILDREN_DRAWN_WITH_CACHE, enabled);
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 36f047e..9d0d5ff 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -414,6 +414,15 @@ public abstract class Window {
public boolean onSearchRequested();
/**
+ * Called when the user signals the desire to start a search.
+ *
+ * @param searchEvent A {@link SearchEvent} describing the signal to
+ * start a search.
+ * @return true if search launched, false if activity refuses (blocks)
+ */
+ public boolean onSearchRequested(SearchEvent searchEvent);
+
+ /**
* Called when an action mode is being started for this window. Gives the
* callback an opportunity to handle the action mode in its own unique and
* beautiful way. If this method returns null the system can choose a way
diff --git a/core/java/android/view/WindowCallbackWrapper.java b/core/java/android/view/WindowCallbackWrapper.java
index 979ee95..8ce1f8c 100644
--- a/core/java/android/view/WindowCallbackWrapper.java
+++ b/core/java/android/view/WindowCallbackWrapper.java
@@ -122,6 +122,11 @@ public class WindowCallbackWrapper implements Window.Callback {
}
@Override
+ public boolean onSearchRequested(SearchEvent searchEvent) {
+ return mWrapped.onSearchRequested(searchEvent);
+ }
+
+ @Override
public boolean onSearchRequested() {
return mWrapped.onSearchRequested();
}
diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java
index f951dc2..e0b0e1f 100644
--- a/core/java/android/widget/ActionMenuPresenter.java
+++ b/core/java/android/widget/ActionMenuPresenter.java
@@ -40,7 +40,6 @@ import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ListPopupWindow.ForwardingListener;
-import com.android.internal.transition.ActionBarTransition;
import com.android.internal.view.ActionBarPolicy;
import com.android.internal.view.menu.ActionMenuItemView;
import com.android.internal.view.menu.BaseMenuPresenter;
@@ -99,7 +98,30 @@ public class ActionMenuPresenter extends BaseMenuPresenter
// The list of currently running animations on menu items.
private List<ItemAnimationInfo> mRunningItemAnimations = new ArrayList<ItemAnimationInfo>();
+ private ViewTreeObserver.OnPreDrawListener mItemAnimationPreDrawListener =
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ computeMenuItemAnimationInfo(false);
+ ((View) mMenuView).getViewTreeObserver().removeOnPreDrawListener(this);
+ runItemAnimations();
+ return true;
+ }
+ };
+ private View.OnAttachStateChangeListener mAttachStateChangeListener =
+ new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ }
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ ((View) mMenuView).getViewTreeObserver().removeOnPreDrawListener(
+ mItemAnimationPreDrawListener);
+ mPreLayoutItems.clear();
+ mPostLayoutItems.clear();
+ }
+ };
public ActionMenuPresenter(Context context) {
@@ -177,8 +199,15 @@ public class ActionMenuPresenter extends BaseMenuPresenter
@Override
public MenuView getMenuView(ViewGroup root) {
+ MenuView oldMenuView = mMenuView;
MenuView result = super.getMenuView(root);
- ((ActionMenuView) result).setPresenter(this);
+ if (oldMenuView != result) {
+ ((ActionMenuView) result).setPresenter(this);
+ if (oldMenuView != null) {
+ ((View) oldMenuView).removeOnAttachStateChangeListener(mAttachStateChangeListener);
+ }
+ ((View) result).addOnAttachStateChangeListener(mAttachStateChangeListener);
+ }
return result;
}
@@ -226,11 +255,11 @@ public class ActionMenuPresenter extends BaseMenuPresenter
* into the MenuItemLayoutInfo structure to store the appropriate position values.
*/
private void computeMenuItemAnimationInfo(boolean preLayout) {
- final ViewGroup menuViewParent = (ViewGroup) mMenuView;
- final int count = menuViewParent.getChildCount();
+ final ViewGroup menuView = (ViewGroup) mMenuView;
+ final int count = menuView.getChildCount();
SparseArray items = preLayout ? mPreLayoutItems : mPostLayoutItems;
for (int i = 0; i < count; ++i) {
- View child = menuViewParent.getChildAt(i);
+ View child = menuView.getChildAt(i);
final int id = child.getId();
if (id > 0 && child.getWidth() != 0 && child.getHeight() != 0) {
MenuItemLayoutInfo info = new MenuItemLayoutInfo(child, preLayout);
@@ -377,28 +406,16 @@ public class ActionMenuPresenter extends BaseMenuPresenter
* which is then fed into runItemAnimations()
*/
private void setupItemAnimations() {
- final ViewGroup menuViewParent = (ViewGroup) mMenuView;
computeMenuItemAnimationInfo(true);
- final ViewTreeObserver observer = menuViewParent.getViewTreeObserver();
- if (observer != null) {
- observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
- @Override
- public boolean onPreDraw() {
- computeMenuItemAnimationInfo(false);
- observer.removeOnPreDrawListener(this);
- runItemAnimations();
- return true;
- }
- });
- }
+ ((View) mMenuView).getViewTreeObserver().
+ addOnPreDrawListener(mItemAnimationPreDrawListener);
}
@Override
public void updateMenuView(boolean cleared) {
final ViewGroup menuViewParent = (ViewGroup) ((View) mMenuView).getParent();
if (menuViewParent != null) {
-// setupItemAnimations();
- ActionBarTransition.beginDelayedTransition(menuViewParent);
+ setupItemAnimations();
}
super.updateMenuView(cleared);
@@ -736,8 +753,14 @@ public class ActionMenuPresenter extends BaseMenuPresenter
}
public void setMenuView(ActionMenuView menuView) {
- mMenuView = menuView;
- menuView.initialize(mMenu);
+ if (menuView != mMenuView) {
+ if (mMenuView != null) {
+ ((View) mMenuView).removeOnAttachStateChangeListener(mAttachStateChangeListener);
+ }
+ mMenuView = menuView;
+ menuView.initialize(mMenu);
+ menuView.addOnAttachStateChangeListener(mAttachStateChangeListener);
+ }
}
public void setOverflowTintList(ColorStateList tint) {
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index a157087..06a5bd2 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -534,22 +534,23 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate {
@Override
public void onRestoreInstanceState(Parcelable state) {
- SavedState ss = (SavedState) state;
+ final SavedState ss = (SavedState) state;
// TODO: Move instance state into DayPickerView, YearPickerView.
mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
- mCurrentView = ss.getCurrentView();
mMinDate.setTimeInMillis(ss.getMinDate());
mMaxDate.setTimeInMillis(ss.getMaxDate());
onCurrentDateChanged(false);
- setCurrentView(mCurrentView);
+
+ final int currentView = ss.getCurrentView();
+ setCurrentView(currentView);
final int listPosition = ss.getListPosition();
if (listPosition != -1) {
- if (mCurrentView == VIEW_MONTH_DAY) {
+ if (currentView == VIEW_MONTH_DAY) {
mDayPickerView.setCurrentItem(listPosition);
- } else if (mCurrentView == VIEW_YEAR) {
+ } else if (currentView == VIEW_YEAR) {
final int listPositionOffset = ss.getListPositionOffset();
mYearPickerView.setSelectionFromTop(listPosition, listPositionOffset);
}
@@ -601,7 +602,6 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate {
* Class for managing state storing/restoring.
*/
private static class SavedState extends View.BaseSavedState {
-
private final int mSelectedYear;
private final int mSelectedMonth;
private final int mSelectedDay;
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index ec2528f..0e0b2d3 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -22,9 +22,12 @@ import com.android.internal.R;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.MathUtils;
+import android.view.View;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
@@ -41,6 +44,8 @@ class DayPickerView extends ViewPager {
private final Calendar mMinDate = Calendar.getInstance();
private final Calendar mMaxDate = Calendar.getInstance();
+ private final ArrayList<View> mMatchParentChildren = new ArrayList<>(1);
+
private final DayPickerAdapter mAdapter;
/** Temporary calendar used for date calculations. */
@@ -140,6 +145,93 @@ class DayPickerView extends ViewPager {
});
}
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ populate();
+
+ // Everything below is mostly copied from FrameLayout.
+ int count = getChildCount();
+
+ final boolean measureMatchParentChildren =
+ MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY ||
+ MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
+
+ int maxHeight = 0;
+ int maxWidth = 0;
+ int childState = 0;
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() != GONE) {
+ measureChild(child, widthMeasureSpec, heightMeasureSpec);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
+ maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
+ childState = combineMeasuredStates(childState, child.getMeasuredState());
+ if (measureMatchParentChildren) {
+ if (lp.width == LayoutParams.MATCH_PARENT ||
+ lp.height == LayoutParams.MATCH_PARENT) {
+ mMatchParentChildren.add(child);
+ }
+ }
+ }
+ }
+
+ // Account for padding too
+ maxWidth += getPaddingLeft() + getPaddingRight();
+ maxHeight += getPaddingTop() + getPaddingBottom();
+
+ // Check against our minimum height and width
+ maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
+ maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
+
+ // Check against our foreground's minimum height and width
+ final Drawable drawable = getForeground();
+ if (drawable != null) {
+ maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
+ maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
+ }
+
+ setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
+ resolveSizeAndState(maxHeight, heightMeasureSpec,
+ childState << MEASURED_HEIGHT_STATE_SHIFT));
+
+ count = mMatchParentChildren.size();
+ if (count > 1) {
+ for (int i = 0; i < count; i++) {
+ final View child = mMatchParentChildren.get(i);
+
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final int childWidthMeasureSpec;
+ final int childHeightMeasureSpec;
+
+ if (lp.width == LayoutParams.MATCH_PARENT) {
+ childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
+ MeasureSpec.EXACTLY);
+ } else {
+ childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
+ getPaddingLeft() + getPaddingRight(),
+ lp.width);
+ }
+
+ if (lp.height == LayoutParams.MATCH_PARENT) {
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ getMeasuredHeight() - getPaddingTop() - getPaddingBottom(),
+ MeasureSpec.EXACTLY);
+ } else {
+ childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+ getPaddingTop() + getPaddingBottom(),
+ lp.height);
+ }
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+ }
+
+ mMatchParentChildren.clear();
+ }
+
public void setDayOfWeekTextAppearance(int resId) {
mAdapter.setDayOfWeekTextAppearance(resId);
}
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index d9f1f0e..aa7f0b6 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -585,7 +585,6 @@ class SimpleMonthView extends View {
mToday = day;
}
}
- mNumWeeks = calculateNumRows();
// Invalidate the old title.
mTitle = null;
@@ -616,18 +615,6 @@ class SimpleMonthView extends View {
}
}
- public void reuse() {
- mNumWeeks = MAX_WEEKS_IN_MONTH;
- requestLayout();
- }
-
- private int calculateNumRows() {
- final int offset = findDayOffset();
- final int dividend = (offset + mDaysInMonth) / DAYS_IN_WEEK;
- final int remainder = (offset + mDaysInMonth) % DAYS_IN_WEEK;
- return dividend + (remainder > 0 ? 1 : 0);
- }
-
private boolean sameDay(int day, Calendar today) {
return mYear == today.get(Calendar.YEAR) && mMonth == today.get(Calendar.MONTH)
&& day == today.get(Calendar.DAY_OF_MONTH);
@@ -635,8 +622,9 @@ class SimpleMonthView extends View {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- final int preferredHeight = mDesiredDayHeight * mNumWeeks + mDesiredDayOfWeekHeight
- + mDesiredMonthHeight + getPaddingTop() + getPaddingBottom();
+ final int preferredHeight = mDesiredDayHeight * MAX_WEEKS_IN_MONTH
+ + mDesiredDayOfWeekHeight + mDesiredMonthHeight
+ + getPaddingTop() + getPaddingBottom();
final int preferredWidth = mDesiredCellWidth * DAYS_IN_WEEK
+ getPaddingStart() + getPaddingEnd();
final int resolvedWidth = resolveSize(preferredWidth, widthMeasureSpec);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5d60f99..9bbf375 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -540,6 +540,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private Layout mLayout;
private boolean mLocaleChanged = false;
+ @ViewDebug.ExportedProperty(category = "text")
private int mGravity = Gravity.TOP | Gravity.START;
private boolean mHorizontallyScrolling;
diff --git a/core/java/android/widget/YearPickerView.java b/core/java/android/widget/YearPickerView.java
index 7182414..89e59f9 100644
--- a/core/java/android/widget/YearPickerView.java
+++ b/core/java/android/widget/YearPickerView.java
@@ -178,24 +178,29 @@ class YearPickerView extends ListView {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = mInflater.inflate(ITEM_LAYOUT, parent, false);
+ final TextView v;
+ final boolean hasNewView = convertView == null;
+ if (hasNewView) {
+ v = (TextView) mInflater.inflate(ITEM_LAYOUT, parent, false);
+ } else {
+ v = (TextView) convertView;
}
final int year = getYearForPosition(position);
final boolean activated = mActivatedYear == year;
- final int textAppearanceResId;
- if (activated && ITEM_TEXT_ACTIVATED_APPEARANCE != 0) {
- textAppearanceResId = ITEM_TEXT_ACTIVATED_APPEARANCE;
- } else {
- textAppearanceResId = ITEM_TEXT_APPEARANCE;
+ if (hasNewView || v.isActivated() != activated) {
+ final int textAppearanceResId;
+ if (activated && ITEM_TEXT_ACTIVATED_APPEARANCE != 0) {
+ textAppearanceResId = ITEM_TEXT_ACTIVATED_APPEARANCE;
+ } else {
+ textAppearanceResId = ITEM_TEXT_APPEARANCE;
+ }
+ v.setTextAppearance(textAppearanceResId);
+ v.setActivated(activated);
}
- final TextView v = (TextView) convertView;
- v.setText("" + year);
- v.setTextAppearance(v.getContext(), textAppearanceResId);
- v.setActivated(activated);
+ v.setText(Integer.toString(year));
return v;
}
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 9dabb4e..b8110e3 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -170,9 +170,8 @@ public class AlertController {
}
private static boolean shouldCenterSingleButton(Context context) {
- TypedValue outValue = new TypedValue();
- context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogCenterButtons,
- outValue, true);
+ final TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(R.attr.alertDialogCenterButtons, outValue, true);
return outValue.data != 0;
}
@@ -182,27 +181,25 @@ public class AlertController {
mWindow = window;
mHandler = new ButtonHandler(di);
- TypedArray a = context.obtainStyledAttributes(null,
- com.android.internal.R.styleable.AlertDialog,
- com.android.internal.R.attr.alertDialogStyle, 0);
+ final TypedArray a = context.obtainStyledAttributes(null,
+ R.styleable.AlertDialog, R.attr.alertDialogStyle, 0);
- mAlertDialogLayout = a.getResourceId(com.android.internal.R.styleable.AlertDialog_layout,
- com.android.internal.R.layout.alert_dialog);
+ mAlertDialogLayout = a.getResourceId(
+ R.styleable.AlertDialog_layout, R.layout.alert_dialog);
mButtonPanelSideLayout = a.getResourceId(
- com.android.internal.R.styleable.AlertDialog_buttonPanelSideLayout, 0);
-
+ R.styleable.AlertDialog_buttonPanelSideLayout, 0);
mListLayout = a.getResourceId(
- com.android.internal.R.styleable.AlertDialog_listLayout,
- com.android.internal.R.layout.select_dialog);
+ R.styleable.AlertDialog_listLayout, R.layout.select_dialog);
+
mMultiChoiceItemLayout = a.getResourceId(
- com.android.internal.R.styleable.AlertDialog_multiChoiceItemLayout,
- com.android.internal.R.layout.select_dialog_multichoice);
+ R.styleable.AlertDialog_multiChoiceItemLayout,
+ R.layout.select_dialog_multichoice);
mSingleChoiceItemLayout = a.getResourceId(
- com.android.internal.R.styleable.AlertDialog_singleChoiceItemLayout,
- com.android.internal.R.layout.select_dialog_singlechoice);
+ R.styleable.AlertDialog_singleChoiceItemLayout,
+ R.layout.select_dialog_singlechoice);
mListItemLayout = a.getResourceId(
- com.android.internal.R.styleable.AlertDialog_listItemLayout,
- com.android.internal.R.layout.select_dialog_item);
+ R.styleable.AlertDialog_listItemLayout,
+ R.layout.select_dialog_item);
a.recycle();
}
@@ -1067,9 +1064,9 @@ public class AlertController {
}
private void createListView(final AlertController dialog) {
- final RecycleListView listView = (RecycleListView)
- mInflater.inflate(dialog.mListLayout, null);
- ListAdapter adapter;
+ final RecycleListView listView =
+ (RecycleListView) mInflater.inflate(dialog.mListLayout, null);
+ final ListAdapter adapter;
if (mIsMultiChoice) {
if (mCursor == null) {
@@ -1115,14 +1112,20 @@ public class AlertController {
};
}
} else {
- int layout = mIsSingleChoice
- ? dialog.mSingleChoiceItemLayout : dialog.mListItemLayout;
- if (mCursor == null) {
- adapter = (mAdapter != null) ? mAdapter
- : new CheckedItemAdapter(mContext, layout, R.id.text1, mItems);
+ final int layout;
+ if (mIsSingleChoice) {
+ layout = dialog.mSingleChoiceItemLayout;
+ } else {
+ layout = dialog.mListItemLayout;
+ }
+
+ if (mCursor != null) {
+ adapter = new SimpleCursorAdapter(mContext, layout, mCursor,
+ new String[] { mLabelColumn }, new int[] { R.id.text1 });
+ } else if (mAdapter != null) {
+ adapter = mAdapter;
} else {
- adapter = new SimpleCursorAdapter(mContext, layout,
- mCursor, new String[]{mLabelColumn}, new int[]{R.id.text1});
+ adapter = new CheckedItemAdapter(mContext, layout, R.id.text1, mItems);
}
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 64bd6b6..8403e77 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -18,20 +18,87 @@ package com.android.internal.app;
import android.app.Activity;
import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.service.chooser.ChooserTarget;
+import android.service.chooser.ChooserTargetService;
+import android.service.chooser.IChooserTargetResult;
+import android.service.chooser.IChooserTargetService;
+import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+import java.util.List;
public class ChooserActivity extends ResolverActivity {
private static final String TAG = "ChooserActivity";
+ private static final boolean DEBUG = false;
+
+ private static final int QUERY_TARGET_LIMIT = 5;
+ private static final int WATCHDOG_TIMEOUT_MILLIS = 5000;
+
private Bundle mReplacementExtras;
private IntentSender mChosenComponentSender;
+ private ChooserTarget[] mCallerChooserTargets;
+
+ private final List<ChooserTargetServiceConnection> mServiceConnections = new ArrayList<>();
+
+ private static final int CHOOSER_TARGET_SERVICE_RESULT = 1;
+ private static final int CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT = 2;
+
+ private Handler mTargetResultHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case CHOOSER_TARGET_SERVICE_RESULT:
+ if (DEBUG) Log.d(TAG, "CHOOSER_TARGET_SERVICE_RESULT");
+ if (isDestroyed()) break;
+ final ServiceResultInfo sri = (ServiceResultInfo) msg.obj;
+ if (!mServiceConnections.contains(sri.connection)) {
+ Log.w(TAG, "ChooserTargetServiceConnection " + sri.connection
+ + " returned after being removed from active connections."
+ + " Have you considered returning results faster?");
+ break;
+ }
+ final ChooserListAdapter cla = (ChooserListAdapter) getAdapter();
+ cla.addServiceResults(sri.originalTarget, sri.resultTargets);
+ unbindService(sri.connection);
+ mServiceConnections.remove(sri.connection);
+ break;
+
+ case CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT:
+ if (DEBUG) {
+ Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services");
+ }
+ unbindRemainingServices();
+ break;
+
+ default:
+ super.handleMessage(msg);
+ }
+ }
+ };
+
@Override
protected void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
@@ -42,7 +109,7 @@ public class ChooserActivity extends ResolverActivity {
super.onCreate(null);
return;
}
- Intent target = (Intent)targetParcelable;
+ Intent target = (Intent) targetParcelable;
if (target != null) {
modifyTargetIntent(target);
}
@@ -68,6 +135,22 @@ public class ChooserActivity extends ResolverActivity {
initialIntents[i] = in;
}
}
+
+ pa = intent.getParcelableArrayExtra(Intent.EXTRA_CHOOSER_TARGETS);
+ if (pa != null) {
+ final ChooserTarget[] targets = new ChooserTarget[pa.length];
+ for (int i = 0; i < pa.length; i++) {
+ if (!(pa[i] instanceof ChooserTarget)) {
+ Log.w("ChooserActivity", "Chooser target #" + i + " is not a ChooserTarget: " +
+ pa[i]);
+ finish();
+ super.onCreate(null);
+ return;
+ }
+ targets[i] = (ChooserTarget) pa[i];
+ }
+ mCallerChooserTargets = targets;
+ }
mChosenComponentSender = intent.getParcelableExtra(
Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER);
setSafeForwardingMode(true);
@@ -94,9 +177,9 @@ public class ChooserActivity extends ResolverActivity {
}
@Override
- public void onActivityStarted(Intent intent) {
+ void onActivityStarted(TargetInfo cti) {
if (mChosenComponentSender != null) {
- final ComponentName target = intent.getComponent();
+ final ComponentName target = cti.getResolvedComponentName();
if (target != null) {
final Intent fillIn = new Intent().putExtra(Intent.EXTRA_CHOSEN_COMPONENT, target);
try {
@@ -109,6 +192,16 @@ public class ChooserActivity extends ResolverActivity {
}
}
+ @Override
+ int getLayoutResource() {
+ return com.android.internal.R.layout.chooser_grid;
+ }
+
+ @Override
+ boolean shouldGetActivityMetadata() {
+ return true;
+ }
+
private void modifyTargetIntent(Intent in) {
final String action = in.getAction();
if (Intent.ACTION_SEND.equals(action) ||
@@ -117,4 +210,297 @@ public class ChooserActivity extends ResolverActivity {
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
}
}
+
+ void queryTargetServices(ChooserListAdapter adapter) {
+ final PackageManager pm = getPackageManager();
+ int targetsToQuery = 0;
+ for (int i = 0, N = adapter.getDisplayResolveInfoCount(); i < N; i++) {
+ final DisplayResolveInfo dri = adapter.getDisplayResolveInfo(i);
+ final ActivityInfo ai = dri.getResolveInfo().activityInfo;
+ final Bundle md = ai.metaData;
+ final String serviceName = md != null ? convertServiceName(ai.packageName,
+ md.getString(ChooserTargetService.META_DATA_NAME)) : null;
+ if (serviceName != null) {
+ final ComponentName serviceComponent = new ComponentName(
+ ai.packageName, serviceName);
+ final Intent serviceIntent = new Intent(ChooserTargetService.SERVICE_INTERFACE)
+ .setComponent(serviceComponent);
+
+ if (DEBUG) {
+ Log.d(TAG, "queryTargets found target with service " + serviceComponent);
+ }
+
+ try {
+ final String perm = pm.getServiceInfo(serviceComponent, 0).permission;
+ if (!ChooserTargetService.BIND_PERMISSION.equals(perm)) {
+ Log.w(TAG, "ChooserTargetService " + serviceComponent + " does not require"
+ + " permission " + ChooserTargetService.BIND_PERMISSION
+ + " - this service will not be queried for ChooserTargets."
+ + " add android:permission=\""
+ + ChooserTargetService.BIND_PERMISSION + "\""
+ + " to the <service> tag for " + serviceComponent
+ + " in the manifest.");
+ continue;
+ }
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Could not look up service " + serviceComponent, e);
+ continue;
+ }
+
+ final ChooserTargetServiceConnection conn = new ChooserTargetServiceConnection(dri);
+ if (bindServiceAsUser(serviceIntent, conn, BIND_AUTO_CREATE | BIND_NOT_FOREGROUND,
+ UserHandle.CURRENT)) {
+ if (DEBUG) {
+ Log.d(TAG, "Binding service connection for target " + dri
+ + " intent " + serviceIntent);
+ }
+ mServiceConnections.add(conn);
+ targetsToQuery++;
+ }
+ }
+ if (targetsToQuery >= QUERY_TARGET_LIMIT) {
+ if (DEBUG) Log.d(TAG, "queryTargets hit query target limit " + QUERY_TARGET_LIMIT);
+ break;
+ }
+ }
+
+ if (!mServiceConnections.isEmpty()) {
+ if (DEBUG) Log.d(TAG, "queryTargets setting watchdog timer for "
+ + WATCHDOG_TIMEOUT_MILLIS + "ms");
+ mTargetResultHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT,
+ WATCHDOG_TIMEOUT_MILLIS);
+ }
+ }
+
+ private String convertServiceName(String packageName, String serviceName) {
+ if (TextUtils.isEmpty(serviceName)) {
+ return null;
+ }
+
+ final String fullName;
+ if (serviceName.startsWith(".")) {
+ // Relative to the app package. Prepend the app package name.
+ fullName = packageName + serviceName;
+ } else if (serviceName.indexOf('.') >= 0) {
+ // Fully qualified package name.
+ fullName = serviceName;
+ } else {
+ fullName = null;
+ }
+ return fullName;
+ }
+
+ void unbindRemainingServices() {
+ if (DEBUG) {
+ Log.d(TAG, "unbindRemainingServices, " + mServiceConnections.size() + " left");
+ }
+ for (int i = 0, N = mServiceConnections.size(); i < N; i++) {
+ final ChooserTargetServiceConnection conn = mServiceConnections.get(i);
+ if (DEBUG) Log.d(TAG, "unbinding " + conn);
+ unbindService(conn);
+ }
+ mServiceConnections.clear();
+ mTargetResultHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
+ }
+
+ @Override
+ ResolveListAdapter createAdapter(Context context, Intent[] initialIntents,
+ List<ResolveInfo> rList, int launchedFromUid, boolean filterLastUsed) {
+ final ChooserListAdapter adapter = new ChooserListAdapter(context, initialIntents, rList,
+ launchedFromUid, filterLastUsed);
+ if (DEBUG) Log.d(TAG, "Adapter created; querying services");
+ queryTargetServices(adapter);
+ return adapter;
+ }
+
+ class ChooserTargetInfo implements TargetInfo {
+ private final TargetInfo mSourceInfo;
+ private final ChooserTarget mChooserTarget;
+ private final Drawable mDisplayIcon;
+
+ public ChooserTargetInfo(TargetInfo sourceInfo, ChooserTarget chooserTarget) {
+ mSourceInfo = sourceInfo;
+ mChooserTarget = chooserTarget;
+ mDisplayIcon = new BitmapDrawable(getResources(), chooserTarget.getIcon());
+ }
+
+ @Override
+ public Intent getResolvedIntent() {
+ final Intent targetIntent = mChooserTarget.getIntent();
+ return targetIntent != null ? targetIntent : mSourceInfo.getResolvedIntent();
+ }
+
+ @Override
+ public ComponentName getResolvedComponentName() {
+ return mSourceInfo.getResolvedComponentName();
+ }
+
+ @Override
+ public boolean start(Activity activity, Bundle options) {
+ return mChooserTarget.sendIntent(activity, mSourceInfo.getResolvedIntent());
+ }
+
+ @Override
+ public boolean startAsCaller(Activity activity, Bundle options, int userId) {
+ return mChooserTarget.sendIntentAsCaller(activity, mSourceInfo.getResolvedIntent(),
+ userId);
+ }
+
+ @Override
+ public boolean startAsUser(Activity activity, Bundle options, UserHandle user) {
+ return mChooserTarget.sendIntentAsUser(activity, mSourceInfo.getResolvedIntent(), user);
+ }
+
+ @Override
+ public ResolveInfo getResolveInfo() {
+ return mSourceInfo.getResolveInfo();
+ }
+
+ @Override
+ public CharSequence getDisplayLabel() {
+ return mChooserTarget.getTitle();
+ }
+
+ @Override
+ public CharSequence getExtendedInfo() {
+ return mSourceInfo.getExtendedInfo();
+ }
+
+ @Override
+ public Drawable getDisplayIcon() {
+ return mDisplayIcon;
+ }
+ }
+
+ public class ChooserListAdapter extends ResolveListAdapter {
+ private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
+
+ public ChooserListAdapter(Context context, Intent[] initialIntents, List<ResolveInfo> rList,
+ int launchedFromUid, boolean filterLastUsed) {
+ super(context, initialIntents, rList, launchedFromUid, filterLastUsed);
+ }
+
+ @Override
+ public boolean showsExtendedInfo(TargetInfo info) {
+ // Reserve space to show extended info if any one of the items in the adapter has
+ // extended info. This keeps grid item sizes uniform.
+ return hasExtendedInfo();
+ }
+
+ @Override
+ public View createView(ViewGroup parent) {
+ return mInflater.inflate(
+ com.android.internal.R.layout.resolve_grid_item, parent, false);
+ }
+
+ @Override
+ public void onListRebuilt() {
+ if (mServiceTargets != null) {
+ pruneServiceTargets();
+ }
+ }
+
+ @Override
+ public int getCount() {
+ int count = super.getCount();
+ if (mServiceTargets != null) {
+ count += mServiceTargets.size();
+ }
+ return count;
+ }
+
+ @Override
+ public TargetInfo getItem(int position) {
+ int offset = 0;
+ if (mServiceTargets != null) {
+ final int serviceTargetCount = mServiceTargets.size();
+ if (position < serviceTargetCount) {
+ return mServiceTargets.get(position);
+ }
+ offset += serviceTargetCount;
+ }
+ return super.getItem(position - offset);
+ }
+
+ public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets) {
+ if (DEBUG) Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size()
+ + " targets");
+ for (int i = 0, N = targets.size(); i < N; i++) {
+ mServiceTargets.add(new ChooserTargetInfo(origTarget, targets.get(i)));
+ }
+
+ // TODO: Maintain sort by ranking scores.
+
+ notifyDataSetChanged();
+ }
+
+ private void pruneServiceTargets() {
+ if (DEBUG) Log.d(TAG, "pruneServiceTargets");
+ for (int i = mServiceTargets.size() - 1; i >= 0; i--) {
+ final ChooserTargetInfo cti = mServiceTargets.get(i);
+ if (!hasResolvedTarget(cti.getResolveInfo())) {
+ if (DEBUG) Log.d(TAG, " => " + i + " " + cti);
+ mServiceTargets.remove(i);
+ }
+ }
+ }
+ }
+
+ class ChooserTargetServiceConnection implements ServiceConnection {
+ private final DisplayResolveInfo mOriginalTarget;
+
+ private final IChooserTargetResult mChooserTargetResult = new IChooserTargetResult.Stub() {
+ @Override
+ public void sendResult(List<ChooserTarget> targets) throws RemoteException {
+ final Message msg = Message.obtain();
+ msg.what = CHOOSER_TARGET_SERVICE_RESULT;
+ msg.obj = new ServiceResultInfo(mOriginalTarget, targets,
+ ChooserTargetServiceConnection.this);
+ mTargetResultHandler.sendMessage(msg);
+ }
+ };
+
+ public ChooserTargetServiceConnection(DisplayResolveInfo dri) {
+ mOriginalTarget = dri;
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (DEBUG) Log.d(TAG, "onServiceConnected: " + name);
+ final IChooserTargetService icts = IChooserTargetService.Stub.asInterface(service);
+ try {
+ icts.getChooserTargets(mOriginalTarget.getResolvedComponentName(),
+ mOriginalTarget.getResolveInfo().filter, mChooserTargetResult);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Querying ChooserTargetService " + name + " failed.", e);
+ unbindService(this);
+ mServiceConnections.remove(this);
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ if (DEBUG) Log.d(TAG, "onServiceDisconnected: " + name);
+ unbindService(this);
+ mServiceConnections.remove(this);
+ }
+
+ @Override
+ public String toString() {
+ return mOriginalTarget.getResolveInfo().activityInfo.toString();
+ }
+ }
+
+ static class ServiceResultInfo {
+ public final DisplayResolveInfo originalTarget;
+ public final List<ChooserTarget> resultTargets;
+ public final ChooserTargetServiceConnection connection;
+
+ public ServiceResultInfo(DisplayResolveInfo ot, List<ChooserTarget> rt,
+ ChooserTargetServiceConnection c) {
+ originalTarget = ot;
+ resultTargets = rt;
+ connection = c;
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 6b35f3f..3cd69a1 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -25,6 +25,7 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.Slog;
import android.widget.AbsListView;
+import android.widget.GridView;
import com.android.internal.R;
import com.android.internal.content.PackageMonitor;
@@ -91,15 +92,14 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
private PackageManager mPm;
private boolean mSafeForwardingMode;
private boolean mAlwaysUseOption;
- private boolean mShowExtended;
+ private AbsListView mAdapterView;
private ListView mListView;
+ private GridView mGridView;
private Button mAlwaysButton;
private Button mOnceButton;
private View mProfileView;
private int mIconDpi;
- private int mIconSize;
- private int mMaxColumns;
- private int mLastSelected = ListView.INVALID_POSITION;
+ private int mLastSelected = AbsListView.INVALID_POSITION;
private boolean mResolvingHome = false;
private int mProfileSwitchMessageId = -1;
private Intent mIntent;
@@ -192,7 +192,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
/**
- * Compatibility version for other bundled services that use this ocerload without
+ * Compatibility version for other bundled services that use this overload without
* a default title resource
*/
protected void onCreate(Bundle savedInstanceState, Intent intent,
@@ -223,18 +223,14 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
final long sinceTime = System.currentTimeMillis() - USAGE_STATS_PERIOD;
mStats = mUsm.queryAndAggregateUsageStats(sinceTime, System.currentTimeMillis());
- mMaxColumns = getResources().getInteger(R.integer.config_maxResolverActivityColumns);
-
mPackageMonitor.register(this, getMainLooper(), false);
mRegistered = true;
final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
mIconDpi = am.getLauncherLargeIconDensity();
- mIconSize = am.getLauncherLargeIconSize();
mIntent = new Intent(intent);
- mAdapter = new ResolveListAdapter(this, initialIntents, rList,
- mLaunchedFromUid, alwaysUseOption);
+ mAdapter = createAdapter(this, initialIntents, rList, mLaunchedFromUid, alwaysUseOption);
final int layoutId;
final boolean useHeader;
@@ -244,7 +240,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
useHeader = true;
} else {
useHeader = false;
- layoutId = R.layout.resolver_list;
+ layoutId = getLayoutResource();
}
mAlwaysUseOption = alwaysUseOption;
@@ -257,21 +253,30 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
int count = mAdapter.mList.size();
if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) {
setContentView(layoutId);
- mListView = (ListView) findViewById(R.id.resolver_list);
- mListView.setAdapter(mAdapter);
- mListView.setOnItemClickListener(this);
- mListView.setOnItemLongClickListener(new ItemLongClickListener());
+ mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
+ mAdapterView.setAdapter(mAdapter);
+ mAdapterView.setOnItemClickListener(this);
+ mAdapterView.setOnItemLongClickListener(new ItemLongClickListener());
+
+ // Initialize the different types of collection views we may have. Depending
+ // on which ones are initialized later we'll configure different properties.
+ if (mAdapterView instanceof ListView) {
+ mListView = (ListView) mAdapterView;
+ }
+ if (mAdapterView instanceof GridView) {
+ mGridView = (GridView) mAdapterView;
+ }
if (alwaysUseOption) {
- mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ mAdapterView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
}
- if (useHeader) {
+ if (useHeader && mListView != null) {
mListView.addHeaderView(LayoutInflater.from(this).inflate(
R.layout.resolver_different_item_header, mListView, false));
}
} else if (count == 1) {
- safelyStartActivity(mAdapter.intentForPosition(0, false));
+ safelyStartActivity(mAdapter.targetInfoForPosition(0, false));
mPackageMonitor.unregister();
mRegistered = false;
finish();
@@ -282,8 +287,8 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
final TextView empty = (TextView) findViewById(R.id.empty);
empty.setVisibility(View.VISIBLE);
- mListView = (ListView) findViewById(R.id.resolver_list);
- mListView.setVisibility(View.GONE);
+ mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
+ mAdapterView.setVisibility(View.GONE);
}
// Prevent the Resolver window from becoming the top fullscreen window and thus from taking
// control of the system bars.
@@ -308,12 +313,30 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
titleView.setText(title);
}
setTitle(title);
+
+ // Try to initialize the title icon if we have a view for it and a title to match
+ final ImageView titleIcon = (ImageView) findViewById(R.id.title_icon);
+ if (titleIcon != null) {
+ final String referrerPackage = getReferrerPackageName();
+ ApplicationInfo ai = null;
+ try {
+ if (!TextUtils.isEmpty(referrerPackage)) {
+ ai = mPm.getApplicationInfo(referrerPackage, 0);
+ }
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Could not find referrer package " + referrerPackage);
+ }
+
+ if (ai != null) {
+ titleIcon.setImageDrawable(ai.loadIcon(mPm));
+ }
+ }
}
final ImageView iconView = (ImageView) findViewById(R.id.icon);
final DisplayResolveInfo iconInfo = mAdapter.getFilteredItem();
if (iconView != null && iconInfo != null) {
- new LoadIconIntoViewTask(iconView).execute(iconInfo);
+ new LoadIconIntoViewTask(iconInfo, iconView).execute();
}
if (alwaysUseOption || mAdapter.hasFilteredItem()) {
@@ -345,8 +368,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
// Do not show the profile switch message anymore.
mProfileSwitchMessageId = -1;
- final Intent intent = intentForDisplayResolveInfo(dri);
- onIntentSelected(dri.ri, intent, false);
+ onTargetSelected(dri, false);
finish();
}
});
@@ -354,17 +376,29 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
}
+ private String getReferrerPackageName() {
+ final Uri referrer = getReferrer();
+ if (referrer != null && "android-app".equals(referrer.getScheme())) {
+ return referrer.getHost();
+ }
+ return null;
+ }
+
+ int getLayoutResource() {
+ return R.layout.resolver_list;
+ }
+
void bindProfileView() {
final DisplayResolveInfo dri = mAdapter.getOtherProfile();
if (dri != null) {
mProfileView.setVisibility(View.VISIBLE);
final ImageView icon = (ImageView) mProfileView.findViewById(R.id.icon);
final TextView text = (TextView) mProfileView.findViewById(R.id.text1);
- if (dri.displayIcon == null) {
- new LoadIconTask().execute(dri);
+ if (!dri.hasDisplayIcon()) {
+ new LoadIconIntoViewTask(dri, icon).execute();
}
- icon.setImageDrawable(dri.displayIcon);
- text.setText(dri.displayLabel);
+ icon.setImageDrawable(dri.getDisplayIcon());
+ text.setText(dri.getDisplayLabel());
} else {
mProfileView.setVisibility(View.GONE);
}
@@ -408,8 +442,9 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
if (title == ActionTitle.DEFAULT && defaultTitleRes != 0) {
return getString(defaultTitleRes);
} else {
- return named ? getString(title.namedTitleRes, mAdapter.getFilteredItem().displayLabel) :
- getString(title.titleRes);
+ return named
+ ? getString(title.namedTitleRes, mAdapter.getFilteredItem().getDisplayLabel())
+ : getString(title.titleRes);
}
}
@@ -490,31 +525,33 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (mAlwaysUseOption) {
- final int checkedPos = mListView.getCheckedItemPosition();
+ final int checkedPos = mAdapterView.getCheckedItemPosition();
final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
mLastSelected = checkedPos;
setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
mOnceButton.setEnabled(hasValidSelection);
if (hasValidSelection) {
- mListView.setSelection(checkedPos);
+ mAdapterView.setSelection(checkedPos);
}
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- position -= mListView.getHeaderViewsCount();
+ if (mListView != null) {
+ position -= mListView.getHeaderViewsCount();
+ }
if (position < 0) {
// Header views don't count.
return;
}
- final int checkedPos = mListView.getCheckedItemPosition();
+ final int checkedPos = mAdapterView.getCheckedItemPosition();
final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
if (mAlwaysUseOption && (!hasValidSelection || mLastSelected != checkedPos)) {
setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
mOnceButton.setEnabled(hasValidSelection);
if (hasValidSelection) {
- mListView.smoothScrollToPosition(checkedPos);
+ mAdapterView.smoothScrollToPosition(checkedPos);
}
mLastSelected = checkedPos;
} else {
@@ -570,7 +607,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
public void onButtonClick(View v) {
final int id = v.getId();
startSelected(mAlwaysUseOption ?
- mListView.getCheckedItemPosition() : mAdapter.getFilteredPosition(),
+ mAdapterView.getCheckedItemPosition() : mAdapter.getFilteredPosition(),
id == R.id.button_always,
mAlwaysUseOption);
}
@@ -588,8 +625,8 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
return;
}
- Intent intent = mAdapter.intentForPosition(which, filtered);
- onIntentSelected(ri, intent, always);
+ TargetInfo target = mAdapter.targetInfoForPosition(which, filtered);
+ onTargetSelected(target, always);
finish();
}
@@ -600,8 +637,12 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
return defIntent;
}
- protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
- if ((mAlwaysUseOption || mAdapter.hasFilteredItem()) && mAdapter.mOrigResolveList != null) {
+ protected void onTargetSelected(TargetInfo target, boolean alwaysCheck) {
+ final ResolveInfo ri = target.getResolveInfo();
+ final Intent intent = target != null ? target.getResolvedIntent() : null;
+
+ if (intent != null && (mAlwaysUseOption || mAdapter.hasFilteredItem())
+ && mAdapter.mOrigResolveList != null) {
// Build a reasonable intent filter, based on what matched.
IntentFilter filter = new IntentFilter();
String action = intent.getAction();
@@ -617,7 +658,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
filter.addCategory(Intent.CATEGORY_DEFAULT);
- int cat = ri.match&IntentFilter.MATCH_CATEGORY_MASK;
+ int cat = ri.match & IntentFilter.MATCH_CATEGORY_MASK;
Uri data = intent.getData();
if (cat == IntentFilter.MATCH_CATEGORY_TYPE) {
String mimeType = intent.resolveType(this);
@@ -726,25 +767,27 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
}
- if (intent != null) {
- safelyStartActivity(intent);
+ if (target != null) {
+ safelyStartActivity(target);
}
}
- public void safelyStartActivity(Intent intent) {
+ void safelyStartActivity(TargetInfo cti) {
// If needed, show that intent is forwarded
// from managed profile to owner or other way around.
if (mProfileSwitchMessageId != -1) {
Toast.makeText(this, getString(mProfileSwitchMessageId), Toast.LENGTH_LONG).show();
}
if (!mSafeForwardingMode) {
- startActivity(intent);
- onActivityStarted(intent);
+ if (cti.start(this, null)) {
+ onActivityStarted(cti);
+ }
return;
}
try {
- startActivityAsCaller(intent, null, UserHandle.USER_NULL);
- onActivityStarted(intent);
+ if (cti.startAsCaller(this, null, UserHandle.USER_NULL)) {
+ onActivityStarted(cti);
+ }
} catch (RuntimeException e) {
String launchedFromPackage;
try {
@@ -759,51 +802,197 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
}
- public void onActivityStarted(Intent intent) {
+ void onActivityStarted(TargetInfo cti) {
// Do nothing
}
+ boolean shouldGetActivityMetadata() {
+ return false;
+ }
+
void showAppDetails(ResolveInfo ri) {
Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.fromParts("package", ri.activityInfo.packageName, null))
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
startActivity(in);
}
- Intent intentForDisplayResolveInfo(DisplayResolveInfo dri) {
- Intent intent = new Intent(dri.origIntent != null ? dri.origIntent :
- getReplacementIntent(dri.ri.activityInfo, mIntent));
- intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
- |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
- ActivityInfo ai = dri.ri.activityInfo;
- intent.setComponent(new ComponentName(
- ai.applicationInfo.packageName, ai.name));
- return intent;
+ ResolveListAdapter createAdapter(Context context, Intent[] initialIntents,
+ List<ResolveInfo> rList, int launchedFromUid, boolean filterLastUsed) {
+ return new ResolveListAdapter(context, initialIntents, rList, launchedFromUid,
+ filterLastUsed);
+ }
+
+ ResolveListAdapter getAdapter() {
+ return mAdapter;
}
- private final class DisplayResolveInfo {
- ResolveInfo ri;
- CharSequence displayLabel;
- Drawable displayIcon;
- CharSequence extendedInfo;
- Intent origIntent;
+ final class DisplayResolveInfo implements TargetInfo {
+ private final ResolveInfo mResolveInfo;
+ private final CharSequence mDisplayLabel;
+ private Drawable mDisplayIcon;
+ private final CharSequence mExtendedInfo;
+ private final Intent mResolvedIntent;
DisplayResolveInfo(ResolveInfo pri, CharSequence pLabel,
CharSequence pInfo, Intent pOrigIntent) {
- ri = pri;
- displayLabel = pLabel;
- extendedInfo = pInfo;
- origIntent = pOrigIntent;
+ mResolveInfo = pri;
+ mDisplayLabel = pLabel;
+ mExtendedInfo = pInfo;
+
+ final Intent intent = new Intent(pOrigIntent != null ? pOrigIntent :
+ getReplacementIntent(pri.activityInfo, mIntent));
+ intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
+ | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
+ final ActivityInfo ai = mResolveInfo.activityInfo;
+ intent.setComponent(new ComponentName(ai.applicationInfo.packageName, ai.name));
+
+ mResolvedIntent = intent;
+ }
+
+ public ResolveInfo getResolveInfo() {
+ return mResolveInfo;
+ }
+
+ public CharSequence getDisplayLabel() {
+ return mDisplayLabel;
+ }
+
+ public Drawable getDisplayIcon() {
+ return mDisplayIcon;
+ }
+
+ public void setDisplayIcon(Drawable icon) {
+ mDisplayIcon = icon;
+ }
+
+ public boolean hasDisplayIcon() {
+ return mDisplayIcon != null;
+ }
+
+ public CharSequence getExtendedInfo() {
+ return mExtendedInfo;
+ }
+
+ public Intent getResolvedIntent() {
+ return mResolvedIntent;
+ }
+
+ @Override
+ public ComponentName getResolvedComponentName() {
+ return new ComponentName(mResolveInfo.activityInfo.packageName,
+ mResolveInfo.activityInfo.name);
+ }
+
+ @Override
+ public boolean start(Activity activity, Bundle options) {
+ activity.startActivity(mResolvedIntent, options);
+ return true;
}
+
+ @Override
+ public boolean startAsCaller(Activity activity, Bundle options, int userId) {
+ activity.startActivityAsCaller(mResolvedIntent, options, userId);
+ return true;
+ }
+
+ @Override
+ public boolean startAsUser(Activity activity, Bundle options, UserHandle user) {
+ activity.startActivityAsUser(mResolvedIntent, options, user);
+ return false;
+ }
+ }
+
+ /**
+ * A single target as represented in the chooser.
+ */
+ public interface TargetInfo {
+ /**
+ * Get the resolved intent that represents this target. Note that this may not be the
+ * intent that will be launched by calling one of the <code>start</code> methods provided;
+ * this is the intent that will be credited with the launch.
+ *
+ * @return the resolved intent for this target
+ */
+ public Intent getResolvedIntent();
+
+ /**
+ * Get the resolved component name that represents this target. Note that this may not
+ * be the component that will be directly launched by calling one of the <code>start</code>
+ * methods provided; this is the component that will be credited with the launch.
+ *
+ * @return the resolved ComponentName for this target
+ */
+ public ComponentName getResolvedComponentName();
+
+ /**
+ * Start the activity referenced by this target.
+ *
+ * @param activity calling Activity performing the launch
+ * @param options ActivityOptions bundle
+ * @return true if the start completed successfully
+ */
+ public boolean start(Activity activity, Bundle options);
+
+ /**
+ * Start the activity referenced by this target as if the ResolverActivity's caller
+ * was performing the start operation.
+ *
+ * @param activity calling Activity (actually) performing the launch
+ * @param options ActivityOptions bundle
+ * @param userId userId to start as or {@link UserHandle#USER_NULL} for activity's caller
+ * @return true if the start completed successfully
+ */
+ public boolean startAsCaller(Activity activity, Bundle options, int userId);
+
+ /**
+ * Start the activity referenced by this target as a given user.
+ *
+ * @param activity calling activity performing the launch
+ * @param options ActivityOptions bundle
+ * @param user handle for the user to start the activity as
+ * @return true if the start completed successfully
+ */
+ public boolean startAsUser(Activity activity, Bundle options, UserHandle user);
+
+ /**
+ * Return the ResolveInfo about how and why this target matched the original query
+ * for available targets.
+ *
+ * @return ResolveInfo representing this target's match
+ */
+ public ResolveInfo getResolveInfo();
+
+ /**
+ * Return the human-readable text label for this target.
+ *
+ * @return user-visible target label
+ */
+ public CharSequence getDisplayLabel();
+
+ /**
+ * Return any extended info for this target. This may be used to disambiguate
+ * otherwise identical targets.
+ *
+ * @return human-readable disambig string or null if none present
+ */
+ public CharSequence getExtendedInfo();
+
+ /**
+ * @return The drawable that should be used to represent this target
+ */
+ public Drawable getDisplayIcon();
}
- private final class ResolveListAdapter extends BaseAdapter {
+ class ResolveListAdapter extends BaseAdapter {
private final Intent[] mInitialIntents;
private final List<ResolveInfo> mBaseResolveList;
private ResolveInfo mLastChosen;
private DisplayResolveInfo mOtherProfile;
private final int mLaunchedFromUid;
- private final LayoutInflater mInflater;
+ private boolean mHasExtendedInfo;
+
+ protected final LayoutInflater mInflater;
List<DisplayResolveInfo> mList;
List<ResolveInfo> mOrigResolveList;
@@ -817,7 +1006,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
mBaseResolveList = rList;
mLaunchedFromUid = launchedFromUid;
mInflater = LayoutInflater.from(context);
- mList = new ArrayList<DisplayResolveInfo>();
+ mList = new ArrayList<>();
mFilterLastUsed = filterLastUsed;
rebuildList();
}
@@ -871,9 +1060,11 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
if (mBaseResolveList != null) {
currentResolveList = mOrigResolveList = mBaseResolveList;
} else {
- currentResolveList = mOrigResolveList = mPm.queryIntentActivities(
- mIntent, PackageManager.MATCH_DEFAULT_ONLY
- | (mFilterLastUsed ? PackageManager.GET_RESOLVED_FILTER : 0));
+ currentResolveList = mOrigResolveList = mPm.queryIntentActivities(mIntent,
+ PackageManager.MATCH_DEFAULT_ONLY
+ | (mFilterLastUsed ? PackageManager.GET_RESOLVED_FILTER : 0)
+ | (shouldGetActivityMetadata() ? PackageManager.GET_META_DATA : 0)
+ );
// Filter out any activities that the launched uid does not
// have permission for. We don't do this when we have an explicit
// list of resolved activities, because that only happens when
@@ -961,7 +1152,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
r0 = currentResolveList.get(0);
int start = 0;
CharSequence r0Label = r0.loadLabel(mPm);
- mShowExtended = false;
+ mHasExtendedInfo = false;
for (int i = 1; i < N; i++) {
if (r0Label == null) {
r0Label = r0.activityInfo.packageName;
@@ -989,6 +1180,12 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
mLastChosenPosition = -1;
mFilterLastUsed = false;
}
+
+ onListRebuilt();
+ }
+
+ public void onListRebuilt() {
+ // This space for rent
}
private void processGroup(List<ResolveInfo> rList, int start, int end, ResolveInfo ro,
@@ -1000,7 +1197,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
addResolveInfo(new DisplayResolveInfo(ro, roLabel, null, null));
updateLastChosenPosition(ro);
} else {
- mShowExtended = true;
+ mHasExtendedInfo = true;
boolean usePkg = false;
CharSequence startApp = ro.activityInfo.applicationInfo.loadLabel(mPm);
if (startApp == null) {
@@ -1049,7 +1246,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
private void addResolveInfo(DisplayResolveInfo dri) {
- if (dri.ri.targetUserId != UserHandle.USER_CURRENT && mOtherProfile == null) {
+ if (dri.mResolveInfo.targetUserId != UserHandle.USER_CURRENT && mOtherProfile == null) {
// So far we only support a single other profile at a time.
// The first one we see gets special treatment.
mOtherProfile = dri;
@@ -1059,12 +1256,11 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
public ResolveInfo resolveInfoForPosition(int position, boolean filtered) {
- return (filtered ? getItem(position) : mList.get(position)).ri;
+ return (filtered ? getItem(position) : mList.get(position)).getResolveInfo();
}
- public Intent intentForPosition(int position, boolean filtered) {
- DisplayResolveInfo dri = filtered ? getItem(position) : mList.get(position);
- return intentForDisplayResolveInfo(dri);
+ public TargetInfo targetInfoForPosition(int position, boolean filtered) {
+ return filtered ? getItem(position) : mList.get(position);
}
public int getCount() {
@@ -1075,7 +1271,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
return result;
}
- public DisplayResolveInfo getItem(int position) {
+ public TargetInfo getItem(int position) {
if (mFilterLastUsed && mLastChosenPosition >= 0 && position >= mLastChosenPosition) {
position++;
}
@@ -1086,11 +1282,31 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
return position;
}
- public View getView(int position, View convertView, ViewGroup parent) {
+ public boolean hasExtendedInfo() {
+ return mHasExtendedInfo;
+ }
+
+ public boolean hasResolvedTarget(ResolveInfo info) {
+ for (int i = 0, N = mList.size(); i < N; i++) {
+ if (info.equals(mList.get(i).getResolveInfo())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected int getDisplayResolveInfoCount() {
+ return mList.size();
+ }
+
+ protected DisplayResolveInfo getDisplayResolveInfo(int index) {
+ return mList.get(index);
+ }
+
+ public final View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
- view = mInflater.inflate(
- com.android.internal.R.layout.resolve_list_item, parent, false);
+ view = createView(parent);
final ViewHolder holder = new ViewHolder(view);
view.setTag(holder);
@@ -1099,19 +1315,29 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
return view;
}
- private final void bindView(View view, DisplayResolveInfo info) {
+ public View createView(ViewGroup parent) {
+ return mInflater.inflate(
+ com.android.internal.R.layout.resolve_list_item, parent, false);
+ }
+
+ public boolean showsExtendedInfo(TargetInfo info) {
+ return !TextUtils.isEmpty(info.getExtendedInfo());
+ }
+
+ private final void bindView(View view, TargetInfo info) {
final ViewHolder holder = (ViewHolder) view.getTag();
- holder.text.setText(info.displayLabel);
- if (mShowExtended) {
+ holder.text.setText(info.getDisplayLabel());
+ if (showsExtendedInfo(info)) {
holder.text2.setVisibility(View.VISIBLE);
- holder.text2.setText(info.extendedInfo);
+ holder.text2.setText(info.getExtendedInfo());
} else {
holder.text2.setVisibility(View.GONE);
}
- if (info.displayIcon == null) {
- new LoadIconTask().execute(info);
+ if (info instanceof DisplayResolveInfo
+ && !((DisplayResolveInfo) info).hasDisplayIcon()) {
+ new LoadAdapterIconTask((DisplayResolveInfo) info).execute();
}
- holder.icon.setImageDrawable(info.displayIcon);
+ holder.icon.setImageDrawable(info.getDisplayIcon());
}
}
@@ -1131,7 +1357,9 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
- position -= mListView.getHeaderViewsCount();
+ if (mListView != null) {
+ position -= mListView.getHeaderViewsCount();
+ }
if (position < 0) {
// Header views don't count.
return false;
@@ -1143,44 +1371,53 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
- class LoadIconTask extends AsyncTask<DisplayResolveInfo, Void, DisplayResolveInfo> {
+ abstract class LoadIconTask extends AsyncTask<Void, Void, Drawable> {
+ protected final DisplayResolveInfo mDisplayResolveInfo;
+ private final ResolveInfo mResolveInfo;
+
+ public LoadIconTask(DisplayResolveInfo dri) {
+ mDisplayResolveInfo = dri;
+ mResolveInfo = dri.getResolveInfo();
+ }
+
@Override
- protected DisplayResolveInfo doInBackground(DisplayResolveInfo... params) {
- final DisplayResolveInfo info = params[0];
- if (info.displayIcon == null) {
- info.displayIcon = loadIconForResolveInfo(info.ri);
- }
- return info;
+ protected Drawable doInBackground(Void... params) {
+ return loadIconForResolveInfo(mResolveInfo);
+ }
+
+ @Override
+ protected void onPostExecute(Drawable d) {
+ mDisplayResolveInfo.setDisplayIcon(d);
+ }
+ }
+
+ class LoadAdapterIconTask extends LoadIconTask {
+ public LoadAdapterIconTask(DisplayResolveInfo dri) {
+ super(dri);
}
@Override
- protected void onPostExecute(DisplayResolveInfo info) {
- if (mProfileView != null && mAdapter.getOtherProfile() == info) {
+ protected void onPostExecute(Drawable d) {
+ super.onPostExecute(d);
+ if (mProfileView != null && mAdapter.getOtherProfile() == mDisplayResolveInfo) {
bindProfileView();
}
mAdapter.notifyDataSetChanged();
}
}
- class LoadIconIntoViewTask extends AsyncTask<DisplayResolveInfo, Void, DisplayResolveInfo> {
- final ImageView mTargetView;
+ class LoadIconIntoViewTask extends LoadIconTask {
+ private final ImageView mTargetView;
- public LoadIconIntoViewTask(ImageView target) {
+ public LoadIconIntoViewTask(DisplayResolveInfo dri, ImageView target) {
+ super(dri);
mTargetView = target;
}
@Override
- protected DisplayResolveInfo doInBackground(DisplayResolveInfo... params) {
- final DisplayResolveInfo info = params[0];
- if (info.displayIcon == null) {
- info.displayIcon = loadIconForResolveInfo(info.ri);
- }
- return info;
- }
-
- @Override
- protected void onPostExecute(DisplayResolveInfo info) {
- mTargetView.setImageDrawable(info.displayIcon);
+ protected void onPostExecute(Drawable d) {
+ super.onPostExecute(d);
+ mTargetView.setImageDrawable(d);
}
}
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index e32a3a2..22d35f2 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -45,8 +45,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashSet;
-import static android.system.OsConstants.*;
+import static android.system.OsConstants.SEEK_CUR;
/**
* Backup transport for stashing stuff into a known location on disk, and
@@ -284,8 +283,10 @@ public class LocalTransport extends BackupTransport {
private int tearDownFullBackup() {
if (mSocket != null) {
try {
- mFullBackupOutputStream.flush();
- mFullBackupOutputStream.close();
+ if (mFullBackupOutputStream != null) {
+ mFullBackupOutputStream.flush();
+ mFullBackupOutputStream.close();
+ }
mSocketInputStream = null;
mFullTargetPackage = null;
mSocket.close();
@@ -296,6 +297,7 @@ public class LocalTransport extends BackupTransport {
return TRANSPORT_ERROR;
} finally {
mSocket = null;
+ mFullBackupOutputStream = null;
}
}
return TRANSPORT_OK;
@@ -311,6 +313,18 @@ public class LocalTransport extends BackupTransport {
}
@Override
+ public int checkFullBackupSize(long size) {
+ // Decline zero-size "backups"
+ final int result = (size > 0) ? TRANSPORT_OK : TRANSPORT_PACKAGE_REJECTED;
+ if (result != TRANSPORT_OK) {
+ if (DEBUG) {
+ Log.v(TAG, "Declining backup of size " + size);
+ }
+ }
+ return result;
+ }
+
+ @Override
public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket) {
if (mSocket != null) {
Log.e(TAG, "Attempt to initiate full backup while one is in progress");
@@ -333,22 +347,14 @@ public class LocalTransport extends BackupTransport {
}
mFullTargetPackage = targetPackage.packageName;
- FileOutputStream tarstream;
- try {
- File tarball = tarballFile(mFullTargetPackage);
- tarstream = new FileOutputStream(tarball);
- } catch (FileNotFoundException e) {
- return TRANSPORT_ERROR;
- }
- mFullBackupOutputStream = new BufferedOutputStream(tarstream);
mFullBackupBuffer = new byte[4096];
return TRANSPORT_OK;
}
@Override
- public int sendBackupData(int numBytes) {
- if (mFullBackupBuffer == null) {
+ public int sendBackupData(final int numBytes) {
+ if (mSocket == null) {
Log.w(TAG, "Attempted sendBackupData before performFullBackup");
return TRANSPORT_ERROR;
}
@@ -356,16 +362,29 @@ public class LocalTransport extends BackupTransport {
if (numBytes > mFullBackupBuffer.length) {
mFullBackupBuffer = new byte[numBytes];
}
- while (numBytes > 0) {
+
+ if (mFullBackupOutputStream == null) {
+ FileOutputStream tarstream;
+ try {
+ File tarball = tarballFile(mFullTargetPackage);
+ tarstream = new FileOutputStream(tarball);
+ } catch (FileNotFoundException e) {
+ return TRANSPORT_ERROR;
+ }
+ mFullBackupOutputStream = new BufferedOutputStream(tarstream);
+ }
+
+ int bytesLeft = numBytes;
+ while (bytesLeft > 0) {
try {
- int nRead = mSocketInputStream.read(mFullBackupBuffer, 0, numBytes);
+ int nRead = mSocketInputStream.read(mFullBackupBuffer, 0, bytesLeft);
if (nRead < 0) {
// Something went wrong if we expect data but saw EOD
Log.w(TAG, "Unexpected EOD; failing backup");
return TRANSPORT_ERROR;
}
mFullBackupOutputStream.write(mFullBackupBuffer, 0, nRead);
- numBytes -= nRead;
+ bytesLeft -= nRead;
} catch (IOException e) {
Log.e(TAG, "Error handling backup data for " + mFullTargetPackage);
return TRANSPORT_ERROR;
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index 6be6389..24b5d0d 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -26,9 +26,10 @@ import android.os.Build;
*/
public class MetricsLogger implements MetricsConstants {
// These constants are temporary, they should migrate to MetricsConstants.
- // next value is 145;
+ // next value is 146;
public static final int NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
+ public static final int NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145;
public static void visible(Context context, int category) throws IllegalArgumentException {
if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 7e6706c..1efa565 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -316,7 +316,7 @@ public class PowerProfile {
final Double[] values = (Double[]) data;
if (values.length > level && level >= 0) {
return values[level];
- } else if (level < 0) {
+ } else if (level < 0 || values.length == 0) {
return 0;
} else {
return values[values.length - 1];
diff --git a/core/java/com/android/internal/transition/ActionBarTransition.java b/core/java/com/android/internal/transition/ActionBarTransition.java
deleted file mode 100644
index c1065e7..0000000
--- a/core/java/com/android/internal/transition/ActionBarTransition.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2013 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.transition;
-
-import android.transition.ChangeBounds;
-import android.transition.Fade;
-import android.transition.ChangeText;
-import android.transition.Transition;
-import android.transition.TransitionManager;
-import android.transition.TransitionSet;
-import android.view.ViewGroup;
-
-public class ActionBarTransition {
-
- private static boolean TRANSITIONS_ENABLED = false;
-
- private static final int TRANSITION_DURATION = 120; // ms
-
- private static final Transition sTransition;
-
- static {
- if (TRANSITIONS_ENABLED) {
- final ChangeText tc = new ChangeText();
- tc.setChangeBehavior(ChangeText.CHANGE_BEHAVIOR_OUT_IN);
- final TransitionSet inner = new TransitionSet();
- inner.addTransition(tc).addTransition(new ChangeBounds());
- final TransitionSet tg = new TransitionSet();
- tg.addTransition(new Fade(Fade.OUT)).addTransition(inner).
- addTransition(new Fade(Fade.IN));
- tg.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
- tg.setDuration(TRANSITION_DURATION);
- sTransition = tg;
- } else {
- sTransition = null;
- }
- }
-
- public static void beginDelayedTransition(ViewGroup sceneRoot) {
- if (TRANSITIONS_ENABLED) {
- TransitionManager.beginDelayedTransition(sceneRoot, sTransition);
- }
- }
-}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 88436f8..6b781c3 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -49,7 +49,6 @@ import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import com.android.internal.R;
-import com.android.internal.transition.ActionBarTransition;
import com.android.internal.view.menu.ActionMenuItem;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.view.menu.MenuItemImpl;
@@ -459,9 +458,6 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar {
public void setCustomView(View view) {
final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0;
- if (showCustom) {
- ActionBarTransition.beginDelayedTransition(this);
- }
if (mCustomNavView != null && showCustom) {
removeView(mCustomNavView);
}
@@ -499,7 +495,6 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar {
}
private void setTitleImpl(CharSequence title) {
- ActionBarTransition.beginDelayedTransition(this);
mTitle = title;
if (mTitleView != null) {
mTitleView.setText(title);
@@ -519,7 +514,6 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar {
}
public void setSubtitle(CharSequence subtitle) {
- ActionBarTransition.beginDelayedTransition(this);
mSubtitle = subtitle;
if (mSubtitleView != null) {
mSubtitleView.setText(subtitle);
@@ -604,7 +598,6 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar {
mDisplayOptions = options;
if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) {
- ActionBarTransition.beginDelayedTransition(this);
if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0;
@@ -706,7 +699,6 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar {
public void setNavigationMode(int mode) {
final int oldMode = mNavigationMode;
if (mode != oldMode) {
- ActionBarTransition.beginDelayedTransition(this);
switch (oldMode) {
case ActionBar.NAVIGATION_MODE_LIST:
if (mListNavLayout != null) {
@@ -836,7 +828,6 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar {
}
}
- ActionBarTransition.beginDelayedTransition(this);
mUpGoerFive.addView(mTitleLayout);
if (mExpandedActionView != null ||
(TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) {
@@ -1659,7 +1650,6 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar {
@Override
public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
- ActionBarTransition.beginDelayedTransition(ActionBarView.this);
mExpandedActionView = item.getActionView();
mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(getResources()));
@@ -1688,7 +1678,6 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar {
@Override
public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
- ActionBarTransition.beginDelayedTransition(ActionBarView.this);
// Do this before detaching the actionview from the hierarchy, in case
// it needs to dismiss the soft keyboard, etc.
diff --git a/core/java/com/android/internal/widget/DialogViewAnimator.java b/core/java/com/android/internal/widget/DialogViewAnimator.java
new file mode 100644
index 0000000..bdfc1af
--- /dev/null
+++ b/core/java/com/android/internal/widget/DialogViewAnimator.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2015 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.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ViewAnimator;
+
+import java.util.ArrayList;
+
+/**
+ * ViewAnimator with a more reasonable handling of MATCH_PARENT.
+ */
+public class DialogViewAnimator extends ViewAnimator {
+ private final ArrayList<View> mMatchParentChildren = new ArrayList<>(1);
+
+ public DialogViewAnimator(Context context) {
+ super(context);
+ }
+
+ public DialogViewAnimator(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ final boolean measureMatchParentChildren =
+ MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY ||
+ MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
+
+ int maxHeight = 0;
+ int maxWidth = 0;
+ int childState = 0;
+
+ // First measure all children and record maximum dimensions where the
+ // spec isn't MATCH_PARENT.
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (getMeasureAllChildren() || child.getVisibility() != GONE) {
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final boolean matchWidth = lp.width == LayoutParams.MATCH_PARENT;
+ final boolean matchHeight = lp.height == LayoutParams.MATCH_PARENT;
+ if (measureMatchParentChildren && (matchWidth || matchHeight)) {
+ mMatchParentChildren.add(child);
+ }
+
+ measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
+
+ // Measured dimensions only count against the maximum
+ // dimensions if they're not MATCH_PARENT.
+ int state = 0;
+
+ if (measureMatchParentChildren && !matchWidth) {
+ maxWidth = Math.max(maxWidth, child.getMeasuredWidth()
+ + lp.leftMargin + lp.rightMargin);
+ state |= child.getMeasuredWidthAndState() & MEASURED_STATE_MASK;
+ }
+
+ if (measureMatchParentChildren && !matchHeight) {
+ maxHeight = Math.max(maxHeight, child.getMeasuredHeight()
+ + lp.topMargin + lp.bottomMargin);
+ state |= (child.getMeasuredHeightAndState() >> MEASURED_HEIGHT_STATE_SHIFT)
+ & (MEASURED_STATE_MASK >> MEASURED_HEIGHT_STATE_SHIFT);
+ }
+
+ childState = combineMeasuredStates(childState, state);
+ }
+ }
+
+ // Account for padding too.
+ maxWidth += getPaddingLeft() + getPaddingRight();
+ maxHeight += getPaddingTop() + getPaddingBottom();
+
+ // Check against our minimum height and width.
+ maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
+ maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
+
+ // Check against our foreground's minimum height and width.
+ final Drawable drawable = getForeground();
+ if (drawable != null) {
+ maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
+ maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
+ }
+
+ setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
+ resolveSizeAndState(maxHeight, heightMeasureSpec,
+ childState << MEASURED_HEIGHT_STATE_SHIFT));
+
+ // Measure remaining MATCH_PARENT children again using real dimensions.
+ final int matchCount = mMatchParentChildren.size();
+ for (int i = 0; i < matchCount; i++) {
+ final View child = mMatchParentChildren.get(i);
+ final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
+
+ final int childWidthMeasureSpec;
+ if (lp.width == LayoutParams.MATCH_PARENT) {
+ childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ getMeasuredWidth() - getPaddingLeft() - getPaddingRight()
+ - lp.leftMargin - lp.rightMargin,
+ MeasureSpec.EXACTLY);
+ } else {
+ childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
+ getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin,
+ lp.width);
+ }
+
+ final int childHeightMeasureSpec;
+ if (lp.height == LayoutParams.MATCH_PARENT) {
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ getMeasuredHeight() - getPaddingTop() - getPaddingBottom()
+ - lp.topMargin - lp.bottomMargin,
+ MeasureSpec.EXACTLY);
+ } else {
+ childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+ getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin,
+ lp.height);
+ }
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+
+ mMatchParentChildren.clear();
+ }
+}
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index 8d66191..5c08daf 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -889,7 +889,7 @@ public class ViewPager extends ViewGroup {
}
}
- void populate() {
+ public void populate() {
populate(mCurItem);
}
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 4c4a39d..d4069a1 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -261,7 +261,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
SkBitmap* outputBitmap = NULL;
unsigned int existingBufferSize = 0;
if (javaBitmap != NULL) {
- outputBitmap = GraphicsJNI::getSkBitmap(env, javaBitmap);
+ outputBitmap = GraphicsJNI::getSkBitmapDeprecated(env, javaBitmap);
if (outputBitmap->isImmutable()) {
ALOGW("Unable to reuse an immutable bitmap as an image decoder target.");
javaBitmap = NULL;
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index 3525d07..aeea808 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -217,7 +217,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle,
if (tileBitmap != NULL) {
// Re-use bitmap.
- bitmap = GraphicsJNI::getSkBitmap(env, tileBitmap);
+ bitmap = GraphicsJNI::getSkBitmapDeprecated(env, tileBitmap);
}
if (bitmap == NULL) {
bitmap = new SkBitmap;
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 0747969..f0bd5dd 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -338,7 +338,7 @@ SkColorType GraphicsJNI::legacyBitmapConfigToColorType(jint legacyConfig) {
return static_cast<SkColorType>(gConfig2ColorType[legacyConfig]);
}
-SkBitmap* GraphicsJNI::getSkBitmap(JNIEnv* env, jobject bitmap) {
+SkBitmap* GraphicsJNI::getSkBitmapDeprecated(JNIEnv* env, jobject bitmap) {
SkASSERT(env);
SkASSERT(bitmap);
SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
@@ -348,6 +348,21 @@ SkBitmap* GraphicsJNI::getSkBitmap(JNIEnv* env, jobject bitmap) {
return b;
}
+void GraphicsJNI::getSkBitmap(JNIEnv* env, jobject bitmap, SkBitmap* outBitmap) {
+ SkPixelRef* pixelRef = getSkPixelRef(env, bitmap);
+ // TODO: pixelRef->rowBytes() is only valid if the pixels are locked
+ // (which is currently always true on android), switch this to querying
+ // from the wrapper once that exists instead
+ outBitmap->setInfo(pixelRef->info(), pixelRef->rowBytes());
+ outBitmap->setPixelRef(pixelRef);
+}
+
+SkPixelRef* GraphicsJNI::getSkPixelRef(JNIEnv* env, jobject bitmap) {
+ jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_skBitmapPtr);
+ SkBitmap* b = reinterpret_cast<SkBitmap*>(bitmapHandle);
+ return b->pixelRef();
+}
+
SkColorType GraphicsJNI::getNativeBitmapColorType(JNIEnv* env, jobject jconfig) {
SkASSERT(env);
if (NULL == jconfig) {
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 422d3f1..49def13 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -48,7 +48,9 @@ public:
static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
static SkCanvas* getNativeCanvas(JNIEnv*, jobject canvas);
- static SkBitmap* getSkBitmap(JNIEnv*, jobject bitmap);
+ static SkBitmap* getSkBitmapDeprecated(JNIEnv*, jobject bitmap);
+ static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap);
+ static SkPixelRef* getSkPixelRef(JNIEnv*, jobject bitmap);
static SkRegion* getNativeRegion(JNIEnv*, jobject region);
// Given the 'native' long held by the Rasterizer.java object, return a
diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp
index fc98cf9..876bea4 100644
--- a/core/jni/android/graphics/pdf/PdfRenderer.cpp
+++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp
@@ -243,19 +243,21 @@ static void renderPageBitmap(FPDF_BITMAP bitmap, FPDF_PAGE page, int destLeft, i
}
static void nativeRenderPage(JNIEnv* env, jclass thiz, jlong documentPtr, jlong pagePtr,
- jlong bitmapPtr, jint destLeft, jint destTop, jint destRight, jint destBottom,
+ jobject jbitmap, jint destLeft, jint destTop, jint destRight, jint destBottom,
jlong matrixPtr, jint renderMode) {
FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
- SkBitmap* skBitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
SkMatrix* skMatrix = reinterpret_cast<SkMatrix*>(matrixPtr);
- skBitmap->lockPixels();
+ SkBitmap skBitmap;
+ GraphicsJNI::getSkBitmap(env, jbitmap, &skBitmap);
- const int stride = skBitmap->width() * 4;
+ SkAutoLockPixels alp(skBitmap);
- FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(skBitmap->width(), skBitmap->height(),
- FPDFBitmap_BGRA, skBitmap->getPixels(), stride);
+ const int stride = skBitmap.width() * 4;
+
+ FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(skBitmap.width(), skBitmap.height(),
+ FPDFBitmap_BGRA, skBitmap.getPixels(), stride);
if (!bitmap) {
ALOGE("Erorr creating bitmap");
@@ -278,8 +280,7 @@ static void nativeRenderPage(JNIEnv* env, jclass thiz, jlong documentPtr, jlong
renderPageBitmap(bitmap, page, destLeft, destTop, destRight,
destBottom, skMatrix, renderFlags);
- skBitmap->notifyPixelsChanged();
- skBitmap->unlockPixels();
+ skBitmap.notifyPixelsChanged();
}
static JNINativeMethod gPdfRenderer_Methods[] = {
@@ -287,7 +288,7 @@ static JNINativeMethod gPdfRenderer_Methods[] = {
{"nativeClose", "(J)V", (void*) nativeClose},
{"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount},
{"nativeScaleForPrinting", "(J)Z", (void*) nativeScaleForPrinting},
- {"nativeRenderPage", "(JJJIIIIJI)V", (void*) nativeRenderPage},
+ {"nativeRenderPage", "(JJLandroid/graphics/Bitmap;IIIIJI)V", (void*) nativeRenderPage},
{"nativeOpenPageAndGetSize", "(JILandroid/graphics/Point;)J", (void*) nativeOpenPageAndGetSize},
{"nativeClosePage", "(J)V", (void*) nativeClosePage}
};
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 5c2d0d0..bce2b33 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -618,23 +618,25 @@ static int getType(SkColorType colorType)
static jint util_getInternalFormat(JNIEnv *env, jclass clazz,
jobject jbitmap)
{
- SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
- return getInternalFormat(nativeBitmap->colorType());
+ SkBitmap nativeBitmap;
+ GraphicsJNI::getSkBitmap(env, jbitmap, &nativeBitmap);
+ return getInternalFormat(nativeBitmap.colorType());
}
static jint util_getType(JNIEnv *env, jclass clazz,
jobject jbitmap)
{
- SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
- return getType(nativeBitmap->colorType());
+ SkBitmap nativeBitmap;
+ GraphicsJNI::getSkBitmap(env, jbitmap, &nativeBitmap);
+ return getType(nativeBitmap.colorType());
}
static jint util_texImage2D(JNIEnv *env, jclass clazz,
jint target, jint level, jint internalformat,
jobject jbitmap, jint type, jint border)
{
- SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
- const SkBitmap& bitmap(*nativeBitmap);
+ SkBitmap bitmap;
+ GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
SkColorType colorType = bitmap.colorType();
if (internalformat < 0) {
internalformat = getInternalFormat(colorType);
@@ -680,8 +682,8 @@ static jint util_texSubImage2D(JNIEnv *env, jclass clazz,
jint target, jint level, jint xoffset, jint yoffset,
jobject jbitmap, jint format, jint type)
{
- SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
- const SkBitmap& bitmap(*nativeBitmap);
+ SkBitmap bitmap;
+ GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
SkColorType colorType = bitmap.colorType();
if (format < 0) {
format = getInternalFormat(colorType);
diff --git a/core/jni/android_view_PointerIcon.cpp b/core/jni/android_view_PointerIcon.cpp
index f6d9a1a..d04adbf 100644
--- a/core/jni/android_view_PointerIcon.cpp
+++ b/core/jni/android_view_PointerIcon.cpp
@@ -80,10 +80,7 @@ status_t android_view_PointerIcon_load(JNIEnv* env, jobject pointerIconObj, jobj
jobject bitmapObj = env->GetObjectField(loadedPointerIconObj, gPointerIconClassInfo.mBitmap);
if (bitmapObj) {
- SkBitmap* bitmap = GraphicsJNI::getSkBitmap(env, bitmapObj);
- if (bitmap) {
- outPointerIcon->bitmap = *bitmap; // use a shared pixel ref
- }
+ GraphicsJNI::getSkBitmap(env, bitmapObj, &(outPointerIcon->bitmap));
env->DeleteLocalRef(bitmapObj);
}
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 7080e2a..baeb7dd 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -277,8 +277,9 @@ static void jni_eglCreatePixmapSurface(JNIEnv *_env, jobject _this, jobject out_
EGLConfig cnf = getConfig(_env, config);
jint* base = 0;
- SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(_env, native_pixmap);
- SkPixelRef* ref = nativeBitmap ? nativeBitmap->pixelRef() : 0;
+ SkBitmap nativeBitmap;
+ GraphicsJNI::getSkBitmap(_env, native_pixmap, &nativeBitmap);
+ SkPixelRef* ref = nativeBitmap.pixelRef();
if (ref == NULL) {
jniThrowException(_env, "java/lang/IllegalArgumentException", "Bitmap has no PixelRef");
return;
@@ -289,10 +290,10 @@ static void jni_eglCreatePixmapSurface(JNIEnv *_env, jobject _this, jobject out_
egl_native_pixmap_t pixmap;
pixmap.version = sizeof(pixmap);
- pixmap.width = nativeBitmap->width();
- pixmap.height = nativeBitmap->height();
- pixmap.stride = nativeBitmap->rowBytes() / nativeBitmap->bytesPerPixel();
- pixmap.format = convertPixelFormat(nativeBitmap->colorType());
+ pixmap.width = nativeBitmap.width();
+ pixmap.height = nativeBitmap.height();
+ pixmap.stride = nativeBitmap.rowBytes() / nativeBitmap.bytesPerPixel();
+ pixmap.format = convertPixelFormat(nativeBitmap.colorType());
pixmap.data = (uint8_t*)ref->pixels();
base = beginNativeAttribList(_env, attrib_list);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7c5d194..3d22e52 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -87,6 +87,7 @@
<protected-broadcast android:name="android.app.action.ENTER_DESK_MODE" />
<protected-broadcast android:name="android.app.action.EXIT_DESK_MODE" />
<protected-broadcast android:name="android.app.action.NEXT_ALARM_CLOCK_CHANGED" />
+ <protected-broadcast android:name="android.app.action.SEND_DEVICE_INITIALIZER_STATUS" />
<protected-broadcast android:name="android.appwidget.action.APPWIDGET_UPDATE_OPTIONS" />
<protected-broadcast android:name="android.appwidget.action.APPWIDGET_DELETED" />
@@ -310,6 +311,7 @@
<protected-broadcast android:name="android.internal.policy.action.BURN_IN_PROTECTION" />
<protected-broadcast android:name="android.service.persistentdata.action.WIPE_IF_ALLOWED" />
+ <protected-broadcast android:name="android.app.action.OTA_POLICY_CHANGED" />
<!-- ====================================================================== -->
<!-- RUNTIME PERMISSIONS -->
<!-- ====================================================================== -->
@@ -2374,6 +2376,12 @@
<permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS"
android:protectionLevel="signature" />
+ <!-- Allows receiving status updates from a device initializer.
+ @hide Not for use by third-party applications. -->
+ <permission android:name="android.permission.RECEIVE_DEVICE_INITIALIZER_STATUS"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="signature" />
+
<!-- The system process is explicitly the only one allowed to launch the
confirmation UI for full backup/restore -->
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
diff --git a/core/res/res/anim/date_picker_fade_in_material.xml b/core/res/res/anim/date_picker_fade_in_material.xml
new file mode 100644
index 0000000..12e7ce3
--- /dev/null
+++ b/core/res/res/anim/date_picker_fade_in_material.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@interpolator/accelerate_quad"
+ android:fromAlpha="0.0"
+ android:toAlpha="1.0"
+ android:duration="250" />
diff --git a/core/res/res/anim/date_picker_fade_out_material.xml b/core/res/res/anim/date_picker_fade_out_material.xml
new file mode 100644
index 0000000..4084605
--- /dev/null
+++ b/core/res/res/anim/date_picker_fade_out_material.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 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.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@interpolator/decelerate_quad"
+ android:fromAlpha="1.0"
+ android:toAlpha="0.0"
+ android:duration="250" />
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
new file mode 100644
index 0000000..0fa82eb
--- /dev/null
+++ b/core/res/res/layout/chooser_grid.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright 2015, 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.
+*/
+-->
+<com.android.internal.widget.ResolverDrawerLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:maxWidth="@dimen/resolver_max_width"
+ android:maxCollapsedHeight="256dp"
+ android:maxCollapsedHeightSmall="56dp"
+ android:id="@id/contentPanel">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alwaysShow="true"
+ android:elevation="8dp"
+ android:paddingStart="?attr/dialogPreferredPadding"
+ android:background="@color/white" >
+ <ImageView android:id="@+id/title_icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_gravity="start|center_vertical"
+ android:layout_marginEnd="16dp"
+ android:scaleType="fitCenter" />
+ <TextView android:id="@+id/title"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:minHeight="56dp"
+ android:textAppearance="?attr/textAppearanceMedium"
+ android:gravity="start|center_vertical"
+ android:paddingEnd="?attr/dialogPreferredPadding"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp" />
+ <LinearLayout android:id="@+id/profile_button"
+ android:layout_width="wrap_content"
+ android:layout_height="48dp"
+ android:layout_marginTop="4dp"
+ android:layout_marginEnd="4dp"
+ android:paddingStart="8dp"
+ android:paddingEnd="8dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
+ android:focusable="true"
+ android:visibility="gone"
+ style="?attr/borderlessButtonStyle">
+ <ImageView android:id="@+id/icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_gravity="start|center_vertical"
+ android:layout_marginStart="4dp"
+ android:layout_marginEnd="16dp"
+ android:layout_marginTop="12dp"
+ android:layout_marginBottom="12dp"
+ android:scaleType="fitCenter" />
+ <TextView android:id="@id/text1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start|center_vertical"
+ android:layout_marginEnd="16dp"
+ android:textAppearance="?attr/textAppearanceButton"
+ android:textColor="?attr/textColorPrimary"
+ android:minLines="1"
+ android:maxLines="1"
+ android:ellipsize="marquee" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <GridView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/resolver_list"
+ android:clipToPadding="false"
+ android:paddingStart="@dimen/chooser_grid_padding"
+ android:paddingEnd="@dimen/chooser_grid_padding"
+ android:scrollbarStyle="outsideOverlay"
+ android:background="@color/white"
+ android:elevation="8dp"
+ android:numColumns="4"
+ android:nestedScrollingEnabled="true" />
+
+ <TextView android:id="@+id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alwaysShow="true"
+ android:text="@string/noApplications"
+ android:padding="32dp"
+ android:gravity="center"
+ android:visibility="gone" />
+
+</com.android.internal.widget.ResolverDrawerLayout>
diff --git a/core/res/res/layout/date_picker_material.xml b/core/res/res/layout/date_picker_material.xml
index a1c97ff..763f2a4 100644
--- a/core/res/res/layout/date_picker_material.xml
+++ b/core/res/res/layout/date_picker_material.xml
@@ -16,8 +16,8 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:orientation="vertical">
<include
diff --git a/core/res/res/layout/date_picker_view_animator_material.xml b/core/res/res/layout/date_picker_view_animator_material.xml
index 620ddfa..e863b28 100644
--- a/core/res/res/layout/date_picker_view_animator_material.xml
+++ b/core/res/res/layout/date_picker_view_animator_material.xml
@@ -15,23 +15,23 @@
limitations under the License.
-->
-<ViewAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.internal.widget.DialogViewAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/animator"
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:gravity="center">
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:inAnimation="@anim/date_picker_fade_in_material"
+ android:outAnimation="@anim/date_picker_fade_out_material"
+ android:measureAllChildren="true">
<android.widget.DayPickerView
android:id="@+id/date_picker_day_picker"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:inAnimation="@anim/fade_in"
- android:outAnimation="@anim/fade_out" />
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
<android.widget.YearPickerView
android:id="@+id/date_picker_year_picker"
android:layout_width="match_parent"
android:layout_height="match_parent" />
-</ViewAnimator>
+</com.android.internal.widget.DialogViewAnimator>
diff --git a/core/res/res/layout/resolve_grid_item.xml b/core/res/res/layout/resolve_grid_item.xml
new file mode 100644
index 0000000..664b02f
--- /dev/null
+++ b/core/res/res/layout/resolve_grid_item.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2006, 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:orientation="vertical"
+ android:layout_width="match_parent" android:layout_height="wrap_content"
+ android:minWidth="80dp"
+ android:gravity="center"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:background="?attr/activatedBackgroundIndicator">
+
+ <!-- Activity icon when presenting dialog -->
+ <ImageView android:id="@+id/icon"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:scaleType="fitCenter" />
+
+ <!-- Activity name -->
+ <TextView android:id="@android:id/text1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:layout_marginLeft="4dp"
+ android:layout_marginRight="4dp"
+ android:textAppearance="?attr/textAppearanceSmall"
+ android:textColor="?attr/textColorPrimary"
+ android:fontFamily="sans-serif-condensed"
+ android:gravity="center"
+ android:minLines="2"
+ android:maxLines="2"
+ android:ellipsize="marquee" />
+ <!-- Extended activity info to distinguish between duplicate activity names -->
+ <TextView android:id="@android:id/text2"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="4dp"
+ android:layout_marginRight="4dp"
+ android:minLines="2"
+ android:maxLines="2"
+ android:gravity="center"
+ android:ellipsize="marquee" />
+</LinearLayout>
+
diff --git a/core/res/res/layout/select_dialog_multichoice_material.xml b/core/res/res/layout/select_dialog_multichoice_material.xml
index 9cfbbb3..e21df73 100644
--- a/core/res/res/layout/select_dialog_multichoice_material.xml
+++ b/core/res/res/layout/select_dialog_multichoice_material.xml
@@ -16,15 +16,15 @@
-->
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@android:id/text1"
+ android:id="@id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorAlertDialogListItem"
+ android:minHeight="?attr/listPreferredItemHeightSmall"
+ android:textAppearance="?attr/textAppearanceMedium"
+ android:textColor="?attr/textColorAlertDialogListItem"
android:gravity="center_vertical"
- android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingStart="@dimen/select_dialog_padding_start_material"
android:paddingEnd="?attr/dialogPreferredPadding"
- android:checkMark="?android:attr/listChoiceIndicatorMultiple"
+ android:checkMark="?attr/listChoiceIndicatorMultiple"
android:checkMarkGravity="start"
android:ellipsize="marquee" />
diff --git a/core/res/res/layout/select_dialog_singlechoice_material.xml b/core/res/res/layout/select_dialog_singlechoice_material.xml
index 4f8672f..3828317 100644
--- a/core/res/res/layout/select_dialog_singlechoice_material.xml
+++ b/core/res/res/layout/select_dialog_singlechoice_material.xml
@@ -16,15 +16,15 @@
-->
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@android:id/text1"
+ android:id="@id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorAlertDialogListItem"
+ android:minHeight="?attr/listPreferredItemHeightSmall"
+ android:textAppearance="?attr/textAppearanceMedium"
+ android:textColor="?attr/textColorAlertDialogListItem"
android:gravity="center_vertical"
- android:paddingStart="?attr/dialogPreferredPadding"
+ android:paddingStart="@dimen/select_dialog_padding_start_material"
android:paddingEnd="?attr/dialogPreferredPadding"
- android:checkMark="?android:attr/listChoiceIndicatorSingle"
+ android:checkMark="?attr/listChoiceIndicatorSingle"
android:checkMarkGravity="start"
android:ellipsize="marquee" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index d70b81b..05ff157 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Vinger is te vinnig beweeg. Probeer asseblief weer."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Vinger is te stadig beweeg. Probeer asseblief weer."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Handelaarspesifieke aankoopfoutboodskap 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Kon nie verwerk nie. Probeer weer."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardeware is nie beskikbaar nie."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vingerafdrukuittelling is bereik. Probeer weer."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Vingerafdrukuittelling is bereik. Probeer weer."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Handelaarspesifieke foutboodskap."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lees sinkroniseer-instellings"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Laat die program toe om die sinkroniseringinstellings van \'n rekening te lees. Byvoorbeeld, dit kan bepaal of die People-program met \'n rekening gesinkroniseer is."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 36a29fb..ea49736 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"ጣት በጣም በፍጥነት ተንቀሳቅሷል። እባክዎ እንደገና ይሞክሩ።"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"ጣት በጣም በዝግታ ተንቀሳቅሷል። እባክዎ እንደገና ይሞክሩ።"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"አቅራቢ-ተኮር ግዢ የስህተት መልዕክት 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"ሂደትን ማከናወን አልተቻለም። እንደገና ይሞክሩ።"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"ሃርድዌር አይገኝም።"</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"የጣት አሻራ ማብቂያ ጊዜ ደርሷል። እንደገና ይሞክሩ።"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"የጣት አሻራ ማብቂያ ጊዜ ደርሷል። እንደገና ይሞክሩ።"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"አቅራቢ-ተኮር የስህተት መልዕክት"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"የሥምሪያ ቅንብሮች አንብብ"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"መተግበሪያው የአንድ መለያ የማመሳሰል ቅንብሮችን እንዲያነብ ይፈቅድለታል። ለምሳሌ ይህ የሰዎች መተግበሪያ ከመለያ ጋር መመሳሰሉን አለመመሳሰሉን ሊወስን ይችላል።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index ab57d6c..ccf5fa2 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -450,7 +450,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"تحرك الإصبع بسرعة كبيرة جدًا؛ يرجى إعادة المحاولة."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"تحرك الإصبع ببطء شديد جدًا؛ يرجى إعادة المحاولة."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"رسالة الخطأ 0 التي حددها المورّد بشأن الاكتساب"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"تعذرت المعالجة؛ أعد المحاولة."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"الجهاز غير متاح."</string>
@@ -458,7 +457,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"تم بلوغ مهلة إدخال بصمة الإصبع. أعد المحاولة."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"تم بلوغ مهلة إدخال بصمة الإصبع. أعد المحاولة."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"رسالة الخطأ التي حددها المورّد."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"قراءة إعدادات المزامنة"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"للسماح للتطبيق بقراءة الإعدادات المتزامنة لحساب ما. على سبيل المثال، يمكن أن يؤدي هذا إلى تحديد ما إذا تمت مزامنة تطبيق \"الأشخاص\" مع حساب ما."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index bbbc1c4..ceb64e5 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Преместихте пръста си твърде бързо. Моля, опитайте отново."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Преместихте пръста си твърде бавно. Моля, опитайте отново."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Съобщение за грешка 0 при придобиване от конкретен доставчик"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Не може да се обработи. Опитайте отново."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Няма достъп до хардуера."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Времето за изчакване за отпечатък изтече. Опитайте отново."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Времето за изчакване за отпечатък изтече. Опитайте отново."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Съобщение за грешка от конкретен доставчик."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"четене на настройките за синхронизиране"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Разрешава на приложението да чете настройките за синхронизиране на профил. Например това може да определи дали приложението Хора е синхронизирано с даден профил."</string>
@@ -1474,8 +1472,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Още опции"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Затваряне на менюто при препълване"</string>
</resources>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index cdd4331..fd25d30 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"আঙ্গুল অতি দ্রুত সরানো হয়েছে৷ অনুগ্রহ করে আবার চেষ্টা করুন৷"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"আঙ্গুল ধীরে সরানো হয়েছে৷ অনুগ্রহ করে আবার চেষ্টা করুন৷"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"বিক্রেতা-নির্দিষ্ট অর্জনে ত্রুটি বার্তা ০"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"প্রক্রিয়া করতে অক্ষম হয়েছে৷ আবার চেষ্টা করুন৷"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"হার্ডওয়্যার অনুপলব্ধ৷"</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"আঙ্গুলের ছাপ নেওয়ার সময়সীমা শেষ হযেছে৷ আবার চেষ্টা করুন৷"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"আঙ্গুলের ছাপ নেওয়ার সময়সীমা শেষ হযেছে৷ আবার চেষ্টা করুন৷"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"বিক্রেতা-নির্দিষ্ট ত্রুটি বার্তা৷"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"সিঙ্ক সেটিংস পড়ে"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"অ্যাপ্লিকেশানটিকে একটি অ্যাকাউন্টের জন্য সিঙ্ক সেটিংস পড়ার অনুমতি দেয়৷ উদাহরণস্বরূপ, \'পিপল\' অ্যাপ্লিকেশানটি কোনো অ্যাকাউন্টের সাথে সিঙ্ক করা আছে কিনা তা নির্ধারণ করতে পারে৷"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index aca92bc..a643581 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"El dit s\'ha mogut massa ràpid. Torna-ho a provar."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"El dit s\'ha mogut massa lentament. Torna-ho a provar."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Missatge d\'error d\'adquisició 0 específic del proveïdor"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"No es pot processar. Torna-ho a provar."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"No hi ha maquinari disponible."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"S\'ha esgotat el temps d\'espera per a l\'empremta digital. Torna-ho a provar."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"S\'ha esgotat el temps d\'espera per a l\'empremta digital. Torna-ho a provar."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Missatge d\'error específic del proveïdor."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"llegir la configuració de sincronització"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet que l\'aplicació llegeixi la configuració de sincronització d\'un compte. Per exemple, això pot determinar que l\'aplicació Persones estigui sincronitzada amb un compte."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index e8366ed..b23e01d 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -448,7 +448,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Pohyb prstem byl příliš rychlý. Zkuste to znovu."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Pohyb prstem byl příliš pomalý. Zkuste to znovu."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Chybová zpráva 0 dodavatele ohledně načtení otisků"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Otisk prstu nelze zpracovat. Zkuste to znovu."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware není dostupný."</string>
@@ -456,7 +455,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Časový limit sejmutí otisku prstu vypršel. Zkuste to znovu."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Časový limit sejmutí otisku prstu vypršel. Zkuste to znovu."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Chybová zpráva dodavatele"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"čtení nastavení synchronizace"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Umožňuje aplikaci číst nastavení synchronizace v účtu. Může například určit, zda je s účtem synchronizována aplikace Lidé."</string>
@@ -1500,8 +1498,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Další možnosti"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Zavřít rozbalovací nabídku"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 8d9c6ce..f63f274 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Du bevægede fingeren for hurtigt. Prøv igen."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Du bevægede fingeren for langsomt. Prøv igen."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Leverandørspecifik fejlmeddelelse 0 i forbindelse med hentning"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Registreringen kan ikke gennemføres. Prøv igen."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardwaren er ikke tilgængelig."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Registrering af fingeraftryk fik timeout. Prøv igen."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Registrering af fingeraftryk fik timeout. Prøv igen."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Leverandørspecifik fejlmeddelelse."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"læse indstillinger for synkronisering"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Tillader, at appen kan læse synkroniseringsindstillingerne for en konto. Denne tilladelse kan f.eks. fastslå, om appen Personer er synkroniseret med en konto."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 51ed3d8..2873860 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Finger zu schnell bewegt. Versuchen Sie es erneut."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Finger zu langsam bewegt. Versuchen Sie es erneut."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Anbieterspezifische Erfassungsfehlermeldung 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Unbrauchbar. Versuchen Sie es erneut."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware nicht verfügbar"</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Zeitüberschreitung für Fingerabdruck. Versuchen Sie es erneut."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Zeitüberschreitung für Fingerabdruck. Versuchen Sie es erneut."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Anbieterspezifische Fehlermeldung"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"Synchronisierungseinstellungen lesen"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Ermöglicht der App, die Synchronisierungseinstellungen eines Kontos zu lesen. Beispielsweise kann damit festgestellt werden, ob Kontakte mit einem Konto synchronisiert werden."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 63c3ff7..3c3bf46 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Πολύ γρήγορη κίνηση δαχτύλου. Δοκιμάστε ξανά."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Πολύ αργή κίνηση δαχτύλου. Δοκιμάστε ξανά."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Μήνυμα σφάλματος εξαγοράς για συγκεκριμένο προμηθευτή 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Δεν είναι δυνατή η επεξεργασία. Δοκιμάστε ξανά."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Ο εξοπλισμός δεν είναι διαθέσιμος."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Λήξη χρονικού ορίου μοναδικού χαρακτηριστικού. Δοκιμάστε ξανά."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Λήξη χρονικού ορίου μοναδικού χαρακτηριστικού. Δοκιμάστε ξανά."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Μήνυμα σφάλματος για συγκεκριμένο προμηθευτή."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ανάγνωση ρυθμίσεων συγχρονισμού"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Επιτρέπει στην εφαρμογή την ανάγνωση των ρυθμίσεων συγχρονισμού για έναν λογαριασμό. Για παράδειγμα, αυτό μπορεί να καθορίσει εάν η εφαρμογή \"Άτομα\" είναι συγχρονισμένη με έναν λογαριασμό."</string>
@@ -1449,17 +1447,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Έως τις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Μέχρι να το απενεργοποιήσετε"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Σύμπτυξη"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"Αποκλεισμός διακοπών"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Διακοπή λειτουργίας"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"Καθημερινές"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"Σαββατοκύριακα"</string>
<string name="muted_by" msgid="6147073845094180001">"Σίγαση από <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Υπάρχει ένα εσωτερικό πρόβλημα με τη συσκευή σας και ενδέχεται να είναι ασταθής μέχρι την επαναφορά των εργοστασιακών ρυθμίσεων."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Υπάρχει ένα εσωτερικό πρόβλημα με τη συσκευή σας. Επικοινωνήστε με τον κατασκευαστή σας για λεπτομέρειες."</string>
@@ -1469,11 +1462,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Το αίτημα SS τροποποιήθηκε σε αίτημα DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Το αίτημα SS τροποποιήθηκε σε αίτημα USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Το αίτημα SS τροποποιήθηκε σε νέο αίτημα SS."</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Περιφερειακή θύρα USB Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Περιφερειακή θύρα USB"</string>
<string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Περισσότερες επιλογές"</string>
<string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Κλείσιμο υπερχείλισης"</string>
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index f02b319..4fe28a9 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Finger moved to fast. Please try again."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Finger moved to slow. Please try again."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Vendor-specific acquisition error message 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Unable to process. Try again."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware not available."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Fingerprint timeout reached. Try again."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Fingerprint timeout reached. Try again."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Vendor-specific error message."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Allows the app to read the sync settings for an account. For example, this can determine whether the People app is synced with an account."</string>
@@ -1449,17 +1447,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"Block interruptions"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Downtime"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"Weeknights"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"Weekends"</string>
<string name="muted_by" msgid="6147073845094180001">"Muted by <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
@@ -1469,11 +1462,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS request is modified to DIAL request."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Peripheral Port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral Port"</string>
<string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"More options"</string>
<string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Close overflow"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index f02b319..4fe28a9 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Finger moved to fast. Please try again."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Finger moved to slow. Please try again."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Vendor-specific acquisition error message 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Unable to process. Try again."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware not available."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Fingerprint timeout reached. Try again."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Fingerprint timeout reached. Try again."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Vendor-specific error message."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Allows the app to read the sync settings for an account. For example, this can determine whether the People app is synced with an account."</string>
@@ -1449,17 +1447,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"Block interruptions"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Downtime"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"Weeknights"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"Weekends"</string>
<string name="muted_by" msgid="6147073845094180001">"Muted by <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
@@ -1469,11 +1462,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS request is modified to DIAL request."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Peripheral Port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral Port"</string>
<string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"More options"</string>
<string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Close overflow"</string>
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index f02b319..4fe28a9 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Finger moved to fast. Please try again."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Finger moved to slow. Please try again."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Vendor-specific acquisition error message 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Unable to process. Try again."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware not available."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Fingerprint timeout reached. Try again."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Fingerprint timeout reached. Try again."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Vendor-specific error message."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Allows the app to read the sync settings for an account. For example, this can determine whether the People app is synced with an account."</string>
@@ -1449,17 +1447,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"Block interruptions"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Downtime"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"Weeknights"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"Weekends"</string>
<string name="muted_by" msgid="6147073845094180001">"Muted by <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
@@ -1469,11 +1462,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS request is modified to DIAL request."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Peripheral Port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral Port"</string>
<string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"More options"</string>
<string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Close overflow"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 181139b..b730c70 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Moviste el dedo muy rápido. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Moviste el dedo muy despacio. Vuelve a intentarlo."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Mensaje de error de adquisición específico del proveedor 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"No se puede procesar. Vuelve a intentarlo."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"El hardware no está disponible."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Finalizó el tiempo de espera para la huella digital. Vuelve a intentarlo."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Finalizó el tiempo de espera para la huella digital. Vuelve a intentarlo."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Mensaje de error específico del proveedor"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"leer la configuración de sincronización"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Este permiso permite que la aplicación consulte la configuración de sincronización de una cuenta. Esto permite, por ejemplo, determinar si la aplicación Personas está sincronizada con una cuenta."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 937c0b1..bd2b942 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Has movido el dedo muy rápido. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Has movido el dedo muy despacio. Vuelve a intentarlo."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Mensaje de error de adquisición específico del proveedor: 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"No se puede procesar la huella digital. Vuelve a intentarlo."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware no disponible."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Se ha alcanzado el tiempo de espera de la huella digital. Vuelve a intentarlo."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Se ha alcanzado el tiempo de espera de la huella digital. Vuelve a intentarlo."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Mensaje de error específico del proveedor."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"leer la configuración de sincronización"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite que la aplicación consulte la configuración de sincronización de una cuenta. La aplicación puede utilizar este permiso, por ejemplo, para determinar si la aplicación Contactos está sincronizada con una cuenta."</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index ddd84f0..7f1f6b0 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Sõrm liikus liiga kiiresti. Proovige uuesti."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Sõrm liikus liiga aeglaselt. Proovige uuesti."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Teenusepakkujapõhise värbamise veateade 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Töötlemine ei õnnestu. Proovige uuesti."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Riistvara pole saadaval."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Sõrmejälje riistvara taimeri ajalõpp. Proovige uuesti."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Sõrmejälje riistvara taimeri ajalõpp. Proovige uuesti."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Teenusepakkujapõhine veateade."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"loe sünkroonimisseadeid"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Võimaldab rakendusel lugeda konto sünkroonimisseadeid. Näiteks võib see määrata, kas rakendus Inimesed on kontoga sünkroonitud."</string>
@@ -1474,8 +1472,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Rohkem valikuid"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Ületäite sulgemine"</string>
</resources>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index f3418f3..80b24c4 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Hatza bizkorregi mugitu duzu. Saiatu berriro."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Hatza mantsoegi mugitu duzu. Saiatu berriro."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Saltzailearen berariazko errore-mezua, erosketarekin erlazionatuta"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Ezin da prozesatu. Saiatu berriro."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardwarea ez dago erabilgarri."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Hatz-marka digitalak prozesatzeko denbora-muga gainditu da. Saiatu berriro."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Hatz-marka digitalak prozesatzeko denbora-muga gainditu da. Saiatu berriro."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Saltzailearen berariazko errore-mezua."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"Irakurri sinkronizazio-ezarpenak"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Kontu baten sinkronizazio-ezarpenak irakurtzeko baimena ematen die aplikazioei. Adibidez, Jendea aplikazioa konturen batekin sinkronizatuta dagoen zehatz dezake."</string>
@@ -1475,8 +1473,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Aukera gehiago"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Itxi gainfluxua"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 6e06497..0f3da45 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"انگشت خیلی سریع حرکت کرد. لطفاً دوباره امتحان کنید."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"انگشت خیلی آهسته حرکت کرد. لطفاً دوباره امتحان کنید."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"پیام خطای خرید خاص فروشنده ۰"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"پردازش ممکن نیست. دوباره امتحان کنید."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"سخت‌افزار در دسترس نیست."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"مهلت زمانی ثبت اثر انگشت به پایان رسید. دوباره امتحان کنید."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"مهلت زمانی ثبت اثر انگشت به پایان رسید. دوباره امتحان کنید."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"پیام خطای خاص فروشنده."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"خواندن تنظیمات همگام‌سازی"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"به برنامه اجازه می‌دهد تنظیمات را برای یک حساب بخواند. به‌عنوان مثال، این ویژگی می‌تواند تعیین کند آیا حساب «افراد» شما با یک حساب همگام‌سازی شده است."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 7bd7a5a..1959ac1 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Liikutit sormea liian nopeasti. Yritä uudelleen."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Liikutit sormea liian hitaasti. Yritä uudelleen."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Toimittajakohtainen ​​hankintavirheilmoitus 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Käsittely ei onnistu. Yritä uudelleen."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Laitteisto ei ole käytettävissä."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Sormenjälkitunnistimen toiminta aikakatkaistiin. Yritä uudelleen."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Sormenjälkitunnistimen toiminta aikakatkaistiin. Yritä uudelleen."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Toimittajakohtainen ​​virheilmoitus."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lue synkronointiasetuksia"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Antaa sovelluksen lukea tilien synkronointiasetuksia. Sovellus voi esimerkiksi määrittää, onko Henkilöt-sovellus synkronoitu tilin kanssa."</string>
@@ -1474,8 +1472,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Lisäasetukset"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Sulje ylivuoto"</string>
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 16cee11..93648f6 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Le doigt a bougé trop vite. Veuillez essayer de nouveau."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Le doigt a bougé trop lentement. Veuillez essayer de nouveau."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Message d\'erreur d\'acquisition propre au fournisseur 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Traitement impossible. Essayer de nouveau."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Matériel non disponible."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Le temps attribué pour lire l\'empreinte est écoulé. Veuillez essayer de nouveau."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Le temps attribué pour lire l\'empreinte est écoulé. Veuillez essayer de nouveau."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Message d\'erreur propre au fournisseur."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lire les paramètres de synchronisation"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet à l\'application d\'accéder aux paramètres de synchronisation d\'un compte. Par exemple, cette autorisation peut permettre de déterminer si l\'application Contacts est synchronisée avec un compte ou non."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index c8c93c8..5eac701 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Vous avez retiré votre doigt trop rapidement. Veuillez réessayer."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Vous avez déplacé votre doigt trop lentement. Veuillez réessayer."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Message d\'erreur d\'acquisition spécifique au fournisseur 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Impossible de reconnaître l\'empreinte numérique. Veuillez réessayer."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Matériel non disponible."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Délai de détection de l\'empreinte numérique expiré. Veuillez réessayer."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Délai de détection de l\'empreinte numérique expiré. Veuillez réessayer."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Message d\'erreur spécifique au fournisseur."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lire les paramètres de synchronisation"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet à l\'application d\'accéder aux paramètres de synchronisation d\'un compte. Par exemple, cette autorisation peut permettre de déterminer si l\'application Contacts est synchronisée avec un compte ou non."</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index faa4e33..41c56d8 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"O dedo moveuse demasiado rápido. Téntao de novo."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"O dedo moveuse demasiado lento. Téntao de novo."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Mensaxe de erro de adquisición específico do vendedor 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Non se pode procesar. Téntao de novo."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware non dispoñible."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Esgotouse o tempo de espera da impresión dixital. Téntao de novo."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Esgotouse o tempo de espera da impresión dixital. Téntao de novo."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Mensaxe de erro específico do vendedor"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler a configuración de sincronización"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite á aplicación ler a configuración de sincronización dunha conta. Por exemplo, esta acción pode determinar se a aplicación Contactos se sincroniza cunha conta."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index f14af79..7f75425 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"अंगुली को तेज़ी से चलाया गया. कृपया पुनः प्रयास करें."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"अंगुली को धीरे चलाया गया. कृपया पुनः प्रयास करें."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"विक्रेता-विशिष्‍ट प्राप्‍ति त्रुटि संदेश 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"संसाधित करने में असमर्थ. पुनः प्रयास करें."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"हार्डवेयर उपलब्ध नहीं है."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"फ़िंगरप्रिंट का समय समाप्त हो गया. पुनः प्रयास करें."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"फ़िंगरप्रिंट का समय समाप्त हो गया. पुनः प्रयास करें."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"विक्रेता-विशिष्‍ट त्रुटि संदेश."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"समन्वयन सेटिंग पढ़ें"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ऐप्स को किसी खाते की समन्वयन सेटिंग पढ़ने देता है. उदाहरण के लिए, इससे यह निर्धारित किया जा सकता है कि लोग ऐप्स किसी खाते के साथ समन्‍वयित है या नहीं."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 642d76b..95d3863 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Prebrzo pomicanje prsta. Pokušajte ponovo."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Presporo pomicanje prsta. Pokušajte ponovo."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Poruka pogreške prilikom dohvaćanja vezana uz dobavljača 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Nije obrađeno. Pokušajte ponovo."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardver nije dostupan."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Isteklo je vrijeme čekanja za otisak prsta. Pokušajte ponovo."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Isteklo je vrijeme čekanja za otisak prsta. Pokušajte ponovo."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Poruka pogreške vezana uz dobavljača."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"čitanje postavki sinkronizacije"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Aplikaciji omogućuje čitanje postavki sinkronizacije za račun. Time se, primjerice, može utvrditi je li aplikacija Osobe sinkronizirana s računom."</string>
@@ -1487,8 +1485,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Više opcija"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Zatvori dodatni izbornik"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 6778fb6..47693e3 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Túl hamar vette el az ujját. Próbálkozzon újra."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Túl lassan vette el az ujját. Próbálkozzon újra."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Szolgáltatóspecifikus akvizíciós hibakód 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"A feldolgozás sikertelen. Próbálkozzon újra."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"A hardver nem érhető el."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Az ujjlenyomat-beolvasási műveletkor időtúllépés történt. Próbálkozzon újra."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Az ujjlenyomat-beolvasási műveletkor időtúllépés történt. Próbálkozzon újra."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Szolgáltatóspecifikus hibaüzenet"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"szinkronizálási beállítások olvasása"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Lehetővé teszi az alkalmazás számára egy fiók szinkronizálási beállításainak beolvasását. Például ellenőrizheti, hogy a Személyek alkalmazás szinkronizálva van-e egy fiókkal."</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 339cb90..27023cd 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Մատը շարժեցիք շատ արագ: Փորձեք նորից:"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Մատը շարժեցիք շատ դանդաղ: Փորձեք նորից:"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Վաճառողի կողմից սահմանվող ձեռքբերման սխալի հաղորդագրություն 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Հնարավոր չէ շարունակել: Փորձեք նորից:"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Սարքն անհասանելի է:"</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Մատնահետքի գրանցման ժամանակը սպառվել է: Փորձեք նորից:"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Մատնահետքի գրանցման ժամանակը սպառվել է: Փորձեք նորից:"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Վաճառողի կողմից սահմանվող սխալի հաղորդագրություն:"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"կարդալ համաժամեցման կարգավորումները"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Թույլ է տալիս հավելվածին կարդալ համաժամեցման կարգավորումները հաշվի համար: Օրինակ` այն կարող է որոշել, արդյոք Մարդիկ հավելվածը համաժամեցված է հաշվի հետ:"</string>
@@ -1475,8 +1473,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Այլ ընտրանքներ"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Փակել ավելորդ տեղեկությունները"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 6a2a4e9..fac966f 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Jari digerakkan terlalu cepat. Coba lagi."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Jari digerakkan terlalu lambat. Coba lagi."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Pesan kesalahan akuisisi khusus vendor 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Tidak dapat memproses. Coba lagi."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Perangkat keras tidak tersedia."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Waktu sidik jari habis. Coba lagi."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Waktu sidik jari habis. Coba lagi."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Pesan kesalahan khusus vendor"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"baca setelan sinkron"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Memungkinkan aplikasi membaca setelan sinkronisasi untuk sebuah akun. Misalnya, izin ini dapat menentukan apakah aplikasi Orang disinkronkan dengan sebuah akun."</string>
@@ -1449,17 +1447,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Hingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hingga Anda menonaktifkan ini"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Ciutkan"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"Blokir gangguan"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Waktu non-operasional"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"Malam hari kerja"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"Akhir pekan"</string>
<string name="muted_by" msgid="6147073845094180001">"Dinonaktifkan oleh <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Ada masalah dengan perangkat. Hal ini mungkin membuat perangkat jadi tidak stabil dan perlu dikembalikan ke setelan pabrik."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Ada masalah dengan perangkat. Hubungi produsen perangkat untuk informasi selengkapnya."</string>
@@ -1469,11 +1462,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Permintaan SS diubah menjadi permintaan DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Permintaan SS diubah menjadi permintaan USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Permintaan SS diubah menjadi permintaan SS baru."</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Port Periferal USB Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Port Periferal USB"</string>
<string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Opsi lainnya"</string>
<string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Tutup luapan"</string>
</resources>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 084e4a4..c551ca3 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Fingurinn hreyfðist of hratt. Reyndu aftur."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Fingurinn hreyfðist of hægt. Reyndu aftur."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Skráningarvilluboð 0 frá framleiðanda"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Ekki var hægt að vinna úr þessu. Reyndu aftur."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Vélbúnaður er ekki tiltækur."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tímamörk runnu út fyrir fingrafar. Reyndu aftur."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Tímamörk runnu út fyrir fingrafar. Reyndu aftur."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Villuboð frá framleiðanda."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lesa samstillingar"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Leyfir forriti að lesa kosti samstillingar fyrir reikning. Þetta er til dæmis hægt að nota til að komast að því hvort forritið Fólk er samstillt við reikning."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 0e4dc93..9e7d440 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Movimento del dito troppo rapido. Riprova."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Movimento del dito troppo lento. Riprova."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Messaggio di errore di acquisizione specifico del fornitore: 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Impossibile elaborare l\'impronta. Riprova."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware non disponibile."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Timeout impronta digitale. Riprova."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Timeout impronta digitale. Riprova."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Messaggio di errore specifico del fornitore."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lettura impostazioni di sincronizz."</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Consente all\'applicazione di leggere le impostazioni di sincronizzazione per un account. Ad esempio, questa autorizzazione può determinare se l\'applicazione Persone è sincronizzata con un account."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 6fc19bc..2f411ae 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -448,7 +448,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"האצבע זזה מהר מדי, נסה שוב."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"האצבע זזה לאט מדי, נסה שוב."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"הודעת שגיאה 0 של רכישה ספציפית לספק"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"אין אפשרות לעבד. נסה שוב."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"החומרה לא זמינה."</string>
@@ -456,7 +455,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"חלף הזמן הקצוב לטביעת אצבע. נסה שוב."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"חלף הזמן הקצוב לטביעת אצבע. נסה שוב."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"הודעת שגיאה ספציפית לספק."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"קרא את הגדרות הסינכרון"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"מאפשר לאפליקציה לקרוא את הגדרות הסנכרון של חשבון. לדוגמה, ניתן לגלות כך האם האפליקציה \'אנשים\' מסונכרן עם חשבון כלשהו."</string>
@@ -1475,17 +1473,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"עד <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"עד שתכבה"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"כווץ"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"חסימת הפרעות"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"זמן השבתה"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"לילות בימי חול"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"סופי שבוע"</string>
<string name="muted_by" msgid="6147073845094180001">"הושתק על ידי <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"קיימת בעיה פנימית במכשיר שלך, וייתכן שהתפקוד שלו לא יהיה יציב עד שתבצע איפוס לנתוני היצרן."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"קיימת בעיה פנימית במכשיר שלך. לקבלת פרטים, צור קשר עם היצרן."</string>
@@ -1495,13 +1488,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"‏בקשת SS שונתה לבקשת DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"‏בקשת SS שונתה לבקשת USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"‏בקשת SS שונתה לבקשת SS חדשה."</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"‏יציאת USB בציוד היקפי של Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"‏יציאת USB בציוד היקפי"</string>
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"אפשרויות נוספות"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"סגור את האפשרויות הנוספות"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 83d2482..b733ec1 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"指の動きが速すぎました。もう一度お試しください。"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"指の動きが遅すぎました。もう一度お試しください。"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"ベンダー固有の取得エラーメッセージ0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"処理できませんでした。もう一度お試しください。"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"ハードウェアを利用できません。"</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"指紋の読み取りがタイムアウトになりました。もう一度お試しください。"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"指紋の読み取りがタイムアウトになりました。もう一度お試しください。"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"ベンダー固有のエラーメッセージです。"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"同期設定の読み取り"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"アカウントの同期設定の読み取りをアプリに許可します。たとえば、連絡帳アプリがアカウントと同期しているかどうかをアプリから特定できるようになります。"</string>
@@ -1474,8 +1472,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"その他のオプション"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"オーバーフローを閉じる"</string>
</resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 8380035..11017dc 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"თითის აღება მეტისმეტად სწრაფად მოხდა. გთხოვთ, სცადოთ ხელახლა."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"თითის აღება მეტისმეტად ნელა მოხდა. გთხოვთ, სცადოთ ხელახლა."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"მომწოდებლის მიხედვით სპეციფიკური მოპოვების შეცდომის შეტყობინება 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"დამუშავება შეუძლებელია. სცადეთ ხელახლა."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"აპარატურა არ არის ხელმისაწვდომი."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"თითის ანაბეჭდის ლოდინის დრო ამოიწურა. სცადეთ ხელახლა."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"თითის ანაბეჭდის ლოდინის დრო ამოიწურა. სცადეთ ხელახლა."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"მომწოდებლის მიხედვით სპეციფიკური შეცდომის შეტყობინება."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"სინქრონიზაციის პარამეტრების წაკითხვა"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"აპს შეეძლება, წაიკითხოს ანგარიშის სინქრონიზაციის პარამეტრები. მაგალითად, მას შეეძლება განსაზღვროს, არის თუ არა People აპი სინქრონიზებული ანგარიშთან."</string>
@@ -1475,8 +1473,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"სხვა ვარიანტები"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"გადავსების დახურვა"</string>
</resources>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index cd48f4c..e76a9a5 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Саусақ тым тез қозғалды. Әрекетті қайталаңыз."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Саусақ тым баяу қозғалды. Әрекетті қайталаңыз."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Жеткізушіге тән алу қатесі туралы хабар 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Өңдеу мүмкін емес. Әрекетті қайталаңыз."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Жабдық қол жетімді емес."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Саусақ ізін күту уақыты бітті. Әрекетті қайталаңыз."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Саусақ ізін күту уақыты бітті. Әрекетті қайталаңыз."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Жеткізушіге тән қате туралы хабар."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"синх параметрлерін оқу"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Қолданбаға есептік жазба синхрондау параметрлерін оқу мүмкіндігін береді. Мысалы, бұл арқылы People қолданбасының есептік жазбамен сихрондалғаны анықталуы мүмкін."</string>
@@ -1475,8 +1473,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Қосымша опциялар"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Артық толуды жабу"</string>
</resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index f60a6fc..a206d1e 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"ម្រាមដៃមានចលនារហ័សពេក។ សូមព្យាយាមម្តងទៀត។"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"ម្រាមដៃមានចលនាយឺតពេក។ សូមព្យាយាមម្តងទៀត។"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"សារកំហុសនៃការទិញពីអ្នកលក់ជាក់លាក់ 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"មិនអាចដំណើរការបានទេ។ សូមព្យាយាមម្តងទៀត។"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"មិនមានផ្នែករឹងទេ។"</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"ការផ្តិតម្រាមដៃបានអស់ពេល។ សូមព្យាយាមម្តងទៀត។"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"ការផ្តិតម្រាមដៃបានអស់ពេល។ សូមព្យាយាមម្តងទៀត។"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"សារកំហុសពីអ្នកលក់ជាក់លាក់។"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"អាន​ការ​កំណត់​ធ្វើ​សម​កាល​កម្ម"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ឲ្យ​កម្មវិធី​អាន​ការ​កំណត់​ធ្វើ​សម​កាល​កម្ម​សម្រាប់​គណនី។ ឧទាហរណ៍ វា​អាច​កំណត់​ថា​តើ​​​កម្មវិធី​ត្រូវ​បាន​បើក​ជា​មួយ​គណនី​ដែរ​ឬទេ។"</string>
@@ -1477,8 +1475,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"ជម្រើសច្រើនទៀត"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"បិទលើសចំណុះ"</string>
</resources>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 8c3b367..35d214c 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"ಬೆರಳನ್ನು ವೇಗವಾಗಿ ಸರಿಸಲಾಗಿದೆ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"ಬೆರಳನ್ನು ನಿಧಾನವಾಗಿ ಸರಿಸಲಾಗಿದೆ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"ಮಾರಾಟಗಾರ-ನಿರ್ದಿಷ್ಟ ಸ್ವಾಧೀನ ದೋಷ ಸಂದೇಶ 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"ಹಾರ್ಡ್‌ವೇರ್ ಲಭ್ಯವಿಲ್ಲ."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅವಧಿ ಮೀರಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅವಧಿ ಮೀರಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"ಮಾರಾಟಗಾರ-ನಿರ್ದಿಷ್ಟ ದೋಷ ಸಂದೇಶ."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ಸಿಂಕ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ರೀಡ್‌ ಮಾಡು"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ಒಂದು ಖಾತೆಯ ಸಿಂಕ್ ಸೆಟ್ಟಿಂಗ್‍‍ಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ಖಾತೆಯೊಂದಿಗೆ ಜನರ ಅಪ್ಲಿಕೇಶನ್ ಸಿಂಕ್ ಮಾಡಲಾಗಿದೆಯೇ ಎಂಬುದನ್ನು ಇದು ನಿರ್ಧರಿಸಬಹುದು."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 3d2035c..5771080 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"손가락을 너무 빨리 움직였습니다. 다시 시도해 주세요."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"손가락을 너무 느리게 움직였습니다. 다시 시도해 주세요."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"공급업체별 획득 오류 메시지 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"인식할 수 없습니다. 다시 시도하세요."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"하드웨어를 사용할 수 없습니다."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"지문 인식 시간이 초과되었습니다. 다시 시도하세요."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"지문 인식 시간이 초과되었습니다. 다시 시도하세요."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"공급업체별 오류 메시지"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"동기화 설정 읽기"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"앱이 계정의 동기화 설정을 읽을 수 있도록 허용합니다. 예를 들어, 계정에서 주소록 앱을 동기화할지 여부를 확인할 수 있습니다."</string>
@@ -1474,8 +1472,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"옵션 더보기"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"더보기 닫기"</string>
</resources>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 0dc0c20..91408bc 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -575,7 +575,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Манжа өтө тез жылдырылды. Кайра аракет кылыңыз."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Манжа өтө жай жылдырылды. Кайра аракет кылыңыз."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Жеткирүүчүгө тиешелүү ээ болуу катасы жөнүндө билдирүү 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Иштетилбей жатат. Кайра аракет кылыңыз."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Аппараттык камсыздоо жеткиликтүү эмес."</string>
@@ -583,7 +582,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Манжа изин күтүү мөөнөтү бүттү. Кайра аракет кылыңыз."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Манжа изин күтүү мөөнөтү бүттү. Кайра аракет кылыңыз."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Жеткирүүчүгө тиешелүү ката жөнүндө билдирүү."</item>
</string-array>
<!-- no translation found for permlab_readSyncSettings (6201810008230503052) -->
<skip />
@@ -1908,8 +1906,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Дагы параметрлер"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Ашып-ташууну жабуу"</string>
</resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 0fcbf47..3332de1 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"ຍ້າຍ​ນີ້ວ​ມື​ໄປ​ໄວ​ເກີນ​ໄປ. ກະ​ລຸ​ນາ​ລອງ​ໃໝ່​ອີກ."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"ຍ້າຍ​ນີ້ວ​ມື​ໄປ​ຊ້ເກີນ​ໄປ. ກະ​ລຸ​ນາ​ລອງ​ໃໝ່​ອີກ."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"ຂໍ້​ຄວາມ​ການ​ຜິດ​ພາດ​ການ​ໄດ້​ມາ​ສະ​ເພາະ​ຜູ້​ຂາຍ 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"ບໍ່​ສາ​ມາດ​ປະ​ມວນ​ຜົນ​ໄດ້. ລອງ​ໃໝ່​ອີກ."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"ບໍ່​ມີ​ຮາດ​ແວ​ໃຫ້​ຢູ່."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"ເວ​ລາ​ລາຍ​ນີ້ວ​ມື​ບໍ່​ເຂົ້າ​ເຖິງ​ໄດ້. ລອງ​ໃໝ່​ອີກ."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"ເວ​ລາ​ລາຍ​ນີ້ວ​ມື​ບໍ່​ເຂົ້າ​ເຖິງ​ໄດ້. ລອງ​ໃໝ່​ອີກ."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"ຂໍ້​ຄວາມ​ການ​ຂັດ​ຂ້ອງ​ສະ​ເພາະ​ຜູ້​ຂາຍ"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ອ່ານການຕັ້ງຄ່າຊິ້ງຂໍ້ມູນ"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານການຕັ້ງຄ່າການຊິ້ງຂໍ້ມູນຂອງບັນຊີໄດ້. ຕົວຢ່າງເຊັ່ນ: ມັນຈະສາມາດກວດສອບໄດ້ແອັບຯ People ຖືກຊິ້ງຂໍ້ມູນກັບບັນຊີໃດນຶ່ງແລ້ວຫຼືຍັງ."</string>
@@ -1450,17 +1448,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"ຈົນ​ຮອດ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ຈົນກວ່າ​ທ່ານ​ຈະ​ປິດ​"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ຫຍໍ້"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"ບ​ລັອກ​ການ​ລົບ​ກວນ"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"​ເວ​ລາ​ປິດ​ເຮັດ​ວຽກ"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"ຄືນ​ວັນ​ຈັນຫາ​ສຸກ"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"ທ້າຍ​ອາ​ທິດ"</string>
<string name="muted_by" msgid="6147073845094180001">"ຖືກ​ປິດ​ສຽງ​ໂດຍ <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"ມີ​ບັນ​ຫາ​ພາຍ​ໃນ​ກັບ​ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ, ແລະ​ມັນ​ອາດ​ຈະ​ບໍ່​ສະ​ຖຽນ​ຈົນ​ກວ່າ​ທ່ານ​ຕັ້ງ​ເປັນ​ຂໍ້​ມູນ​ໂຮງ​ງານ​ຄືນ​ແລ້ວ."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"ມີ​ບັນ​ຫາ​ພາຍ​ໃນ​ກັບ​ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ. ຕິດ​ຕໍ່ຜູ້​ຜະ​ລິດ​ຂອງ​ທ່ານ​ສຳ​ລັບ​ລາຍ​ລະ​ອຽດ​ຕ່າງໆ."</string>
@@ -1470,13 +1463,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"ການ​ຂໍ SS ຖືກ​ດັດ​ແປງ​ເປັນ​ການ​ຂໍ DIAL ແລ້ວ."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"ການ​ຂໍ SS ຖືກ​ດັດ​ແປງ​ເປັນ​ການ​ຂໍ USSD ແລ້ວ."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"ການ​ຂໍ SS ຖືກ​ດັດ​ແປງ​ເປັນ​ການ​ຂໍ SS ໃໝ່​ແລ້ວ."</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"ຜອດ​ຮອບນອກ Android USB"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"ຜອດ​ຮອບນອກ USB"</string>
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"ໂຕ​ເລືອກ​ເພີ່ມ​ເຕີມ"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"ປິດ​ການ​ໄຫຼ​ລົ້ນ​ອອກ​ມາ"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index a788332..34fe86c 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -448,7 +448,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Per greitai judinate pirštą. Bandykite dar kartą."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Per lėtai judinate pirštą. Bandykite dar kartą."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Konkretaus paslaugų teikėjo įgijimo klaidos pranešimas (0)"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Nepavyko apdoroti. Bandykite dar kartą."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Aparatinė įranga negalima."</string>
@@ -456,7 +455,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Baigėsi kontrolinio kodo nustatymo skirtasis laikas. Bandykite dar kartą."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Baigėsi kontrolinio kodo nustatymo skirtasis laikas. Bandykite dar kartą."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Konkretaus paslaugų teikėjo klaidos pranešimas"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"skaityti sinchronizavimo nustatymus"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Leidžiama programai skaityti ir sinchronizuoti paskyros nustatymus. Pvz., taip gali būti nustatoma, ar su paskyra sinchronizuota Žmonių programa."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 1665ff6..63aa295 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Pārāk ātra pirksta kustība. Lūdzu, mēģiniet vēlreiz."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Pārāk lēna pirksta kustība. Lūdzu, mēģiniet vēlreiz."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Piegādātāja noteikts iegūšanas kļūdas ziņojums 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Nevar apstrādāt pirksta nospiedumu. Mēģiniet vēlreiz."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Aparatūra nav pieejama."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Pirkstu nospiedumu nolasīšanas aparatūras noildze. Mēģiniet vēlreiz."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Pirkstu nospiedumu nolasīšanas aparatūras noildze. Mēģiniet vēlreiz."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Piegādātāja noteikts kļūdas ziņojums"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lasīt sinhronizācijas iestatījumus"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Ļauj lietotnei lasīt konta sinhronizācijas iestatījumus. Piemēram, šādi var noteikt, vai lietotne Personas ir sinhronizēta ar kontu."</string>
@@ -1487,8 +1485,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Citas opcijas"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Aizvērt pārpildes izvēlni"</string>
</resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 90e302a..202c1f5 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Прстот се движеше премногу брзо. Обидете се повторно."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Прстот се движеше премногу бавно. Обидете се повторно."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Добивање порака за грешка карактеристична за снабдувачот 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Не може да се обработи. Обидете се повторно."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Хардвер не е достапен."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Се достигна времето на истекување на отпечатокот. Обидете се повторно."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Се достигна времето на истекување на отпечатокот. Обидете се повторно."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Порака за грешка карактеристична за снабдувачот."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"прочитај синхронизирани подесувања"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Овозможува апликацијата да ги чита подесувањата за синхронизирање на сметка. На пример, така може да се утврди дали апликацијата „Луѓе“ е синхронизирана со сметка."</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 36f2bd2..8945ae5 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"വിരൽ വേഗത്തിൽ നീക്കി. വീണ്ടും ശ്രമിക്കുക."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"വിരൽ പതുക്കെ നീക്കി. വീണ്ടും ശ്രമിക്കുക."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"വെൻഡർ നിർദ്ദിഷ്‌ട നേടൽ പിശക് സന്ദേശം 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"പ്രോസസ്സ് ചെയ്യാനാവുന്നില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"ഹാർഡ്‌വെയർ ലഭ്യമല്ല."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"വിരലടയാളം നൽകേണ്ട സമയം കഴിഞ്ഞു. വീണ്ടും ശ്രമിക്കുക."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"വിരലടയാളം നൽകേണ്ട സമയം കഴിഞ്ഞു. വീണ്ടും ശ്രമിക്കുക."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"വെൻഡർ നിർദ്ദിഷ്‌ട പിശക് സന്ദേശം."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"സമന്വയ ക്രമീകരണങ്ങൾ റീഡുചെയ്യുക"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ഒരു അക്കൗണ്ടിനായി സമന്വയ ക്രമീകരണങ്ങൾ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഉദാഹരണത്തിന്, ആളുകൾ അപ്ലിക്കേഷൻ ഒരു അക്കൗണ്ടിൽ സമന്വയിപ്പിച്ചിട്ടുണ്ടോയെന്നത് നിർണ്ണയിക്കാൻ ഇതിനാകും."</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index ab502a2..3341381 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Хурууг уншиж дуусаагүй байхад авсан байна. Та дахин уншуулна уу."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Хурууг хэт удаан уншуулсан байна. Та дахин уншуулна уу."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Борлуулагч-хурууны хээ авахад гардаг алдаа 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Мэдээллийг оруулах боломжгүй байна. Дахин оролдоно уу."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Техник хангамж бэлэн бус байна"</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Хурууны хээ оруулах хугацаа өнгөрсөн байна. Дахин оруулна уу."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Хурууны хээ оруулах хугацаа өнгөрсөн байна. Дахин оруулна уу."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Борлуулаг-тодорхой алдааны зурвас"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"синк тохиргоог унших"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Апп нь акаунтын синк тохиргоог унших боломжтой. Жишээ нь энэ нь Хүмүүс апп акаунттай синк хийгдсэн эсэхийг тодорхойлох боломжтой."</string>
@@ -1473,8 +1471,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Нэмэлт сонголтууд"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Илүү цонхнуудыг хаах"</string>
</resources>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index b4c7d58..db9a4b8 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"बोट लवकर हलविले. कृपया पुन्हा प्रयत्न करा."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"बोट हळू हलविले. कृपया पुन्हा प्रयत्न करा."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"व्यापारी-विशिष्‍ट प्राप्ती त्रुटी संदेश 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"प्रक्रिया करण्यात अयशस्वी. पुन्हा प्रयत्न करा."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"हार्डवेअर उपलब्ध नाही."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"फिंगरप्रिंट कालबाह्य झाले. पुन्हा प्रयत्न करा."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"फिंगरप्रिंट कालबाह्य झाले. पुन्हा प्रयत्न करा."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"व्यापारी-विशिष्‍ट त्रुटी संदेश."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"संकालन सेटिंग्‍ज वाचा"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"खात्याच्या संकालन सेटिंग्ज वाचण्यासाठी अॅप ला अनुमती देते. उदाहरणार्थ, हे खात्यासह लोकांचा अॅप संकालित केला आहे किंवा नाही हे निर्धारित करू शकते."</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index acbf1e4..e9f2047 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Jari digerakkan terlalu cepat. Sila cuba lagi."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Jari digerakkan terlalu perlahan. Sila cuba lagi."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Mesej ralat pemerolehan khusus vendor 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Tidak dapat memproses. Cuba lagi."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Perkakasan tidak tersedia."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tamat masa cap jari dicapai. Cuba lagi."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Tamat masa cap jari dicapai. Cuba lagi."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Mesej ralat khusus vendor"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"membaca tetapan penyegerakan"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Membenarkan apl membaca tetapan segerak untuk akaun. Sebagai contoh, ini boleh menentukan sama ada apl Orang disegerakkan dengan akaun."</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index e1c3681..7a05b6a 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"လက်ရွှေ့လျားခြင်း အလွန်မြန်သည်။ ကျေးဇူးပြု၍ ထပ်မံကြိုးစားပါ။"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"လက်ရွှေ့လျားခြင်း အလွန်နှေးသည်။ ကျေးဇူးပြု၍ ထပ်မံကြိုးစားပါ။"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"ရောင်းသူ-တိကျသတ်မှတ်သော ရယူခြင်းဆိုင်ရာ မှားယွင်းချက် စာ ၀"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"လုပ်ဆောင်၍မရပါ။ ထပ်မံကြိုးစားပါ။"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"ပစ္စည်းမရနိုင်ပါ။"</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"လက်ဗွေရာအချိန်ကုန် သွားပါသည်။ ထပ်မံကြိုးစားပါ။"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"လက်ဗွေရာအချိန်ကုန် သွားပါသည်။ ထပ်မံကြိုးစားပါ။"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"ရောင်းသူ-တိကျသတ်မှတ်သော မှားယွင်းချက် စာ။"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ထပ်တူပြုအဆင်အပြင်အားဖတ်ခြင်း"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"အပလီကေးရှင်းအား အကောင့်တစ်ခုအတွက် ထပ်တူညီအောင် လုပ်ဆောင်မှု ဆက်တင်အား ကြည့်ခွင့် ပြုပါ။ ဥပမာ People app က အကောင့်တစ်ခုနဲ့ ထပ်တူညီအောင် လုပ်ရန် ဆက်သွယ်ထားမှု ရှိမရှိ သိရှိနိုင်ခြင်း"</string>
@@ -1450,17 +1448,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>အထိ"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"သင်က ဒါကို ပိတ်မပစ်သည့် အထိ"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ခေါက်ရန်"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"ကြားဖြတ်ဝင်မှုများ ပိတ်ဆို့ရန်"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ကျချိန်"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"ရုံးရက်ညများ"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"စနေတနင်္ဂနွေများ"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> အသံပိတ်သည်"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေပြီး၊ မူလစက်ရုံထုတ်အခြေအနေအဖြစ် ပြန်လည်ရယူနိုင်သည်အထိ အခြေအနေမတည်ငြိမ်နိုင်ပါ။"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေ၏။ အသေးစိတ်သိရန်အတွက် ပစ္စည်းထုတ်လုပ်သူအား ဆက်သွယ်ပါ။"</string>
@@ -1470,11 +1463,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"DIAL တောင်းဆိုချက်အရ SS တောင်းဆိုချက်အား ပြင်ဆင်ထား၏။"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"USSD တောင်းဆိုချက်အရ SS တောင်းဆိုချက်အား ပြင်ဆင်ထား၏။"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS တောင်းဆိုချက်အရ SS တောင်းဆိုချက်အား ပြင်ဆင်ထား၏။"</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB ဘေးဘက်အပေါက်"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"အန်းဒရွိုက်"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB ဘေးရှိပို့တ်"</string>
<string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"နောက်ထပ် ရွေးစရာများ"</string>
<string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"ကိရိယာဘားအပိုအား ပိတ်ရန်"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 3597d1d..e98b888 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Fingeren ble fjernet for raskt. Prøv på nytt."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Fingeren ble fjernet for sakte. Prøv på nytt."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Feilmelding 0 for leverandørspesifikk brukeranskaffelse"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Kunne ikke behandle fingeravtrykket. Prøv på nytt."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Maskinvaren er ikke tilgjengelig."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tidsavbrudd for fingeravtrykk er nådd. Prøv på nytt."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Tidsavbrudd for fingeravtrykk er nådd. Prøv på nytt."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Leverandørspesifikk feilmelding."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lese synkroniseringsinnstillinger"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Lar appen lese synkroniseringsinnstillingene for en konto. For eksempel kan den finne ut om Personer-appen er synkronisert med en konto."</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index de8535c..aa8d6e8 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"औंला निकै छिटो सारियो। कृपया फेरि प्रयास गर्नुहोस्।"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"औंला निकै ढिला सारियो। कृपया फेरि प्रयास गर्नुहोस्।"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"विक्रेता-निर्दिष्ट अधिग्रहण त्रुटि सन्देश 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"प्रसोधन गर्न असमर्थ। फेरि प्रयास गर्नुहोस्।"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"हार्डवेयर उपलब्ध छैन।"</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"औँठाछापको समय सकिएको छ। फेरि प्रयास गर्नुहोस्।"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"औँठाछापको समय सकिएको छ। फेरि प्रयास गर्नुहोस्।"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"विक्रेता-निर्दिष्ट त्रुटि सन्देश।"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"समीकरण सेटिङहरू पढ्नुहोस्"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"अनुप्रयोगलाई खाताको लागि सिङ्क सेटिङहरू पढ्न अनुमति दिन्छ। उदाहरणको लागि यसले व्यक्तिहरको अनुप्रयोग खातासँग सिङ्क भएको नभएको निर्धारण गर्न सक्दछ।"</string>
@@ -1456,17 +1454,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> सम्म"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"तपाईँले यसलाई बन्द नगरेसम्म"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त पार्नुहोस्"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"अवरोधहरू रोक्नुहोस्"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"डाउनटाइम"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"सप्ताह रातहरू"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"सप्ताहन्त"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> द्वारा मौन गरिएको"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"तपाईंको यन्त्रसँग आन्तरिक समस्या छ, र तपाईंले फ्याक्ट्री डाटा रिसेट नगर्दासम्म यो अस्थिर रहन्छ।"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"तपाईंको यन्त्रसँग आन्तरिक समस्या छ। विवरणहरूको लागि आफ्नो निर्मातासँग सम्पर्क गर्नुहोस्।"</string>
@@ -1476,13 +1469,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS अनुरोध DIAL अनुरोधमा परिमार्जन गरिएको छ।"</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS अनुरोध USSD अनुरोधमा परिमार्जन गरिएको छ।"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS अनुरोध नयाँ SS अनुरोधमा परिमार्जन गरिएको छ।"</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB परिधीय पोर्ट"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB परिधीय पोर्ट"</string>
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"थप विकल्पहरू"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"अतिप्रवाह बन्द गर्नुहोस्"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index e388c01..221b918 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Vinger te snel bewogen. Probeer het opnieuw."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Vinger te langzaam bewogen. Probeer het opnieuw."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Leveranciersspecifieke foutmelding voor acquisitie 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Kan niet verwerken. Probeer het opnieuw."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware niet beschikbaar."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Time-out bereikt voor vingerafdruk. Probeer het opnieuw."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Time-out bereikt voor vingerafdruk. Probeer het opnieuw."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Leveranciersspecifieke foutmelding"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"synchronisatie-instellingen lezen"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Hiermee kan de app de synchronisatie-instellingen voor een account lezen. Dit kan bijvoorbeeld bepalen of de app Personen wordt gesynchroniseerd met een account."</string>
@@ -1474,8 +1472,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Meer opties"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Overloop sluiten"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index dc61dd6..8c6805e 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -448,7 +448,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Palec został uniesiony zbyt szybko. Spróbuj ponownie."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Palec został przesunięty zbyt wolno. Spróbuj ponownie."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Komunikat o błędzie pozyskania specyficzny dla dostawcy 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Nie można przetworzyć. Spróbuj ponownie."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Czytnik jest niedostępny."</string>
@@ -456,7 +455,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Osiągnięto limit czasu odczytu linii papilarnych. Spróbuj ponownie."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Osiągnięto limit czasu odczytu linii papilarnych. Spróbuj ponownie."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Komunikat o błędzie specyficzny dla dostawcy."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"czytanie ustawień synchronizacji"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Zezwala aplikacji na odczyt ustawień synchronizacji konta. Pozwala to na przykład określić, czy aplikacja Ludzie jest zsynchronizowana z kontem."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index aa96384..221364f 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"O dedo moveu-se demasiado rápido. Tente novamente."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"O dedo moveu-se demasiado devagar. Tente novamente."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Mensagem de erro de aquisição específica do fornecedor 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Não é possível processar. Tente novamente."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware não disponível."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Foi atingido o limite de tempo da impressão digital. Tente novamente."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Foi atingido o limite de tempo da impressão digital. Tente novamente."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Mensagem de erro específica do fornecedor."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler definições de sincronização"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite que a aplicação leia as definições de sincronização de uma conta. Por exemplo, pode determinar se a aplicação Pessoas está sincronizada com uma conta."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index c288989..0f0965b 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"O dedo foi retirado rápido demais. Tente novamente."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"O movimento do dedo está muito lento. Tente novamente."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Mensagem de erro de aquisição específica de fornecedor 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Não foi possível concluir o processo. Tente novamente."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware indisponível."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tempo máximo para captura da impressão digital atingido. Tente novamente."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Tempo máximo para captura da impressão digital atingido. Tente novamente."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Mensagem de erro específica de fornecedor."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler as configurações de sincronização"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite que o app leia as configurações de sincronização de uma conta. Por exemplo, pode determinar se o app People está sincronizado com uma conta."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index bf96715..41ab078 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Ați mișcat degetul prea repede. Încercați din nou."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Ați mișcat degetul prea încet. Încercați din nou."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Mesaj de eroare 0 specific furnizorului pentru achiziție"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Nu se poate procesa. Încercați din nou."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardware-ul nu este disponibil."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Timpul pentru amprentare a expirat. Încercați din nou."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Timpul pentru amprentare a expirat. Încercați din nou."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Mesaj de eroare specific furnizorului."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"citire setări sincronizare"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite aplicației să citească setările de sincronizare ale unui cont. De exemplu, cu această permisiune aplicația poate determina dacă aplicația Persoane este sincronizată cu un anumit cont."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 301bdaa..0a86298 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -448,7 +448,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Вы слишком быстро убрали палец. Повторите попытку."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Вы слишком долго удерживали палец. Повторите попытку."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Сообщение об ошибке при сканировании отпечатка (0)"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Не удалось распознать отпечаток. Повторите попытку."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Сканер недоступен."</string>
@@ -456,7 +455,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Превышено время ожидания. Повторите попытку."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Превышено время ожидания. Повторите попытку."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Сообщение об ошибке."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"Просмотр настроек синхронизации"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Приложение сможет просматривать настройки синхронизации аккаунта, например определять, включена ли синхронизация для приложения \"Контакты\"."</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 5d799b8..04cc98c 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"ඇඟිල්ල වේගයෙන් ගෙනයන ලදි. කරුණාකර නැවත උත්සාහ කරන්න."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"ඇඟිල්ල සෙමින් ගෙන යන ලදී. කරුණාකර නැවත උත්සාහ කරන්න."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"විකුණුම්කරු-විශේෂිත අත්පත්පත් කර ගැනීමේ දෝෂ පණිවිඩය 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"ක්‍රියාවලිය සම්පූර්ණ කිරීමට නොහැක. නැවත උත්සාහ කරන්න."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"දෘඪාංගය ලද නොහැකිය."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"ඇඟිලි සලකුණු කාල නිමාව ළඟා විය. නැවත උත්සාහ කරන්න."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"ඇඟිලි සලකුණු කාල නිමාව ළඟා විය. නැවත උත්සාහ කරන්න."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"විකුණුම්කරු-විශේෂිත දෝෂ පණිවිඩය."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"සමමුහුර්ත සැකසීම් කියවන්න"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ගිණුම සඳහා සමමුහුර්ත සැකසීම් කියවීමට යෙදුමට අවසර දෙන්න. උදාහරණයක් ලෙස, ගිණුමක් සමඟ පුද්ගල යෙදුම සමමුහුර්ත දැයි මෙයට හඳුනා ගත හැක."</string>
@@ -1477,8 +1475,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"තවත් විකල්ප"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"ඉතිරී යාම වසන්න"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index eb4041c..8eb0f40 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -448,7 +448,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Pohli ste prstom príliš rýchlo. Skúste to znova."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Pohli ste prstom príliš pomaly. Skúste to znova."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Chybové hlásenie o akvizícii týkajúcej sa konkrétneho dodávateľa 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Došlo k chybe spracovania. Skúste to znova."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hardvér nie je k dispozícii"</string>
@@ -456,7 +455,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Časový limit rozpoznania odtlačku vypršal. Skúste to znova."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Časový limit rozpoznania odtlačku vypršal. Skúste to znova."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Chybové hlásenie týkajúce sa konkrétneho dodávateľa"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"čítať nastavenia synchronizácie"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Umožňuje aplikácii čítať nastavenia synchronizácie v účte. Môže napríklad určiť, či je s účtom synchronizovaná aplikácia Ľudia."</string>
@@ -1500,8 +1498,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Ďalšie možnosti"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Zatvoriť rozbaľovaciu ponuku"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index f8a98b1..cffc58d 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -448,7 +448,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Prehiter premik prsta. Poskusite znova."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Prepočasen premik prsta. Poskusite znova."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Vendor-specific acquisition error message 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Obdelava ni mogoča. Poskusite znova."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Strojna oprema ni na voljo."</string>
@@ -456,7 +455,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Dosežena časovna omejitev za prstni odtis. Poskusite znova."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Dosežena časovna omejitev za prstni odtis. Poskusite znova."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Vendor-specifc error message."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"branje nastavitev sinhronizacije"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Aplikaciji omogoča branje nastavitev sinhronizacije za račun. S tem lahko aplikacija na primer ugotovi, ali je aplikacija Ljudje sinhronizirana z računom."</string>
@@ -1500,8 +1498,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Več možnosti"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Zapri presežni element"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index f8b8e8c..e495afa 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Превише брзо сте померили прст. Покушајте поново."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Превише споро сте померили прст. Покушајте поново."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Порука о грешци за аквизицију специфична за произвођача 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Обрада није могућа. Покушајте поново."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Хардвер није доступан."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Временско ограничење за отисак прста је истекло. Покушајте поново."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Временско ограничење за отисак прста је истекло. Покушајте поново."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Порука о грешци специфична за произвођача."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"читање подешавања синхронизације"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Дозвољава апликацији да чита подешавања синхронизације за налог. На пример, овако може да се утврди да ли је апликација Људи синхронизована са налогом."</string>
@@ -1487,8 +1485,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Још опција"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Затвори преклопни мени"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 9e2d02c..95087ac 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Du flyttade fingret för snabbt. Försök igen."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Du flyttade fingret för långsamt. Försök igen."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Leverantörsspecifikt felmeddelande om förvärv 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Det går inte att bearbeta fingeravtrycket. Försök igen."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Maskinvaran är inte tillgänglig."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tidsgränsen för fingeravtrycket har uppnåtts. Försök igen."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Tidsgränsen för fingeravtrycket har uppnåtts. Försök igen."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Leverantörsspecifikt felmeddelande"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"läsa synkroniseringsinställningar"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Tillåter att appen läser synkroniseringsinställningarna för ett konto. Detta kan användas till exempel för att avgöra om appen Personer är synkroniserad med ett konto."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 898084c..b4a60ec 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Ulisogeza kidole kwa kasi mno. Tafadhali jaribu tena."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Ulisogeza kidole pole pole mno. Tafadhali jaribu tena."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Ujumbe maalum kwa muuzaji kuhusu hitilafu ya uletaji wa kitambulisho 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Haikuweza kuchakata. Jaribu tena."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Maunzi hayapatikani."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Muda wa kitambulisho umekwisha. Jaribu tena."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Muda wa kitambulisho umekwisha. Jaribu tena."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Ujumbe maalum kwa muuzaji kuhusu hitilafu."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"kusoma mipangilio ya usawazishaji"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Inaruhusu programu kusoma mipangilio ya upatanishi wa akaunti. Kwa mfano, huku kunaweza kuamua kama programu ya Watu imepatanishwa na akaunti."</string>
@@ -1428,7 +1426,7 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Omba PIN kabla hujabandua"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Omba mchoro wa kufungua kabla hujabandua"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Omba nenosiri kabla hujabandua"</string>
- <string name="package_installed_device_owner" msgid="8420696545959087545">"Kiliwekwa na msimamizi wako"</string>
+ <string name="package_installed_device_owner" msgid="8420696545959087545">"Kilisakinishwa na msimamizi wako"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"Kilifutwa na msimamizi wako"</string>
<string name="battery_saver_description" msgid="1960431123816253034">"Kusaidia kuboresha muda wa matumizi ya betri, inayookoa betri hupunguza utendaji wa kifaa chako na kupunguza mtetemo, huduma za utambuzi wa mahali, na data nyingi ya chini chini. Barua pepe, ujumbe na programu nyingine zinazotege,ea usawazishaji huenda zisisasishwe usipozifungua.\n\nInayookoa betri hujizima kiotomatiki kifaa chako kinapokuwa kinachaji."</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
diff --git a/core/java/android/os/IHardwareService.aidl b/core/res/res/values-sw360dp/dimens.xml
index 38abfc0..4c74264 100644
--- a/core/java/android/os/IHardwareService.aidl
+++ b/core/res/res/values-sw360dp/dimens.xml
@@ -1,5 +1,7 @@
-/**
- * Copyright (c) 2007, The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 2015, 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.
@@ -13,14 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package android.os;
-
-/** {@hide} */
-interface IHardwareService
-{
- // obsolete flashlight support
- boolean getFlashlightEnabled();
- void setFlashlightEnabled(boolean on);
-}
-
+-->
+<resources>
+ <dimen name="chooser_grid_padding">16dp</dimen>
+</resources>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 39fdd78..39fedec 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"விரலை வேகமாக எடுத்துவிட்டீர்கள். மீண்டும் முயலவும்."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"விரலை மெதுவாக எடுத்துவிட்டீர்கள். மீண்டும் முயலவும்."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"விற்பனையாளர் சார்ந்த பெறுதல் தொடர்பான பிழைச் செய்தி 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"செயல்படுத்த முடியவில்லை. மீண்டும் முயலவும்."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"வன்பொருள் இல்லை."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"கைரேகைக்கான நேரம் முடிந்தது. மீண்டும் முயலவும்."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"கைரேகைக்கான நேரம் முடிந்தது. மீண்டும் முயலவும்."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"விற்பனையாளர் சார்ந்த பிழைச் செய்தி."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ஒத்திசைவு அமைப்புகளைப் படித்தல்"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"கணக்கிற்கான ஒத்திசைவு அமைப்புகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது. எடுத்துக்காட்டாக, பீப்பிள் பயன்பாடு கணக்குடன் ஒத்திசைக்கப்பட்டுள்ளதா என்பதை இது தீர்மானிக்கலாம்."</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 20ae99a..f4e0c3c 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"వేలిని చాలా తొందరగా కదిలించారు. దయచేసి మళ్లీ ప్రయత్నించండి."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"వేలిని చాలా నిదానంగా కదిలించారు. దయచేసి మళ్లీ ప్రయత్నించండి."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"విక్రేత-నిర్దిష్ట సేకరణ లోప సందేశం 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"ప్రాసెస్ చేయడం సాధ్యపడలేదు. మళ్లీ ప్రయత్నించండి."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"హార్డ్‌వేర్ అందుబాటులో లేదు."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"వేలిముద్ర గడువు సమయం చేరుకుంది. మళ్లీ ప్రయత్నించండి."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"వేలిముద్ర గడువు సమయం చేరుకుంది. మళ్లీ ప్రయత్నించండి."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"విక్రేత-నిర్దిష్ట లోప సందేశం."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"సమకాలీకరణ సెట్టింగ్‌లను చదవడం"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ఖాతా యొక్క సమకాలీకరణ సెట్టింగ్‌లను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఉదాహరణకు, వ్యక్తుల అనువర్తనం ఖాతాతో సమకాలీకరించబడాలా లేదా అనే విషయాన్ని ఇది నిశ్చయించవచ్చు."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 4e05042..44b07e3 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"เคลื่อนนิ้วเร็วเกินไป โปรดลองอีกครั้ง"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"เคลื่อนนิ้วช้าเกินไป โปรดลองอีกครั้ง"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"ข้อความแสดงข้อผิดพลาดการกระทำเฉพาะผู้ขาย 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"ไม่สามารถดำเนินการได้ โปรดลองอีกครั้ง"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"ฮาร์ดแวร์ไม่พร้อมใช้งาน"</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"หมดเวลาใช้ลายนิ้วมือแล้ว โปรดลองอีกครั้ง"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"หมดเวลาใช้ลายนิ้วมือแล้ว โปรดลองอีกครั้ง"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"ข้อความแสดงข้อผิดพลาดเฉพาะผู้ขาย"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"อ่านการตั้งค่าการซิงค์แล้ว"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"อนุญาตให้แอปพลิเคชันอ่านการตั้งค่าการซิงค์ของบัญชี ตัวอย่างเช่น การอนุญาตนี้สามารถระบุได้ว่าแอปพลิเคชัน People ซิงค์กับบัญชีหรือไม่"</string>
@@ -1474,8 +1472,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"ตัวเลือกเพิ่มเติม"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"ปิดรายการเพิ่มเติม"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 85354d7..4630e76 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Masyadong mabilis ang paggalaw ng daliri. Pakisubukang muli."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Masyadong mabagal ang paggalaw ng daliri. Pakisubukang muli."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Mensahe ng error sa pagkuha na partikular sa vendor 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Hindi maproseso. Subukang muli."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Hindi available ang hardware."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Nag-time out ang fingerprint. Subukang muli."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Nag-time out ang fingerprint. Subukang muli."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Mensahe ng error na partikular sa vendor."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"basahin ang mga setting ng sync"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Pinapayagan ang app na basahin ang mga setting ng pag-sync para sa isang account. Halimbawa, matutukoy nito kung naka-sync ang app na Mga Tao sa isang account."</string>
@@ -1449,17 +1447,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Hanggang <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hanggang sa i-off mo ito"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"I-collapse"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"I-block ang mga pagkaantala"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Walang serbisyo"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"Mga Weeknight"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"Sabado at Linggo"</string>
<string name="muted_by" msgid="6147073845094180001">"Na-mute ng <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"May internal na problema sa iyong device, at maaaring hindi ito maging stable hanggang sa i-reset mo ang factory data."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"May internal na problema sa iyong device. Makipag-ugnayan sa iyong manufacturer upang malaman ang mga detalye."</string>
@@ -1469,13 +1462,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Ginawang DIAL request ang SS request."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Ginawang USSD request ang SS request."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Ginawang bagong SS request ang SS request."</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Peripheral Port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral Port"</string>
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Higit pang mga opsyon"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Isara ang overflow"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index d3e88d0..c162151 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Parmak hareketi çok hızlıydı. Lütfen tekrar deneyin."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Parmak hareketi çok yavaştı. Lütfen tekrar deneyin."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Tedarikçi firmaya özel edinme hata iletisi 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"İşlenemedi. Tekrar deneyin."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Donanım yok."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Parmak izi için zaman aşımı oluştu. Tekrar deneyin."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Parmak izi için zaman aşımı oluştu. Tekrar deneyin."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Tedarikçi firmaya özel hata iletisi."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"senk. ayarlarını okuma"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Uygulamaya bir hesaba ait senkronizasyon ayarlarını okuma izni verir. Örneğin, bu izne sahip bir uygulama Kişiler uygulamasının bir hesapla senkronize olup olmadığını belirleyebilir."</string>
@@ -1474,8 +1472,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Diğer seçenekler"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Taşan araç çubuğunu kapat"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 9fb33c6d..bccec41 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -448,7 +448,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Ви забрали палець надто швидко. Повторіть спробу."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Ви забрали палець надто повільно. Повторіть спробу."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Повідомленя про помилку: 0. Не отримано відбиток постачальника"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Не вдалось обробити. Повторіть спробу."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Апаратне забезпечення недоступне."</string>
@@ -456,7 +455,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Час очікування відбитка минув. Повторіть спробу."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Час очікування відбитка минув. Повторіть спробу."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Повідомлення про помилку щодо відбитка постачальника."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"читати налаштування синхронізації"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Дозволяє програмі читати налаштування синхронізації для облікового запису, наприклад, визначати, чи програма Люди синхронізується з обліковим записом."</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index d2f1da9..9505d4d 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"انگلی کو کافی تیزی سے ہٹا لیا گیا۔ براہ کرم دوبارہ کوشش کریں۔"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"انگلی کو بہت آہستہ ہٹا لیا گیا۔ براہ کرم دوبارہ کوشش کریں۔"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"وینڈر کیلئے مخصوص حصول کی خرابی کا پیغام 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"کارروائی کرنے سے قاصر ہے۔ دوبارہ کوشش کریں۔"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"ہارڈ ویئر دستیاب نہیں ہے۔"</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"فنگر پرنٹ کی میعاد ختم ہوگئی۔ دوبارہ کوشش کریں۔"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"فنگر پرنٹ کی میعاد ختم ہوگئی۔ دوبارہ کوشش کریں۔"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"وینڈر کیلئے مخصوص خرابی کا پیغام۔"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"مطابقت پذیری کی ترتیبات پڑھیں"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"‏ایپ کو کسی اکاؤنٹ کیلئے مطابقت پذیری کی ترتیبات پڑھنے کی اجازت دیتا ہے۔ مثلا، یہ تعین کرسکتا ہے کہ آیا People ایپ کسی اکاؤنٹ کے ساتھ مطابقت پذیر ہے۔"</string>
@@ -1475,8 +1473,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"مزید اختیارات"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"اوورفلو بند کریں"</string>
</resources>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 10cd282..efefa03 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -447,7 +447,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Barmoq juda tez harakatlandi. Qayta urinib ko‘ring."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Barmoq juda sekin harakatlandi. Qayta urinib ko‘ring."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Sotuvchidan barmoq izini olishda sodir bo‘ladigan xatolik xabari 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Barmoq izini aniqlab bo‘lmadi. Qayta urinib ko‘ring."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Barmoq izi sensoridan foydalanib bo‘lmaydi."</string>
@@ -455,7 +454,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Barmoq izini aniqlash vaqti tugab qoldi. Qayta urinib ko‘ring."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Barmoq izini aniqlash vaqti tugab qoldi. Qayta urinib ko‘ring."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Xizmat bilan bog‘liq xatolik xabari."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"sinx-sh sozlamalarini o‘qish"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Ilovaga hisobning sinxronlash sozlamalarini o‘qish uchun ruxsat beradi. Masalan, bu \"Odamlar\" ilovasi hisob bilan sinxronlangan yoki aksini aniqlay oladi."</string>
@@ -1450,17 +1448,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Men o‘chirmaguncha"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Yig‘ish"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"Bezovta qilinishlar"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Nofaol vaqt"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"Ish kunlari kechasi"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"Dam olish kunlari"</string>
<string name="muted_by" msgid="6147073845094180001">"“<xliff:g id="THIRD_PARTY">%1$s</xliff:g>” tomonidan ovozsiz qilingan"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. U zavod sozlamalari tiklanmaguncha barqaror ishlamasligi mumkin."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. Tafsilotlar uchun qurilmangiz ishlab chiqaruvchisiga murojaat qiling."</string>
@@ -1470,13 +1463,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS so‘rovi DIAL so‘roviga o‘zgartirildi."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS so‘rovi USSD so‘roviga o‘zgartirildi."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS so‘rovi yangi SS so‘roviga o‘zgartirildi."</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android tashqi USB porti"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Tashqi USB porti"</string>
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Ko‘proq"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Qalqib turuvchi asboblar panelini yopish"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 15ca9a5..2d41304 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Ngón tay đã di chuyển quá nhanh. Vui lòng thử lại."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Ngón tay đã di chuyển quá chậm. Vui lòng thử lại."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Thông báo lỗi lấy vân tay từ người bán cụ thể 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Không thể xử lý. Hãy thử lại."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Phần cứng không có sẵn."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Đã hết thời gian chờ vân tay. Hãy thử lại."</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Đã hết thời gian chờ vân tay. Hãy thử lại."</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Thông báo lỗi cho người bán cụ thể."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"đọc cài đặt đồng bộ hóa"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Cho phép ứng dụng đọc cài đặt đồng bộ hóa cho tài khoản. Ví dụ: việc này có thể xác định liệu ứng dụng Mọi người đã được đồng bộ hóa với tài khoản chưa."</string>
@@ -1474,8 +1472,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Tùy chọn khác"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Đóng tràn"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 63fd8db..39b5101 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"手指移动太快,请重试。"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"手指移动太慢,请重试。"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"针对供应商的指纹获取错误消息 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"无法处理指纹,请重试。"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"硬件无法使用。"</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"指纹录入操作超时,请重试。"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"指纹录入操作超时,请重试。"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"针对供应商的错误消息。"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"读取同步设置"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"允许该应用读取某个帐户的同步设置。例如,此权限可确定“联系人”应用是否与某个帐户同步。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 07722fc..22025ab 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"手指移動太快。請再試一次。"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"手指移動太慢。請再試一次。"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"供應商專用採集錯誤訊息 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"無法處理。請再試一次。"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"硬件無法使用。"</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"指紋已逾時。請再試一次。"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"指紋已逾時。請再試一次。"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"供應商專用錯誤訊息。"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"讀取同步處理設定"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"允許應用程式讀取帳戶的同步設定,例如確定「通訊錄」應用程式是否和某個帳戶保持同步。"</string>
@@ -1474,8 +1472,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"更多選項"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"關閉工具列溢位功能"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 49fdd9c..0ef676a 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"手指移動速度過快,請再試一次。"</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"手指移動速度過慢,請再試一次。"</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"供應商自訂的指紋擷取錯誤訊息 0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"無法辨識指紋,請再試一次。"</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"硬體無法使用。"</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"指紋處理作業逾時,請再試一次。"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"指紋處理作業逾時,請再試一次。"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"供應商自訂的錯誤訊息。"</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"讀取同步處理設定"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"允許應用程式讀取帳戶的同步處理設定,例如判斷「使用者」應用程式是否和某個帳戶進行同步處理。"</string>
@@ -1474,8 +1472,6 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
<skip />
- <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
- <skip />
- <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
- <skip />
+ <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"更多選項"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"關閉溢出模式"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 58d012d..007ff53 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -446,7 +446,6 @@
<string name="fingerprint_acquired_too_fast" msgid="5303368850245663580">"Umunwe uhanjiswe ngokushesha kakhulu. Sicela uzame futhi."</string>
<string name="fingerprint_acquired_too_slow" msgid="7381891107120721078">"Umunwe uhanjiswe kancane kakhulu. Sicela uzame futhi."</string>
<string-array name="fingerprint_acquired_vendor">
- <item msgid="2892952818207766996">"Umlayezo wephutha wokutholwa okucacisiwe komthengisi ongu-0"</item>
</string-array>
<string name="fingerprint_error_unable_to_process" msgid="4232401562838100026">"Ayikwazi ukucubungula. Zama futhi."</string>
<string name="fingerprint_error_hw_not_available" msgid="6162709753784993771">"Izingxenyekazi zekhompuyutha azitholakali."</string>
@@ -454,7 +453,6 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Kufinyelelwe isikhathi sokuvala sezigxivizo zeminwe. Zama futhi"</string>
<string name="fingerprint_error_vendor" msgid="3175724710791609491">"Kufinyelelwe isikhathi sokuvala sezigxivizo zeminwe. Zama futhi"</string>
<string-array name="fingerprint_error_vendor">
- <item msgid="5804600450373644614">"Umlayezo wephutha ocacile womthengisi."</item>
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"funda izilungiselelo zokuvumelanisa"</string>
<string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Ivumela uhlelo lokusebenza ukufunda izilungiselelo zokuvumelanisa ze-akhawunti. Isibonelo, lokhu kungacacisa ukuthi noma ngabe uhlelo lokusebenza le-People livumelanisiwe ne-akhawunti."</string>
@@ -1449,17 +1447,12 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"Kuze kube ngu-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Uze uvale lokhu"</string>
- <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
- <skip />
+ <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Goqa"</string>
- <!-- no translation found for zen_mode_feature_name (289097150786114338) -->
- <skip />
- <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
- <skip />
- <!-- no translation found for zen_mode_default_weeknights_name (2069189413656431610) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2377398437072017011) -->
- <skip />
+ <string name="zen_mode_feature_name" msgid="289097150786114338">"Vimba iziphazamiso"</string>
+ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Isikhathi sokuphumula"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"Ubusuku beviki"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"Izimpelasonto"</string>
<string name="muted_by" msgid="6147073845094180001">"Ithuliswe ngu-<xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Kukhona inkinga yangaphakathi ngedivayisi yakho, futhi ingase ibe engazinzile kuze kube yilapho usetha kabusha yonke idatha."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Kukhona inkinga yangaphakathi ngedivayisi yakho. Xhumana nomkhiqizi wakho ukuze uthole imininingwane."</string>
@@ -1469,11 +1462,9 @@
<string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"Isicelo se-SS siguqulelwe kusicelo se-DIAL."</string>
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Isicelo se-SS siguqulelwe kusicelo se-USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Isicelo se-SS siguqulelwe kusicelo esisha se-SS."</string>
- <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
- <skip />
+ <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Imbobo ye-Android USB Peripheral"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"I-Android"</string>
- <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
- <skip />
+ <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Imbobo ye-USB Peripheral"</string>
<string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Izinketho eziningi"</string>
<string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Vala ukuchichima"</string>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index cbd74cd..04e40a7 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5988,11 +5988,11 @@
<enum name="noScale" value="0"/>
<!-- This should be used when the animation's moving distance is proportional to screen,
as the scaling is based on screen size. -->
- <enum name="screen" value="1"/>
+ <enum name="screenBased" value="1"/>
<!-- This is for animations that have a distance defined in dp, which will be the same
across different devices. In this case, scaling is based on the physical distance
per dp on the current device. -->
- <enum name="dp" value="2"/>
+ <enum name="dpBased" value="2"/>
</attr>
</declare-styleable>
@@ -6042,6 +6042,7 @@
<!-- child animations should be played sequentially, in the same order as the xml. -->
<enum name="sequentially" value="1" />
</attr>
+ <attr name="durationScaleHint" />
</declare-styleable>
<!-- ========================== -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6d9bbae..8c78e74 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -23,6 +23,7 @@
<!-- Do not translate. Defines the slots for the right-hand side icons. That is to say, the
icons in the status bar that are not notifications. -->
<string-array name="config_statusBarIcons">
+ <item><xliff:g id="id">managed_profile</xliff:g></item>
<item><xliff:g id="id">ime</xliff:g></item>
<item><xliff:g id="id">sync_failing</xliff:g></item>
<item><xliff:g id="id">sync_active</xliff:g></item>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 2654a25..100b161 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -394,4 +394,5 @@
<dimen name="floating_toolbar_minimum_overflow_height">192dp</dimen>
<dimen name="floating_toolbar_overflow_width">130dp</dimen>
<dimen name="floating_toolbar_margin">2dp</dimen>
+ <dimen name="chooser_grid_padding">0dp</dimen>
</resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index 6fd39f6..937e92ad 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -112,6 +112,9 @@
<dimen name="dialog_padding_material">24dp</dimen>
<dimen name="dialog_padding_top_material">18dp</dimen>
+ <!-- Dialog padding minus control padding, used to fix alignment. -->
+ <dimen name="select_dialog_padding_start_material">20dp</dimen>
+
<!-- Padding above and below selection dialog lists. -->
<dimen name="dialog_list_padding_vertical_material">8dp</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 326a1db..2dbba8e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1655,8 +1655,8 @@
<!-- On the unlock pattern screen, shown at the top of the unlock screen to tell the user what to do. Below this text is the place for theu ser to draw the pattern. -->
<string name="lockscreen_pattern_instructions">Draw pattern to unlock</string>
- <!-- Button at the bottom of the unlock screen to make an emergency call. -->
- <string name="lockscreen_emergency_call">Emergency call</string>
+ <!-- Button at the bottom of the unlock screen to make an emergency call or access other emergency assistance functions. -->
+ <string name="lockscreen_emergency_call">Emergency</string>
<!-- Button at the bottom of the unlock screen that lets the user return to a call -->
<string name="lockscreen_return_to_call">Return to call</string>
<!-- Shown to confirm that the user entered their lock pattern correctly. -->
@@ -3438,8 +3438,6 @@
<string name="display_manager_overlay_display_secure_suffix">, secure</string>
<!-- Keyguard strings -->
- <!-- Label shown on emergency call button in keyguard -->
- <string name="kg_emergency_call_label">Emergency call</string>
<!-- Message shown in pattern unlock after some number of unsuccessful attempts -->
<string name="kg_forgot_pattern_button_text">Forgot Pattern</string>
<!-- Message shown when user enters wrong pattern -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 42d187d..36a736a 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2232,4 +2232,7 @@
<java-symbol type="layout" name="date_picker_month_item_material" />
<java-symbol type="id" name="month_view" />
<java-symbol type="integer" name="config_zen_repeat_callers_threshold" />
+ <java-symbol type="layout" name="chooser_grid" />
+ <java-symbol type="layout" name="resolve_grid_item" />
+ <java-symbol type="id" name="title_icon" />
</resources>
diff --git a/core/tests/coretests/src/android/net/IpPrefixTest.java b/core/tests/coretests/src/android/net/IpPrefixTest.java
index cf278fb..fcc6389 100644
--- a/core/tests/coretests/src/android/net/IpPrefixTest.java
+++ b/core/tests/coretests/src/android/net/IpPrefixTest.java
@@ -29,6 +29,10 @@ import junit.framework.TestCase;
public class IpPrefixTest extends TestCase {
+ private static InetAddress Address(String addr) {
+ return InetAddress.parseNumericAddress(addr);
+ }
+
// Explicitly cast everything to byte because "error: possible loss of precision".
private static final byte[] IPV4_BYTES = { (byte) 192, (byte) 0, (byte) 2, (byte) 4};
private static final byte[] IPV6_BYTES = {
@@ -209,6 +213,34 @@ public class IpPrefixTest extends TestCase {
}
@SmallTest
+ public void testContains() {
+ IpPrefix p = new IpPrefix("2001:db8:f00::ace:d00d/127");
+ assertTrue(p.contains(Address("2001:db8:f00::ace:d00c")));
+ assertTrue(p.contains(Address("2001:db8:f00::ace:d00d")));
+ assertFalse(p.contains(Address("2001:db8:f00::ace:d00e")));
+ assertFalse(p.contains(Address("2001:db8:f00::bad:d00d")));
+ assertFalse(p.contains(Address("2001:4868:4860::8888")));
+ assertFalse(p.contains(null));
+ assertFalse(p.contains(Address("8.8.8.8")));
+
+ p = new IpPrefix("192.0.2.0/23");
+ assertTrue(p.contains(Address("192.0.2.43")));
+ assertTrue(p.contains(Address("192.0.3.21")));
+ assertFalse(p.contains(Address("192.0.0.21")));
+ assertFalse(p.contains(Address("8.8.8.8")));
+ assertFalse(p.contains(Address("2001:4868:4860::8888")));
+
+ IpPrefix ipv6Default = new IpPrefix("::/0");
+ assertTrue(ipv6Default.contains(Address("2001:db8::f00")));
+ assertFalse(ipv6Default.contains(Address("192.0.2.1")));
+
+ IpPrefix ipv4Default = new IpPrefix("0.0.0.0/0");
+ assertTrue(ipv4Default.contains(Address("255.255.255.255")));
+ assertTrue(ipv4Default.contains(Address("192.0.2.1")));
+ assertFalse(ipv4Default.contains(Address("2001:db8::f00")));
+ }
+
+ @SmallTest
public void testHashCode() {
IpPrefix p;
int oldCode = -1;
diff --git a/core/tests/coretests/src/android/net/RouteInfoTest.java b/core/tests/coretests/src/android/net/RouteInfoTest.java
index 0b88bc7..831fefd 100644
--- a/core/tests/coretests/src/android/net/RouteInfoTest.java
+++ b/core/tests/coretests/src/android/net/RouteInfoTest.java
@@ -90,6 +90,7 @@ public class RouteInfoTest extends TestCase {
assertFalse(r.matches(Address("2001:db8:f00::ace:d00e")));
assertFalse(r.matches(Address("2001:db8:f00::bad:d00d")));
assertFalse(r.matches(Address("2001:4868:4860::8888")));
+ assertFalse(r.matches(Address("8.8.8.8")));
r = new PatchedRouteInfo(Prefix("192.0.2.0/23"), null, "wlan0");
assertTrue(r.matches(Address("192.0.2.43")));
diff --git a/docs/html-ndk/ndk/downloads/downloads_toc.cs b/docs/html-ndk/ndk/downloads/downloads_toc.cs
new file mode 100644
index 0000000..66d0007
--- /dev/null
+++ b/docs/html-ndk/ndk/downloads/downloads_toc.cs
@@ -0,0 +1,21 @@
+<?cs # Table of contents for Dev Guide.
+
+ For each document available in translation, add an localized title to this TOC.
+ Do not add localized title for docs not available in translation.
+ Below are template spans for adding localized doc titles. Please ensure that
+ localized titles are added in the language order specified below.
+?>
+
+
+<ul id="nav">
+ <li><a href="/ndk/downloads/index.html"><span class="en">NDK Download</span></a></li>
+</ul>
+
+
+<script type="text/javascript">
+<!--
+ buildToggleLists();
+ changeNavLang(getLangPref());
+//-->
+</script>
+
diff --git a/docs/html-ndk/ndk/downloads/index.jd b/docs/html-ndk/ndk/downloads/index.jd
new file mode 100644
index 0000000..ef00069
--- /dev/null
+++ b/docs/html-ndk/ndk/downloads/index.jd
@@ -0,0 +1,4 @@
+page.title=NDK Downloads
+@jd:body
+
+<p>downloads \ No newline at end of file
diff --git a/docs/html-ndk/ndk/guides/guides_toc.cs b/docs/html-ndk/ndk/guides/guides_toc.cs
new file mode 100644
index 0000000..e6bc199
--- /dev/null
+++ b/docs/html-ndk/ndk/guides/guides_toc.cs
@@ -0,0 +1,22 @@
+<?cs # Table of contents for Dev Guide.
+
+ For each document available in translation, add an localized title to this TOC.
+ Do not add localized title for docs not available in translation.
+ Below are template spans for adding localized doc titles. Please ensure that
+ localized titles are added in the language order specified below.
+?>
+
+
+<ul id="nav">
+ <li><a href="/ndk/guides/index.html"><span class="en">Getting Started</span></a></li>
+ <li><a href="/ndk/guides/pg_html/md_1__concepts__concepts.html">Concepts</a></li>
+</ul>
+
+
+<script type="text/javascript">
+<!--
+ buildToggleLists();
+ changeNavLang(getLangPref());
+//-->
+</script>
+
diff --git a/docs/html-ndk/ndk/guides/index.jd b/docs/html-ndk/ndk/guides/index.jd
new file mode 100644
index 0000000..8c3ecab
--- /dev/null
+++ b/docs/html-ndk/ndk/guides/index.jd
@@ -0,0 +1,4 @@
+page.title=Concepts
+@jd:body
+
+<p>To use the NDK, you must download it and install it separately from the SDK. To do so, follow these directions. \ No newline at end of file
diff --git a/docs/html-ndk/ndk/guides/md_1__concepts__concepts.html b/docs/html-ndk/ndk/guides/md_1__concepts__concepts.html
new file mode 100644
index 0000000..2dcf6ae
--- /dev/null
+++ b/docs/html-ndk/ndk/guides/md_1__concepts__concepts.html
@@ -0,0 +1,4 @@
+page.title=Concepts
+@jd:body
+
+<p>This section provides a high-level explanation of how the NDK works. The Android NDK is a set of tools allowing you to embed C or C++ (“native code”) into your Android apps. The ability to use native code in Android apps can be particularly useful to developers who wish to do one or more of the following: \ No newline at end of file
diff --git a/docs/html-ndk/ndk/index.jd b/docs/html-ndk/ndk/index.jd
new file mode 100644
index 0000000..f1c5ce6
--- /dev/null
+++ b/docs/html-ndk/ndk/index.jd
@@ -0,0 +1,15 @@
+fullpage=true
+page.viewport_width=970
+excludeFromSuggestions=true
+page.metaDescription=The official Android NDK developer web site.
+page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3f61-WpRguHq-aNjtF7xJjMTSi79as" />
+
+@jd:body
+
+
+<h1>SUPER FANCY NDK LANDING PAGE<h1>
+
+<p>Welcome to the placeholder text for the NDK. Here, you'll find all of the details you need to
+combine the power of native code with Android flexibility and compatibility. The documents here
+help you get started, introduce some key concepts that you should know when using the NDK, and then
+provide a variety of other information that you'll find helpful while developing your app.</p>
diff --git a/docs/html-ndk/ndk/reference/index.jd b/docs/html-ndk/ndk/reference/index.jd
new file mode 100644
index 0000000..a496f19
--- /dev/null
+++ b/docs/html-ndk/ndk/reference/index.jd
@@ -0,0 +1,4 @@
+page.title=Reference
+@jd:body
+
+<p>NDK reference docs \ No newline at end of file
diff --git a/docs/html-ndk/ndk/reference/reference_toc.cs b/docs/html-ndk/ndk/reference/reference_toc.cs
new file mode 100644
index 0000000..01364a6
--- /dev/null
+++ b/docs/html-ndk/ndk/reference/reference_toc.cs
@@ -0,0 +1,21 @@
+<?cs # Table of contents for Dev Guide.
+
+ For each document available in translation, add an localized title to this TOC.
+ Do not add localized title for docs not available in translation.
+ Below are template spans for adding localized doc titles. Please ensure that
+ localized titles are added in the language order specified below.
+?>
+
+
+<ul id="nav">
+ <li><a href="/ndk/reference/index.html"><span class="en">foo.h</span></a></li>
+</ul>
+
+
+<script type="text/javascript">
+<!--
+ buildToggleLists();
+ changeNavLang(getLangPref());
+//-->
+</script>
+
diff --git a/docs/html-ndk/ndk/samples/index.jd b/docs/html-ndk/ndk/samples/index.jd
new file mode 100644
index 0000000..b333aa7
--- /dev/null
+++ b/docs/html-ndk/ndk/samples/index.jd
@@ -0,0 +1,4 @@
+page.title=Samples
+@jd:body
+
+<p>NDK samples \ No newline at end of file
diff --git a/docs/html-ndk/ndk/samples/samples_toc.cs b/docs/html-ndk/ndk/samples/samples_toc.cs
new file mode 100644
index 0000000..9fb036e
--- /dev/null
+++ b/docs/html-ndk/ndk/samples/samples_toc.cs
@@ -0,0 +1,21 @@
+<?cs # Table of contents for Dev Guide.
+
+ For each document available in translation, add an localized title to this TOC.
+ Do not add localized title for docs not available in translation.
+ Below are template spans for adding localized doc titles. Please ensure that
+ localized titles are added in the language order specified below.
+?>
+
+
+<ul id="nav">
+ <li><a href="/ndk/samples/index.html"><span class="en">Stuff</span></a></li>
+</ul>
+
+
+<script type="text/javascript">
+<!--
+ buildToggleLists();
+ changeNavLang(getLangPref());
+//-->
+</script>
+
diff --git a/docs/html/distribute/googleplay/families/about.jd b/docs/html/distribute/googleplay/families/about.jd
new file mode 100644
index 0000000..c542e0f
--- /dev/null
+++ b/docs/html/distribute/googleplay/families/about.jd
@@ -0,0 +1,67 @@
+page.title=Designed for Families
+page.metaDescription=Designed for Families helps you make your apps and games more discoverable to families.
+page.image=/distribute/images/about-dff-sm.jpg
+meta.tags="families, googleplay, distribution"
+page.tags="families"
+
+@jd:body
+
+<p>
+ In several weeks, a new family-focused experience on Google Play will give
+ users new ways to browse, search, and discover high quality apps and games
+ for their families.
+</p>
+
+<p>
+ To support a more family-friendly store, developers are invited to opt-in
+ family-focused apps and games to the new Designed for Families program. Apps
+ that meet the <a href=
+ "https://support.google.com/googleplay/android-developer/answer/6184502">program
+ requirements</a> will be shown in the new family experience so that
+ parents can find suitable, trusted, high-quality apps and games more easily.
+</p>
+
+<img src="{@docRoot}distribute/images/about-dff-sm.jpg">
+
+<p>
+ Opt-in your apps and games today using the tools and processes you currently
+ use to manage your apps in the Developer Console. Your apps in the program
+ can benefit from enhanced discoverability in addition to maintaining their
+ existing categories, rankings, and reviews elsewhere on the Google Play
+ store.
+</p>
+
+<h2 id="elibibility">Eligibility</h2>
+
+<p>
+ Apps in the family-friendly experience on Google Play will be more
+ discoverable by parents and families, who expect the apps to be age
+ appropriate. The Designed for Families program is designed to be inclusive of
+ apps that are made for kids as well as those that can be enjoyed by the
+ entire family. To address this audience, there are specific guidelines and
+ policies your apps need to meet, which will be assessed in an app content
+ review.
+</p>
+
+<p>
+ Make sure that you're familiar with the policies that your app must comply
+ with. These include <a href=
+ "http://play.google.com/about/developer-content-policy.html">content
+ policies</a>, the <a href=
+ "http://play.google.com/about/developer-distribution-agreement.html">Developer
+ Distribution Agreement</a>, and the <a href=
+ "https://play.google.com/intl/ALL_us/about/families/developer-distribution-agreement-addendum.html">
+ Designed for Families DDA Addendum</a>.
+</p>
+
+<p>
+ Your app must also meet the <a href=
+ "https://support.google.com/googleplay/android-developer/answer/6184502">Designed
+ for Families program requirements</a> listed in the Google Play Developer
+ Help Center.
+</p>
+
+<div class="paging-links" style="padding-top:.75em;">
+ <a href="{@docRoot}distribute/googleplay/families/start.html" class=
+ "next-class-link">Next: Opt-In</a>
+</div>
diff --git a/docs/html/distribute/googleplay/families/faq.jd b/docs/html/distribute/googleplay/families/faq.jd
new file mode 100644
index 0000000..c6fbf86
--- /dev/null
+++ b/docs/html/distribute/googleplay/families/faq.jd
@@ -0,0 +1,336 @@
+page.title=Frequently Asked Questions
+meta.tags="families", "guidelines", "quality"
+page.tags="families", "addendum"
+page.metaDescription=Questions and answers about Designed for Families
+
+@jd:body
+
+ <style>
+ dt {
+ font-weight:bold;
+ }
+ </style>
+
+<div id="qv-wrapper">
+<ol id="qv">
+<h2>In this document</h2>
+<ol>
+ <li><a href="#review">App Review and Opt-In</a></li>
+ <li><a href="#monetization">Monetization</a></li>
+ <li><a href="#other">Other Questions</a></li>
+</ol>
+</div>
+
+<p>
+ The sections below provide more information about Designed for Families
+ and answer common questions that you might have about it.
+</p>
+
+
+<h2 id="review">App Review and Opt-In</h2>
+
+<dl>
+<dt>How do I opt-in my app(s)?</dt>
+
+<dl>
+ <dd>
+ You can opt-in to Designed for Families on the Pricing and Distribution tab
+ for your app on the Google Play Developer Console. Here's a <a href=
+ "{@docRoot}distribute/googleplay/families/start.html">step-by-step
+ walkthrough</a>.
+ </dd>
+
+ <dt>
+ Where do I disclose my app’s interactive features? Why are you collecting
+ this information?
+ </dt>
+
+ <dd>
+ Interactive feature disclosures are part of the content rating
+ questionnaire. You have an opportunity to review your disclosures as
+ part of the Designed for Families program opt-in flow. We collect this
+ information so that users can make informed choices when evaluating your
+ app.
+ </dd>
+
+ <dt>
+ What is COPPA?
+ </dt>
+
+ <dd>
+ COPPA is the Federal Trade Commission’s (FTC) Child Online Privacy
+ Protection Rule. More details are available on the <a
+ href="http://www.ftc.gov/tips-advice/business-center/guidance/complying-coppa-frequently-asked-questions">
+ FTC's FAQ about COPPA</a>. Note that Google Play cannot provide legal guidance to developers
+ on how to comply with COPPA or other child statutes.
+ </dd>
+
+ <dt>
+ Do I need to provide an up-to-date privacy policy and where do I do that?
+ </dt>
+
+ <dd>
+ Yes, you need to provide a link to a persistent privacy policy on your
+ app’s store listing and confirm your compliance with local privacy statutes
+ in the Developer Console. To add or review your privacy policy, choose your
+ app in the Developer Console and then scroll to the bottom of the
+ <strong>Store Listing</strong> section.
+ </dd>
+
+ <dt>
+ How many age groups can I select?
+ </dt>
+
+ <dd>
+ You can select up to two adjacent age groups. Age groups are: Ages 5 &
+ Under, Ages 6-8, and Ages 9-12. However, if your app targets audiences
+ comprised of children and older audiences, you must select the <em>General
+ Audience</em> category.
+ </dd>
+
+ <dt>
+ How many content categories can I select in the Designed for Families
+ program?
+ </dt>
+
+ <dd>
+ You can select one category as part of the Designed for Families program
+ and another category for the general Google Play store.
+ </dd>
+
+ <dt>
+ What are the Designed for Families categories?
+ </dt>
+
+<ul>
+<li><strong>Action & Adventure</strong>: These are action-oriented apps/games and include everything
+ from racing games, fairy tale adventures, and more.
+ </li>
+
+ <li style="list-style: none"><strong>Brain Games</strong>: This category includes games that
+ make the user think and includes puzzles, matching games, and similar
+ games.
+ </li>
+
+ <li><strong>Creativity</strong>: These are apps/games that spur creativity.
+ Example types of apps/games we expect in this category include drawing,
+ painting, and other games where you can build things.
+ </li>
+
+ <li><strong>Education</strong>: These are apps/games that have educational value and include
+ math, science, learning the alphabet, learning to count, and many more types of
+ educational content like geography and history.
+ </li>
+
+ <li><strong>Music and Video</strong>: These are apps/games that contain a musical element or
+ video component and include everything from playing the
+ piano to watching videos and more.
+ </li>
+
+ <li><strong>Pretend Play</strong>: These are apps/games where one can pretend to take on a
+ role, like pretending to be a cook or a doctor.
+ </li>
+</ul>
+
+<dl>
+ <dt>
+ Will it take longer for my app to get published if I opt-in to the Designed
+ for Families program?
+ </dt>
+
+ <dd>
+ When you opt-in to Designed for Families, Google Play reviews your app to
+ confirm that it is appropriate for families. Assuming your app complies with all program
+ requirements, we expect that publishing time should not take any longer
+ than normal; however, there may be a delay in publishing the app if it is
+ rejected during the Designed for Families review.
+ </dd>
+
+ <dt>
+ What happens if my app is rejected from the Designed for Families program?
+ </dt>
+
+ <dd>
+ If your app is rejected from the Designed for Families program, we’ll
+ indicate why in the Developer Console and in a detailed email. You’ll have
+ an opportunity to correct the issues and resubmit your app to the program,
+ or change your opt-in response. Note that if you have an existing app that
+ is live on Google Play, only your app update will be rejected (your app
+ will remain live on the Play store). If you’ve submitted a new app to the
+ Designed for Families program that does not meet the requirements, your
+ entire app submission will be rejected and the app will not be published on
+ Play. You can then address the identified issue(s) and resubmit the app for
+ the Designed for Families program or opt-out of the program.
+ </dd>
+
+ <dt>
+ What happens if my app is found to be non-compliant with Designed for
+ Families program requirements after it has been published?
+ </dt>
+
+ <dd>
+ Your app may be removed or suspended from the Google Play Store, not only
+ the Designed for Families program. Removed apps can follow the same
+ remedies as rejected apps. Suspended apps can be appealed using the
+ developer appeal process.
+ </dd>
+
+ <dt>
+ If I opt-in to the Designed for Families program, can I opt-out later on?
+ </dt>
+
+ <dd>
+ Yes, you may opt-out of the program at any time. Please note that by opting
+ out you would lose your placement in the new family-friendly experience as
+ well as the other benefits of the program.
+ </dd>
+
+ <dt>
+ What happens when I update my app after it has been accepted into the
+ program?
+ </dt>
+
+ <dd>
+ Apps that are part of the Designed for Families program need to maintain
+ compliance with the eligibility requirements at all times. If you need to
+ edit the Designed for Families metadata associated with your app, please go
+ to the Pricing & Distribution section of the Google Play Developer Console
+ to edit this information. If updating your app results in you changing your
+ target audience, we recommend that you alert the users who already
+ have your app installed.
+ </dd>
+
+ <dt>
+ Can apps and games that use Google sign-in or Google Play Game
+ services opt-into the Designed for Families program?
+ </dt>
+
+ <dd>
+ Apps that participate in Designed for Families that are wholly
+ child-focused, i.e. that target the following age groups: Ages 5 & Under,
+ Ages 6 to 8, or Ages 9 to 12 <strong>may not</strong> use Google+ Sign-in
+ or Google Play Game services as the login experience for their
+ application.
+
+ <p>
+ Apps that participate in Designed for Families that target both children and
+ older audiences, can use Google+ Sign-in or Google Play Game services as an
+ <strong>optional</strong> feature. Child users must be able to access the app
+ or game in its entirety without signing into Google+ or Google Play Game services.
+ </p>
+ </dd>
+
+ <dt>
+ My app is opted-in to Google Play for Education and has Google sign-in integration
+ so that students can login with their school accounts. Do I need to change the way
+ Google sign-in works in my app?
+ </dt>
+
+ <dd>
+ Apps that participate in Google Play for Education may use Google sign-in for
+ student accounts as long as it is not a blocking requirement for all users of the app.
+ </dd>
+</dl>
+
+<h2 id="monetization">
+ Designed for Families Program Monetization
+</h2>
+
+<dl>
+ <dt>
+ Can you give me more details on the advertising policies for Designed for
+ Families?
+ </dt>
+
+ <dd>
+ Read the <a href=
+ "https://support.google.com/googleplay/android-developer/answer/6184502#ads">
+ ads policy for Designed for Families</a>.
+ </dd>
+
+ <dt>
+ Can my app serve interstitial advertisements?
+ </dt>
+
+ <dd>
+ Interstitial ads may be appropriate for some apps. However, a user must be
+ able to navigate to the main activity before any ads are served.
+ </dd>
+
+ <dt>
+ How do I know that my ad network complies with the advertising
+ policies for Designed for Families?
+ </dt>
+
+ <dd>
+ Please contact your advertising network to ask them about their content policies
+ and advertising practices. If you use AdMob, then please refer to the <a href=
+ "https://support.google.com/admob/answer/3248194">AdMob help center</a> for
+ details on how to tag your app or a specific ad unit for child-directed
+ treatment. It is the developer’s responsibility to ensure that the overall
+ user experience with in-app advertising meets the <a href=
+ "https://support.google.com/googleplay/android-developer/answer/6184502">Designed
+ for Families program requirements</a>.
+ </dd>
+
+ <dt>
+ Can I have in-app purchases in my app?
+ </dt>
+
+ <dd>
+ There are no specific restrictions relating to in-app purchases (IAP) in
+ apps participating in the Designed for Families program other than
+ compliance with the <a href=
+ "https://play.google.com/intl/ALL_us/about/families/developer-distribution-agreement-addendum.html">
+ Designed for Families DDA</a> and other applicable legal requirements, but
+ Play reserves the right to reject apps for overly aggressive commercial
+ tactics. Google Play will enforce IAP password protection on all apps
+ participating in the Designed for Families program that primarily target
+ child audiences to ensure that parents, not children, are approving
+ purchases. Please note that this treatment does not extend to apps
+ targeting general audiences.
+ </dd>
+</dl>
+
+<h2 id="other">
+ Other Questions
+</h2>
+
+<dl>
+ <dt>
+ Who is the intended target audience for participating Designed for Families
+ apps?
+ </dt>
+
+ <dd>
+ Our goal is to provide a great experience on the Google Play store for
+ parents and guardians to discover delightful apps designed for kids and
+ families from trusted brands and developers.
+ </dd>
+
+ <dt>
+ Is the Designed for Families Program only available to developers in
+ certain countries?
+ </dt>
+
+ <dd>
+ Designed for Families is a global program.
+ </dd>
+
+ <dt>
+ What happens to apps that are published in the current Family Games
+ category?
+ </dt>
+
+ <dd>
+ The current Family Games category will be deprecated in May 2015. Apps
+ currently in the Family Games category will have to select
+ a different category in the Play store. Apps that have not selected another
+ category will be assigned to the Casual Games category.
+ </dd>
+</dl>
+
+<div class="paging-links" style="padding-top:.75em;">
+ <a href="https://docs.google.com/forms/d/1EtvUWqlkxS6RxHJjeI-3-7uzdbIZx6n9Cocy2D369B8/viewform" class=
+ "next-class-link">Next: Stay in Touch</a>
+</div> \ No newline at end of file
diff --git a/docs/html/distribute/googleplay/families/start.jd b/docs/html/distribute/googleplay/families/start.jd
new file mode 100644
index 0000000..af4eb3a
--- /dev/null
+++ b/docs/html/distribute/googleplay/families/start.jd
@@ -0,0 +1,114 @@
+page.title=Opt-In to Designed for Families
+meta.tags="families", "guidelines", "quality"
+page.tags="families", "addendum"
+page.metaDescription=Join Designed for Families in just a few simple steps.
+
+@jd:body
+
+<p>
+ If you're building an app designed for kids and families, there are a few
+ things you need to do <em>before</em> you’ll be ready to opt-in to the Designed for
+ Families program:
+</p>
+
+<ul>
+ <li>Complete the content rating questionnaire for your app and meet an ESRB
+ rating of Everyone or Everyone 10+ rating
+ </li>
+
+ <li>Add a privacy policy link to your app’s <strong>Store Listing</strong>
+ page.
+ </li>
+
+ <li>Make sure your app meets all the <a href=
+ "https://support.google.com/googleplay/android-developer/answer/6184502">Designed
+ for Families program requirements.</a>
+ </li>
+</ul>
+
+<p>
+ Now that your app is ready to publish, you can opt-in to Designed for
+ Families directly from the <a href=
+ "https://play.google.com/apps/publish/">Developer Console</a>. Opt-in means
+ that you want your app to be made available on the new family-friendly
+ experience on Google Play in addition to the category you’ve selected on
+ the Google Play Store.
+</p>
+
+<p>
+ Opt-in also confirms that your app complies with <a href=
+ "http://play.google.com/about/developer-content-policy.html">Google Play
+ Developer Program Policies</a> and the <a href=
+ "http://play.google.com/about/developer-distribution-agreement.html">Developer
+ Distribution Agreement</a>, including the <a href=
+ "https://play.google.com/intl/ALL_us/about/families/developer-distribution-agreement-addendum.html">
+ Designed for Families DDA Addendum</a>. If you are not familiar with these
+ policy documents or the Addendum, make sure to read them before opting-in.
+</p>
+
+<p>
+ Once you're ready, here's how to opt-in to Designed for Families for a specific app:
+</p>
+
+<ol>
+<li>In the Developer Console <strong>All Applications</strong> page, click the app you want to
+ opt-in. Under Pricing and Distribution, scroll down to find <strong>Designed for
+ Families</strong> and the opt-in checkbox.<img src="/images/gp-dff-optin.png" style=
+ "border:2px solid #ddd;margin:1em 0;">
+ </li>
+
+ <li>Start the opt-in flow and confirm that your app meets the eligibility
+ requirements.</li>
+ <li>If your app has ads, confirm that it meets the ads policy.
+ <img src="/images/gp-dff-appinfo.png"
+ style="border:2px solid #ddd;margin:1em 0;"></li>
+ <li>Choose your target age groups from: Ages 5 & Under, Ages 6 to 8, Ages 9
+ to 12, or General Audience (for apps which target children and older
+ audiences). If your app targets more than one age group, you can choose up to
+ two adjacent age groups. Apps with an ESRB 10+ rating can only choose an
+ age target of 9-12 or General Audience.
+ </li>
+
+ <li>Choose a category for your app for the new family-focused experience on
+ Google Play. Your app will also be discoverable in its existing category in
+ Google Play.</li>
+ <li>Review and agree to the linked documents and then click
+ <strong>Opt-In</strong>. Finally, click <strong>Submit update</strong> on the
+ Pricing & Distribution page to publish or update your app.
+ </li>
+</ol>
+
+<p>
+ Once you opt-in your app, it will be thoroughly reviewed before being
+ accepted into the Designed for Families program.
+</p>
+
+<p class="note">
+ <strong>Note</strong>: Published apps in the Designed for Families program
+ are also available to all users on Google Play.
+</p>
+
+<p>
+ If you opt-in an app that you're publishing for the first time and it doesn't
+ meet the Designed for Families program requirements, it won't be made available
+ on Google Play until <strong>either</strong> you update the app to meet the
+ program requirements <strong>or</strong> you uncheck the opt-in box and pass
+ Google Play's standard review process.
+</p>
+
+<p>
+ If you opt-in an app that's already published on Google Play and it doesn't
+ meet the program requirements, it will remain available to all users but won't
+ be added to the new family experience until you update the app to meet the
+ program requirements.
+</p>
+
+<p>
+ If you publish an update to an app that's opted-in to Designed for Families,
+ the app update needs to pass the Designed for Families review before it will
+ become available to all users on Google Play.</p>
+
+<div class="paging-links" style="padding-top:.75em;">
+ <a href="{@docRoot}distribute/googleplay/families/faq.html" class=
+ "next-class-link">Next: Frequently Asked Questions</a>
+</div>
diff --git a/docs/html/distribute/googleplay/googleplay_toc.cs b/docs/html/distribute/googleplay/googleplay_toc.cs
index 594d6d6..78a3731 100644
--- a/docs/html/distribute/googleplay/googleplay_toc.cs
+++ b/docs/html/distribute/googleplay/googleplay_toc.cs
@@ -24,8 +24,8 @@
</div>
</li>
<li class="nav-section">
- <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/auto.html">
- <span class="en">Distributing to <span style="white-space:nowrap">Android Auto</span></span>
+ <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/wear.html">
+ <span class="en">Distributing to <span style="white-space:nowrap">Android Wear</span></span>
</a>
</div>
</li>
@@ -36,10 +36,27 @@
</div>
</li>
<li class="nav-section">
- <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/wear.html">
- <span class="en">Distributing to <span style="white-space:nowrap">Android Wear</span></span>
+ <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/auto.html">
+ <span class="en">Distributing to <span style="white-space:nowrap">Android Auto</span></span>
+ </a>
+ </div>
+ </li>
+ <li class="nav-section">
+ <div class="nav-section-header" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/families/about.html">
+ <span class="en">Designed for Families</span>
</a>
</div>
+ <ul>
+ <li><a href="<?cs var:toroot?>distribute/googleplay/families/start.html">
+ <span class="en">Opt-In</span>
+ </a></li>
+ <li><a href="<?cs var:toroot?>distribute/googleplay/families/faq.html">
+ <span class="en">FAQ</span>
+ </a></li>
+ <li><a href="https://docs.google.com/forms/d/1EtvUWqlkxS6RxHJjeI-3-7uzdbIZx6n9Cocy2D369B8/viewform">
+ <span class="en">Stay in Touch »</span>
+ </a></li>
+ </ul>
</li>
<li class="nav-section">
<div class="nav-section-header" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/edu/about.html">
@@ -56,7 +73,6 @@
</ul>
</li>
</ul>
-
<script type="text/javascript">
<!--
buildToggleLists();
diff --git a/docs/html/distribute/googleplay/index.jd b/docs/html/distribute/googleplay/index.jd
index 20f07fa..b25f6b7 100644
--- a/docs/html/distribute/googleplay/index.jd
+++ b/docs/html/distribute/googleplay/index.jd
@@ -26,7 +26,7 @@ nonavpage=true
<div class="resource-widget resource-flow-layout landing col-16"
data-query="collection:distribute/gp/gpfelanding"
data-cardSizes="6x6"
- data-maxResults="3">
+ data-maxResults="5">
</div>
<h3>Related resources</h3>
diff --git a/docs/html/distribute/images/about-dff-sm.jpg b/docs/html/distribute/images/about-dff-sm.jpg
new file mode 100644
index 0000000..10cc5fa
--- /dev/null
+++ b/docs/html/distribute/images/about-dff-sm.jpg
Binary files differ
diff --git a/docs/html/images/gp-dff-appinfo.png b/docs/html/images/gp-dff-appinfo.png
new file mode 100644
index 0000000..30f58b8
--- /dev/null
+++ b/docs/html/images/gp-dff-appinfo.png
Binary files differ
diff --git a/docs/html/images/gp-dff-optin.png b/docs/html/images/gp-dff-optin.png
new file mode 100644
index 0000000..9f97d2d
--- /dev/null
+++ b/docs/html/images/gp-dff-optin.png
Binary files differ
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 05a8a3e..99b9dd1 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -87,7 +87,8 @@ var RESOURCE_COLLECTIONS = {
"distribute/googleplay/auto.html",
"distribute/googleplay/tv.html",
"distribute/googleplay/wear.html",
- "distribute/googleplay/edu/about.html"
+ "distribute/googleplay/edu/about.html",
+ "distribute/googleplay/families/about.html"
]
},
"distribute/essentials": {
diff --git a/docs/html/tools/debugging/debugging-memory.jd b/docs/html/tools/debugging/debugging-memory.jd
index ae67b3c..5893ad1 100644
--- a/docs/html/tools/debugging/debugging-memory.jd
+++ b/docs/html/tools/debugging/debugging-memory.jd
@@ -24,63 +24,72 @@ page.tags=memory,OutOfMemoryError
<p>Because Android is designed for mobile devices, you should always be careful about how much
-random-access memory (RAM) your app uses. Although Android’s Dalvik virtual machine performs
-routine garbage collection, this doesn’t mean you can ignore when and where your app allocates and
+random-access memory (RAM) your application uses. Although Dalvik and ART perform
+routine garbage collection (GC), this doesn’t mean you can ignore when and where your application allocates and
releases memory. In order to provide a stable user experience that allows the system to quickly
-switch between apps, it’s important that your app does not needlessly consume memory when the user
+switch between apps, it is important that your application does not needlessly consume memory when the user
is not interacting with it.</p>
<p>Even if you follow all the best practices for <a href="{@docRoot}training/articles/memory.html"
>Managing Your App Memory</a> during
development (which you should), you still might leak objects or introduce other memory bugs. The
-only way to be certain your app is using as little memory as possible is to analyze your app’s
+only way to be certain your application is using as little memory as possible is to analyze your app’s
memory usage with tools. This guide shows you how to do that.</p>
<h2 id="LogMessages">Interpreting Log Messages</h2>
-<p>The simplest place to begin investigating your apps memory usage is the Dalvik log messages. You'll
-find these log messages in <a href="{@docRoot}tools/help/logcat.html">logcat</a> (the output is
-available in the Device Monitor or directly in IDEs such as Eclipse and Android Studio).</p>
+<p>The simplest place to begin investigating your application’s memory usage is the runtime log messages.
+Sometimes when a GC occurs, a message is printed to
+<a href="{@docRoot}tools/help/logcat.html">logcat</a>. The logcat output is also available in the
+Device Monitor or directly in IDEs such as Eclipse and Android Studio.</p>
-<p>Every time a garbage collection occurs, logcat prints a message with the following information:</p>
+<h3 id="DalvikLogMessages">Dalvik Log Messages</h3>
+
+<p>In Dalvik (but not ART), every GC prints the following information to logcat:</p>
<pre class="no-pretty-print">
D/dalvikvm: &lt;GC_Reason> &lt;Amount_freed>, &lt;Heap_stats>, &lt;External_memory_stats>, &lt;Pause_time>
</pre>
+<p>Example:</p>
+
+<pre class="no-pretty-print">
+D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
+</pre>
+
<dl>
<dt>GC Reason</dt>
<dd>
-What triggered the garbage collection and what kind of collection it is. Reasons that may appear
+What triggered the GC and what kind of collection it is. Reasons that may appear
include:
<dl>
<dt><code>GC_CONCURRENT</code></dt>
-<dd>A concurrent garbage collection that frees up memory as your heap begins to fill up.</dd>
+<dd>A concurrent GC that frees up memory as your heap begins to fill up.</dd>
<dt><code>GC_FOR_MALLOC</code></dt>
-<dd>A garbage collection caused because your app attempted to allocate memory when your heap was
-already full, so the system had to stop your app and reclaim memory.</dd>
+<dd>A GC caused because your application attempted to allocate memory when your heap was
+already full, so the system had to stop your application and reclaim memory.</dd>
<dt><code>GC_HPROF_DUMP_HEAP</code></dt>
-<dd>A garbage collection that occurs when you create an HPROF file to analyze your heap.</dd>
+<dd>A GC that occurs when you request to create an HPROF file to analyze your heap.</dd>
<dt><code>GC_EXPLICIT</code>
-<dd>An explicit garbage collection, such as when you call {@link java.lang.System#gc()} (which you
-should avoid calling and instead trust the garbage collector to run when needed).</dd>
+<dd>An explicit GC, such as when you call {@link java.lang.System#gc()} (which you
+should avoid calling and instead trust the GC to run when needed).</dd>
<dt><code>GC_EXTERNAL_ALLOC</code></dt>
<dd>This happens only on API level 10 and lower (newer versions allocate everything in the Dalvik
-heap). A garbage collection for externally allocated memory (such as the pixel data stored in
+heap). A GC for externally allocated memory (such as the pixel data stored in
native memory or NIO byte buffers).</dd>
</dl>
</dd>
<dt>Amount freed</dt>
-<dd>The amount of memory reclaimed from this garbage collection.</dd>
+<dd>The amount of memory reclaimed from this GC.</dd>
<dt>Heap stats</dt>
-<dd>Percentage free and (number of live objects)/(total heap size).</dd>
+<dd>Percentage free of the heap and (number of live objects)/(total heap size).</dd>
<dt>External memory stats</dt>
<dd>Externally allocated memory on API level 10 and lower (amount of allocated memory) / (limit at
@@ -91,20 +100,141 @@ which collection will occur).</dd>
beginning of the collection and another near the end.</dd>
</dl>
-<p>For example:</p>
+<p>As these log messages accumulate, look out for increases in the heap stats (the
+{@code 3571K/9991K} value in the above example). If this value continues to increase, you may have
+a memory leak.</p>
+
+
+<h3 id="ARTLogMessages">ART Log Messages</h3>
+
+<p>Unlike Dalvik, ART doesn't log messqages for GCs that were not explicity requested. GCs are only
+printed when they are they are deemed slow. More precisely, if the GC pause exceeds than 5ms or
+the GC duration exceeds 100ms. If the application is not in a pause perceptible process state,
+then none of its GCs are deemed slow. Explicit GCs are always logged.</p>
+
+<p>ART includes the following information in its garbage collection log messages:</p>
<pre class="no-pretty-print">
-D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
+I/art: &lt;GC_Reason> &lt;GC_Name> &lt;Objects_freed>(&lt;Size_freed>) AllocSpace Objects, &lt;Large_objects_freed>(&lt;Large_object_size_freed>) &lt;Heap_stats> LOS objects, &lt;Pause_time(s)>
+</pre>
+
+<p>Example:</p>
+
+<pre class="no-pretty-print">
+I/art : Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects, 21(416KB) LOS objects, 33% free, 25MB/38MB, paused 1.230ms total 67.216ms
</pre>
-<p>As these log messages stack up, look out for increases in the heap stats (the
-{@code 3571K/9991K} value in the above example). If this value
-continues to increase and doesn't ever seem to get smaller, you could have a memory leak.</p>
+<dl>
+<dt>GC Reason</dt>
+<dd>
+What triggered the GC and what kind of collection it is. Reasons that may appear
+include:
+<dl>
+<dt><code>Concurrent</code></dt>
+<dd>A concurrent GC which does not suspend application threads. This GC runs in a background thread
+and does not prevent allocations.</dd>
+
+<dt><code>Alloc</code></dt>
+<dd>The GC was initiated because your application attempted to allocate memory when your heap
+was already full. In this case, the garbage collection occurred in the allocating thread.</dd>
+
+<dt><code>Explicit</code>
+<dd>The garbage collection was explicitly requested by an application, for instance, by
+calling {@link java.lang.System#gc()} or {@link java.lang.Runtime#gc()}. As with Dalvik, in ART it is
+recommended that you trust the GC and avoid requesting explicit GCs if possible. Explicit GCs are
+discouraged since they block the allocating thread and unnecessarily was CPU cycles. Explicit GCs
+could also cause jank if they cause other threads to get preempted.</dd>
+
+<dt><code>NativeAlloc</code></dt>
+<dd>The collection was caused by native memory pressure from native allocations such as Bitmaps or
+RenderScript allocation objects.</dd>
+
+<dt><code>CollectorTransition</code></dt>
+<dd>The collection was caused by a heap transition; this is caused by switching the GC at run time.
+Collector transitions consist of copying all the objects from a free-list backed
+space to a bump pointer space (or visa versa). Currently collector transitions only occur when an
+application changes process states from a pause perceptible state to a non pause perceptible state
+(or visa versa) on low RAM devices.
+</dd>
+
+<dt><code>HomogeneousSpaceCompact</code></dt>
+<dd>Homogeneous space compaction is free-list space to free-list space compaction which usually
+occurs when an application is moved to a pause imperceptible process state. The main reasons for doing
+this are reducing RAM usage and defragmenting the heap.
+</dd>
+
+<dt><code>DisableMovingGc</code></dt>
+<dd>This is not a real GC reason, but a note that collection was blocked due to use of
+GetPrimitiveArrayCritical. while concurrent heap compaction is occuring. In general, the use of
+GetPrimitiveArrayCritical is strongly discouraged due to its restrictions on moving collectors.
+</dd>
+
+<dt><code>HeapTrim</code></dt>
+<dd>This is not a GC reason, but a note that collection was blocked until a heap trim finished.
+</dd>
+
+</dl>
+</dd>
+
+
+<dl>
+<dt>GC Name</dt>
+<dd>
+ART has various different GCs which can get run.
+<dl>
+<dt><code>Concurrent mark sweep (CMS)</code></dt>
+<dd>A whole heap collector which frees collects all spaces other than the image space.</dd>
+
+<dt><code>Concurrent partial mark sweep</code></dt>
+<dd>A mostly whole heap collector which collects all spaces other than the image and zygote spaces.
+</dd>
+
+<dt><code>Concurrent sticky mark sweep</code></dt>
+<dd>A generational collector which can only free objects allocated since the last GC. This garbage
+collection is run more often than a full or partial mark sweep since it is faster and has lower pauses.
+</dd>
+
+<dt><code>Marksweep + semispace</code></dt>
+<dd>A non concurrent, copying GC used for heap transitions as well as homogeneous space
+compaction (to defragement the heap).</dd>
+
+</dl>
+</dd>
+
+<dt>Objects freed</dt>
+<dd>The number of objects which were reclaimed from this GC from the non large
+object space.</dd>
+
+<dt>Size freed</dt>
+<dd>The number of bytes which were reclaimed from this GC from the non large object
+space.</dd>
+
+<dt>Large objects freed</dt>
+<dd>The number of object in the large object space which were reclaimed from this garbage
+collection.</dd>
+
+<dt>Large object size freed</dt>
+<dd>The number of bytes in the large object space which were reclaimed from this garbage
+collection.</dd>
+
+<dt>Heap stats</dt>
+<dd>Percentage free and (number of live objects)/(total heap size).</dd>
+<dt>Pause times</dt>
+<dd>In general pause times are proportional to the number of object references which were modified
+while the GC was running. Currently, the ART CMS GCs only has one pause, near the end of the GC.
+The moving GCs have a long pause which lasts for the majority of the GC duration.</dd>
+</dl>
+
+<p>If you are seeing a large amount of GCs in logcat, look for increases in the heap stats (the
+{@code 25MB/38MB} value in the above example). If this value continues to increase and doesn't
+ever seem to get smaller, you could have a memory leak. Alternatively, if you are seeing GC which
+are for the reason "Alloc", then you are already operating near your heap capacity and can expect
+OOM exceptios in the near future. </p>
<h2 id="ViewHeap">Viewing Heap Updates</h2>
-<p>To get a little information about what kind of memory your app is using and when, you can view
+<p>To get a little information about what kind of memory your application is using and when, you can view
real-time updates to your app's heap in the Device Monitor:</p>
<ol>
@@ -117,15 +247,15 @@ real-time updates to your app's heap in the Device Monitor:</p>
</ol>
<p>The Heap view shows some basic stats about your heap memory usage, updated after every
-garbage collection. To see the first update, click the <strong>Cause GC</strong> button.</p>
+GC. To see the first update, click the <strong>Cause GC</strong> button.</p>
<img src="{@docRoot}images/tools/monitor-vmheap@2x.png" width="760" alt="" />
<p class="img-caption"><strong>Figure 1.</strong> The Device Monitor tool,
showing the <strong>[1] Update Heap</strong> and <strong>[2] Cause GC</strong> buttons.
The Heap tab on the right shows the heap results.</p>
-<p>Continue interacting with your app to watch your heap allocation update with each garbage
-collection. This can help you identify which actions in your app are likely causing too much
+<p>Continue interacting with your application to watch your heap allocation update with each garbage
+collection. This can help you identify which actions in your application are likely causing too much
allocation and where you should try to reduce allocations and release
resources.</p>
@@ -136,9 +266,9 @@ resources.</p>
<p>As you start narrowing down memory issues, you should also use the Allocation Tracker to
get a better understanding of where your memory-hogging objects are allocated. The Allocation
Tracker can be useful not only for looking at specific uses of memory, but also to analyze critical
-code paths in an app such as scrolling.</p>
+code paths in an application such as scrolling.</p>
-<p>For example, tracking allocations when flinging a list in your app allows you to see all the
+<p>For example, tracking allocations when flinging a list in your application allows you to see all the
allocations that need to be done for that behavior, what thread they are on, and where they came
from. This is extremely valuable for tightening up these paths to reduce the work they need and
improve the overall smoothness of the UI.</p>
@@ -151,7 +281,7 @@ improve the overall smoothness of the UI.</p>
<li>In the DDMS window, select your app's process in the left-side panel.</li>
<li>In the right-side panel, select the <strong>Allocation Tracker</strong> tab.</li>
<li>Click <strong>Start Tracking</strong>.</li>
-<li>Interact with your app to execute the code paths you want to analyze.</li>
+<li>Interact with your application to execute the code paths you want to analyze.</li>
<li>Click <strong>Get Allocations</strong> every time you want to update the
list of allocations.</li>
</ol>
@@ -163,7 +293,7 @@ thread, in which class, in which file and at which line.</p>
<img src="{@docRoot}images/tools/monitor-tracker@2x.png" width="760" alt="" />
<p class="img-caption"><strong>Figure 2.</strong> The Device Monitor tool,
-showing recent app allocations and stack traces in the Allocation Tracker.</p>
+showing recent application allocations and stack traces in the Allocation Tracker.</p>
<p class="note"><strong>Note:</strong> You will always see some allocations from {@code
@@ -186,9 +316,11 @@ divided between different types of RAM allocation with the
following <a href="{@docRoot}tools/help/adb.html">adb</a> command:</p>
<pre class="no-pretty-print">
-adb shell dumpsys meminfo &lt;package_name>
+adb shell dumpsys meminfo &lt;package_name|pid> [-d]
</pre>
+<p>The -d flag prints more info related to Dalvik and ART memory usage.</p>
+
<p>The output lists all of your app's current allocations, measured in kilobytes.</p>
<p>When inspecting this information, you should be familiar with the
@@ -218,13 +350,57 @@ actual RAM weight of a process and for comparison against the RAM use of other p
total available RAM.</p>
-<p>For example, below is the the output for Gmail’s process on a tablet device. There is a lot of
+<p>For example, below is the the output for Map’s process on a Nexus 5 device. There is a lot of
information here, but key points for discussion are listed below.</p>
+<code>adb shell dumpsys meminfo com.google.android.apps.maps -d</code>
<p class="note"><strong>Note:</strong> The information you see may vary slightly from what is shown
here, as some details of the output differ across platform versions.</p>
<pre class="no-pretty-print">
+** MEMINFO in pid 18227 [com.google.android.apps.maps] **
+ Pss Private Private Swapped Heap Heap Heap
+ Total Dirty Clean Dirty Size Alloc Free
+ ------ ------ ------ ------ ------ ------ ------
+ Native Heap 10468 10408 0 0 20480 14462 6017
+ Dalvik Heap 34340 33816 0 0 62436 53883 8553
+ Dalvik Other 972 972 0 0
+ Stack 1144 1144 0 0
+ Gfx dev 35300 35300 0 0
+ Other dev 5 0 4 0
+ .so mmap 1943 504 188 0
+ .apk mmap 598 0 136 0
+ .ttf mmap 134 0 68 0
+ .dex mmap 3908 0 3904 0
+ .oat mmap 1344 0 56 0
+ .art mmap 2037 1784 28 0
+ Other mmap 30 4 0 0
+ EGL mtrack 73072 73072 0 0
+ GL mtrack 51044 51044 0 0
+ Unknown 185 184 0 0
+ TOTAL 216524 208232 4384 0 82916 68345 14570
+
+ Dalvik Details
+ .Heap 6568 6568 0 0
+ .LOS 24771 24404 0 0
+ .GC 500 500 0 0
+ .JITCache 428 428 0 0
+ .Zygote 1093 936 0 0
+ .NonMoving 1908 1908 0 0
+ .IndirectRef 44 44 0 0
+
+ Objects
+ Views: 90 ViewRootImpl: 1
+ AppContexts: 4 Activities: 1
+ Assets: 2 AssetManagers: 2
+ Local Binders: 21 Proxy Binders: 28
+ Parcel memory: 18 Parcel count: 74
+ Death Recipients: 2 OpenSSL Sockets: 2
+</pre>
+
+<p>Here is an older dumpsys on Dalvik of the gmail app:</p>
+
+<pre class="no-pretty-print">
** MEMINFO in pid 9953 [com.google.android.gm] **
Pss Pss Shared Private Shared Private Heap Heap Heap
Total Clean Dirty Dirty Clean Clean Size Alloc Free
@@ -272,7 +448,7 @@ app’s process from Zygote.
<p class="note"><strong>Note:</strong> On newer platform versions that have the <code>Dalvik
Other</code> section, the <code>Pss Total</code> and <code>Private Dirty</code> numbers for Dalvik Heap do
-not include Dalvik overhead such as the just-in-time compilation (JIT) and garbage collection (GC)
+not include Dalvik overhead such as the just-in-time compilation (JIT) and GC
bookkeeping, whereas older versions list it all combined under <code>Dalvik</code>.</p>
<p>The <code>Heap Alloc</code> is the amount of memory that the Dalvik and native heap allocators keep
@@ -282,12 +458,62 @@ with all the others.</p>
</dd>
<dt><code>.so mmap</code> and <code>.dex mmap</code></dt>
-<dd>The RAM being used for mmapped <code>.so</code> (native) and <code>.dex</code> (Dalvik) code. The
-<code>Pss Total</code> number includes platform code shared across apps; the <code>Private Clean</code> is
-your app’s own code. Generally, the actual mapped size will be much larger—the RAM here is only
-what currently needs to be in RAM for code that has been executed by the app. However, the .so mmap
-has a large private dirty, which is due to fix-ups to the native code when it was loaded into its
-final address.
+<dd>The RAM being used for mmapped <code>.so</code> (native) and <code>.dex</code> (Dalvik or ART)
+code. The <code>Pss Total</code> number includes platform code shared across apps; the
+<code>Private Clean</code> is your app’s own code. Generally, the actual mapped size will be much
+larger—the RAM here is only what currently needs to be in RAM for code that has been executed by
+the app. However, the .so mmap has a large private dirty, which is due to fix-ups to the native
+code when it was loaded into its final address.
+</dd>
+
+<dt><code>.oat mmap</code></dt>
+<dd>This is the amount of RAM used by the code image which is based off of the preloaded classes
+which are commonly used by multiple apps. This image is shared across all apps and is unaffected
+by particular apps.
+</dd>
+
+<dt><code>.art mmap</code></dt>
+<dd>This is the amount of RAM used by the heap image which is based off of the preloaded classes
+which are commonly used by multiple apps. This image is shared across all apps and is unaffected
+by particular apps. Even though the ART image contains {@link java.lang.Object} instances, it does not
+count towards your heap size.
+</dd>
+
+<dt><code>.Heap</code> (only with -d flag)</dt>
+<dd>This is the amount of heap memory for your app. This excludes objects in the image and large
+object spaces, but includes the zygote space and non-moving space.
+</dd>
+
+<dt><code>.LOS</code> (only with -d flag)</dt>
+<dd>This is the amount of RAM used by the ART large object space. This includes zygote large
+objects. Large objects are all primitive array allocations larger than 12KB.
+</dd>
+
+<dt><code>.GC</code> (only with -d flag)</dt>
+<dd>This is the amount of internal GC accounting overhead for your app. There is not really any way
+to reduce this overhead.
+</dd>
+
+<dt><code>.JITCache</code> (only with -d flag)</dt>
+<dd>This is the amount of memory used by the JIT data and code caches. Typically, this is zero
+since all of the apps will be compiled at installed time.
+</dd>
+
+<dt><code>.Zygote</code> (only with -d flag)</dt>
+<dd>This is the amount of memory used by the zygote space. The zygote space is created during
+device startup and is never allocated into.
+</dd>
+
+<dt><code>.NonMoving</code> (only with -d flag)</dt>
+<dd>This is the amount of RAM used by the ART non-moving space. The non-moving space contains
+special non-movable objects such as fields and methods. You can reduce this section by using fewer
+fields and methods in your app.
+</dd>
+
+<dt><code>.IndirectRef</code> (only with -d flag)</dt>
+<dd>This is the amount of RAM used by the ART indirect reference tables. Usually this amount is
+small, but if it is too high, it may be possible to reduce it by reducing the number of local and
+global JNI references used.
</dd>
<dt><code>Unknown</code></dt>
@@ -318,7 +544,7 @@ window, so this can help you identify memory leaks involving dialogs or other wi
</dd>
<dt><code>AppContexts</code> and <code>Activities</code></dt>
-<dd>The number of app {@link android.content.Context} and {@link android.app.Activity} objects that
+<dd>The number of application {@link android.content.Context} and {@link android.app.Activity} objects that
currently live in your process. This can be useful to quickly identify leaked {@link
android.app.Activity} objects that can’t be garbage collected due to static references on them,
which is common. These objects often have a lot of other allocations associated with them and so
@@ -327,7 +553,7 @@ are a good way to track large memory leaks.</dd>
<p class="note"><strong>Note:</strong> A {@link android.view.View} or {@link
android.graphics.drawable.Drawable} object also holds a reference to the {@link
android.app.Activity} that it's from, so holding a {@link android.view.View} or {@link
-android.graphics.drawable.Drawable} object can also lead to your app leaking an {@link
+android.graphics.drawable.Drawable} object can also lead to your application leaking an {@link
android.app.Activity}.</p>
</dd>
@@ -363,13 +589,13 @@ then click <strong>Save</strong>.</li>
showing the <strong>[1] Dump HPROF file</strong> button.</p>
<p>If you need to be more precise about when the dump is created, you can also create a heap dump
-at the critical point in your app code by calling {@link android.os.Debug#dumpHprofData
+at the critical point in your application code by calling {@link android.os.Debug#dumpHprofData
dumpHprofData()}.</p>
<p>The heap dump is provided in a format that's similar to, but not identical to one from the Java
HPROF tool. The major difference in an Android heap dump is due to the fact that there are a large
number of allocations in the Zygote process. But because the Zygote allocations are shared across
-all app processes, they don’t matter very much to your own heap analysis.</p>
+all application processes, they don’t matter very much to your own heap analysis.</p>
<p>To analyze your heap dump, you can use a standard tool like jhat or the <a href=
"http://www.eclipse.org/mat/downloads.php">Eclipse Memory Analyzer Tool</a> (MAT). However, first
@@ -434,7 +660,7 @@ showing what your largest objects are. Below this chart, are links to couple of
<p class="note"><strong>Note:</strong> Most apps will show an instance of
{@link android.content.res.Resources} near the top with a good chunk of heap, but this is
- usually expected when your app uses lots of resources from your {@code res/} directory.</p>
+ usually expected when your application uses lots of resources from your {@code res/} directory.</p>
</li>
</ul>
@@ -473,19 +699,19 @@ to inspect the changes in memory allocation. To compare two heap dumps using MAT
<h2 id="TriggerLeaks">Triggering Memory Leaks</h2>
-<p>While using the tools described above, you should aggressively stress your app code and try
-forcing memory leaks. One way to provoke memory leaks in your app is to let it
+<p>While using the tools described above, you should aggressively stress your application code and try
+forcing memory leaks. One way to provoke memory leaks in your application is to let it
run for a while before inspecting the heap. Leaks will trickle up to the top of the allocations in
-the heap. However, the smaller the leak, the longer you need to run the app in order to see it.</p>
+the heap. However, the smaller the leak, the longer you need to run the application in order to see it.</p>
<p>You can also trigger a memory leak in one of the following ways:</p>
<ol>
<li>Rotate the device from portrait to landscape and back again multiple times while in different
-activity states. Rotating the device can often cause an app to leak an {@link android.app.Activity},
+activity states. Rotating the device can often cause an application to leak an {@link android.app.Activity},
{@link android.content.Context}, or {@link android.view.View} object because the system
-recreates the {@link android.app.Activity} and if your app holds a reference
+recreates the {@link android.app.Activity} and if your application holds a reference
to one of those objects somewhere else, the system can't garbage collect it.</li>
-<li>Switch between your app and another app while in different activity states (navigate to
+<li>Switch between your application and another application while in different activity states (navigate to
the Home screen, then return to your app).</li>
</ol>
diff --git a/docs/html/tools/extras/oem-usb.jd b/docs/html/tools/extras/oem-usb.jd
index b25b41e..6d449ee 100644
--- a/docs/html/tools/extras/oem-usb.jd
+++ b/docs/html/tools/extras/oem-usb.jd
@@ -32,12 +32,13 @@ not exhaustive for all available Android-powered devices.</p>
To start developing with your device, read <a
href="{@docRoot}tools/device.html">Using Hardware Devices</a>.</p>
-<p class="note"><strong>Note:</strong> If your device is one of the Android Developer Phones
-(ADP), a Nexus One, or a Nexus S, then you need
-the <a href="{@docRoot}sdk/win-usb.html">Google USB Driver</a>, instead of an OEM driver. The Galaxy
-Nexus driver, however, is distributed by <a
-href="http://www.samsung.com/us/support/downloads/verizon-wireless/SCH-I515MSAVZW">Samsung</a>
-(listed as model SCH-I515).</p>
+<p>The Google USB Driver is <strong>required for Windows only</strong> in order to perform
+<a href="{@docRoot}tools/help/adb.html">adb</a> debugging with any of
+the <strong>Google Nexus devices</strong>. The one exception is the
+Galaxy Nexus: the driver for Galaxy Nexus is distributed by <a
+href="http://www.samsung.com/us/support/owners/product/GT-I9250TSGGEN">Samsung</a>
+(listed as model GT-I9250TSGGEN).</p>
+
<h2 id="InstallingDriver">Installing a USB Driver</h2>
@@ -99,7 +100,7 @@ driver:</p>
<li>Select <strong>Device Manager</strong> in the left pane of the Computer Management
window.</li>
<li>Locate and expand <em>Android Phone</em> in the right pane.</li>
- <li>Right-click <em>Android Composite ADB Interface</em> and select <strong>Update
+ <li>Right-click on <em>Android Composite ADB Interface</em> and select <strong>Update
Driver</strong>.
This will launch the Hardware Update Wizard.</li>
<li>Select <strong>Install from a list or specific location</strong> and click
@@ -145,14 +146,14 @@ driver:</p>
and select <strong>Manage</strong>.</li>
<li>Select <strong>Device Manager</strong> in the left pane.</li>
<li>Locate and expand <em>ADB Interface</em> in the right pane.</li>
- <li>Right-click on <em>HTC Dream Composite ADB Interface</em>, and select <strong>Update
+ <li>Right-click on <em>Android Composite ADB Interface</em>, and select <strong>Update
Driver Software</strong>.</li>
<li>When Vista starts updating the driver, a prompt will ask how you want to
search for the driver
software. Select <strong>Browse my computer for driver software</strong>.</li>
<li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
Driver is located in {@code &lt;sdk&gt;\extras\google\usb_driver\}.) As long as you specified the
-exact location of the
+exact location of the
installation package, you may leave <strong>Include subfolders</strong> checked or
unchecked&mdash;it doesn't matter.</li>
<li>Click <strong>Next</strong>. Vista might prompt you to confirm the privilege elevation
@@ -164,13 +165,6 @@ exact location of the
<h2 id="Drivers">OEM Drivers</h2>
-<p class="note"><strong>Note:</strong> If your device is one of the Android Developer Phones
-(purchased from the Google Play Developer Console), a Nexus One, or a Nexus S, then you need
-the <a href="{@docRoot}sdk/win-usb.html">Google USB Driver</a>, instead of an OEM driver. The Galaxy
-Nexus driver, however, is distributed by <a
-href="http://www.samsung.com/us/support/downloads/verizon-wireless/SCH-I515MSAVZW">Samsung</a>
-(listed as model SCH-I515).</p>
-
<table><tr>
<th>OEM</th>
diff --git a/docs/html/tools/help/adb.jd b/docs/html/tools/help/adb.jd
index e2dd196..41c6686 100644
--- a/docs/html/tools/help/adb.jd
+++ b/docs/html/tools/help/adb.jd
@@ -962,7 +962,6 @@ install [options] &lt;PATH>
</code></td>
<td>Installs a package (specified by {@code &lt;PATH>}) to the system. <p>Options:
<ul>
- <li>{@code -l}: Install the package with forward lock.
<li>{@code -r}: Reinstall an exisiting app, keeping its data.
<li>{@code -t}: Allow test APKs to be installed.
<li>{@code -i &lt;INSTALLER_PACKAGE_NAME>}: Specify the installer package name.
diff --git a/docs/html/tools/help/systrace.jd b/docs/html/tools/help/systrace.jd
index d6fc05e..4461da9 100644
--- a/docs/html/tools/help/systrace.jd
+++ b/docs/html/tools/help/systrace.jd
@@ -68,7 +68,8 @@ or the Android <a href="{@docRoot}tools/help/monitor.html">Device Monitor</a>.
<ol>
<li>In <a href="{@docRoot}sdk/installing/studio.html">Android Studio</a>, open an
Android application project.</li>
- <li>Open the Device Monitor by selecting <strong>Tools &gt; Android &gt; Monitor</strong>.</li>
+ <li>Open the Device Monitor by selecting <strong>Tools &gt; Android &gt; Android Device
+ Monitor</strong>.</li>
<li>In the <strong>Devices</strong> tab, select the device on which to run a trace. If no
devices are listed, make sure your device is connected via USB cable and that debugging is
enabled on the device.</li>
diff --git a/docs/html/training/articles/keystore.jd b/docs/html/training/articles/keystore.jd
index bbbda67..a4fc2d2 100644
--- a/docs/html/training/articles/keystore.jd
+++ b/docs/html/training/articles/keystore.jd
@@ -26,11 +26,10 @@ page.title=Android Keystore System
</div>
</div>
-<p>The Android Keystore system lets you store private keys
- in a container to make it more difficult to extract from the
- device. Once keys are in the keystore, they can be used for
- cryptographic operations with the private key material remaining
- non-exportable.</p>
+<p>The Android Keystore system lets you store cryptographic keys in a container
+ to make it more difficult to extract from the device. Once keys are in the
+ keystore, they can be used for cryptographic operations with the key material
+ remaining non-exportable.</p>
<p>The Keystore system is used by the {@link
android.security.KeyChain} API as well as the Android
@@ -59,7 +58,8 @@ Android Keystore Provider</h2>
<p>
To use this feature, you use the standard {@link java.security.KeyStore}
-and {@link java.security.KeyPairGenerator} classes along with the
+and {@link java.security.KeyPairGenerator} or
+{@link javax.crypto.KeyGenerator} classes along with the
{@code AndroidKeyStore} provider introduced in Android 4.3 (API level 18).</p>
<p>{@code AndroidKeyStore} is registered as a {@link
@@ -67,7 +67,9 @@ and {@link java.security.KeyPairGenerator} classes along with the
java.security.KeyStore#getInstance(String) KeyStore.getInstance(type)}
method and as a provider for use with the {@link
java.security.KeyPairGenerator#getInstance(String, String)
- KeyPairGenerator.getInstance(algorithm, provider)} method.</p>
+ KeyPairGenerator.getInstance(algorithm, provider)} and {@link
+ javax.crypto.KeyGenerator#getInstance(String, String)
+ KeyGenerator.getInstance(algorithm, provider)} methods.</p>
<h3 id="GeneratingANewPrivateKey">Generating a New Private Key</h3>
@@ -81,6 +83,11 @@ and {@link java.security.KeyPairGenerator} classes along with the
{@sample development/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java generate}
+<h3 id="GeneratingANewSecretKey">Generating a New Secret Key</h3>
+
+<p>To generate the key, use a {@link javax.crypto.KeyGenerator} with
+ {@link android.security.KeyGeneratorSpec}.
+
<h3 id="WorkingWithKeyStoreEntries">Working with Keystore Entries</h3>
<p>Using the {@code AndroidKeyStore} provider takes place through
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 05a81de..8468d9e 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -297,7 +297,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
}
final Drawable d = layer.mDrawable;
- if (d.canApplyTheme()) {
+ if (d != null && d.canApplyTheme()) {
d.applyTheme(t);
// Update cached mask of child changing configurations.
@@ -881,7 +881,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.draw(canvas);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.draw(canvas);
+ }
}
}
@@ -946,13 +949,15 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
*/
@Override
public void getOutline(@NonNull Outline outline) {
- final LayerState state = mLayerState;
- final ChildDrawable[] children = state.mChildren;
- final int N = state.mNum;
+ final ChildDrawable[] array = mLayerState.mChildren;
+ final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- children[i].mDrawable.getOutline(outline);
- if (!outline.isEmpty()) {
- return;
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.getOutline(outline);
+ if (!outline.isEmpty()) {
+ return;
+ }
}
}
}
@@ -962,7 +967,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setHotspot(x, y);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setHotspot(x, y);
+ }
}
}
@@ -971,7 +979,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setHotspotBounds(left, top, right, bottom);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setHotspotBounds(left, top, right, bottom);
+ }
}
if (mHotspotBounds == null) {
@@ -996,7 +1007,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setVisible(visible, restart);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setVisible(visible, restart);
+ }
}
return changed;
@@ -1007,17 +1021,18 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setDither(dither);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setDither(dither);
+ }
}
}
@Override
public boolean getDither() {
- final ChildDrawable[] array = mLayerState.mChildren;
- if (mLayerState.mNum > 0) {
- // All layers should have the same dither set on them - just return
- // the first one
- return array[0].mDrawable.getDither();
+ final Drawable dr = getFirstNonNullDrawable();
+ if (dr != null) {
+ return dr.getDither();
} else {
return super.getDither();
}
@@ -1028,17 +1043,18 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setAlpha(alpha);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setAlpha(alpha);
+ }
}
}
@Override
public int getAlpha() {
- final ChildDrawable[] array = mLayerState.mChildren;
- if (mLayerState.mNum > 0) {
- // All layers should have the same alpha set on them - just return
- // the first one
- return array[0].mDrawable.getAlpha();
+ final Drawable dr = getFirstNonNullDrawable();
+ if (dr != null) {
+ return dr.getAlpha();
} else {
return super.getAlpha();
}
@@ -1049,7 +1065,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setColorFilter(colorFilter);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setColorFilter(colorFilter);
+ }
}
}
@@ -1058,7 +1077,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setTintList(tint);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setTintList(tint);
+ }
}
}
@@ -1067,8 +1089,23 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setTintMode(tintMode);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setTintMode(tintMode);
+ }
+ }
+ }
+
+ private Drawable getFirstNonNullDrawable() {
+ final ChildDrawable[] array = mLayerState.mChildren;
+ final int N = mLayerState.mNum;
+ for (int i = 0; i < N; i++) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ return dr;
+ }
}
+ return null;
}
/**
@@ -1101,7 +1138,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.setAutoMirrored(mirrored);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.setAutoMirrored(mirrored);
+ }
}
}
@@ -1122,9 +1162,9 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- final ChildDrawable r = array[i];
- if (r.mDrawable.isStateful() && r.mDrawable.setState(state)) {
- refreshChildPadding(i, r);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.isStateful() && dr.setState(state)) {
+ refreshChildPadding(i, array[i]);
changed = true;
}
}
@@ -1143,9 +1183,9 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- final ChildDrawable r = array[i];
- if (r.mDrawable.setLevel(level)) {
- refreshChildPadding(i, r);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.setLevel(level)) {
+ refreshChildPadding(i, array[i]);
changed = true;
}
}
@@ -1176,6 +1216,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
for (int i = 0; i < N; i++) {
final ChildDrawable r = array[i];
final Drawable d = r.mDrawable;
+ if (d == null) {
+ continue;
+ }
+
final Rect container = mTmpContainer;
container.set(d.getBounds());
@@ -1257,6 +1301,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
final ChildDrawable r = array[i];
+ if (r.mDrawable == null) {
+ continue;
+ }
+
final int minWidth = r.mWidth < 0 ? r.mDrawable.getIntrinsicWidth() : r.mWidth;
final int w = minWidth + r.mInsetL + r.mInsetR + padL + padR;
if (w > width) {
@@ -1283,6 +1331,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
final ChildDrawable r = array[i];
+ if (r.mDrawable == null) {
+ continue;
+ }
+
final int minHeight = r.mHeight < 0 ? r.mDrawable.getIntrinsicHeight() : r.mHeight;
final int h = minHeight + r.mInsetT + r.mInsetB + padT + padB;
if (h > height) {
@@ -1304,15 +1356,17 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
* @return true if the child's padding has changed
*/
private boolean refreshChildPadding(int i, ChildDrawable r) {
- final Rect rect = mTmpRect;
- r.mDrawable.getPadding(rect);
- if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i] ||
- rect.right != mPaddingR[i] || rect.bottom != mPaddingB[i]) {
- mPaddingL[i] = rect.left;
- mPaddingT[i] = rect.top;
- mPaddingR[i] = rect.right;
- mPaddingB[i] = rect.bottom;
- return true;
+ if (r.mDrawable != null) {
+ final Rect rect = mTmpRect;
+ r.mDrawable.getPadding(rect);
+ if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i] ||
+ rect.right != mPaddingR[i] || rect.bottom != mPaddingB[i]) {
+ mPaddingL[i] = rect.left;
+ mPaddingT[i] = rect.top;
+ mPaddingR[i] = rect.right;
+ mPaddingB[i] = rect.bottom;
+ return true;
+ }
}
return false;
}
@@ -1348,7 +1402,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.mutate();
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.mutate();
+ }
}
mMutated = true;
}
@@ -1360,10 +1417,14 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
*/
public void clearMutated() {
super.clearMutated();
+
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- array[i].mDrawable.clearMutated();
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ dr.clearMutated();
+ }
}
mMutated = false;
}
@@ -1371,11 +1432,16 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
@Override
public boolean onLayoutDirectionChange(int layoutDirection) {
boolean changed = false;
+
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
- changed |= array[i].mDrawable.setLayoutDirection(layoutDirection);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ changed |= dr.setLayoutDirection(layoutDirection);
+ }
}
+
updateLayerBounds(getBounds());
return changed;
}
@@ -1396,15 +1462,24 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
}
ChildDrawable(ChildDrawable orig, LayerDrawable owner, Resources res) {
- if (res != null) {
- mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
+ final Drawable dr = orig.mDrawable;
+ final Drawable clone;
+ if (dr != null) {
+ final ConstantState cs = dr.getConstantState();
+ if (res != null) {
+ clone = cs.newDrawable(res);
+ } else {
+ clone = cs.newDrawable();
+ }
+ clone.setCallback(owner);
+ clone.setLayoutDirection(dr.getLayoutDirection());
+ clone.setBounds(dr.getBounds());
+ clone.setLevel(dr.getLevel());
} else {
- mDrawable = orig.mDrawable.getConstantState().newDrawable();
+ clone = null;
}
- mDrawable.setCallback(owner);
- mDrawable.setLayoutDirection(orig.mDrawable.getLayoutDirection());
- mDrawable.setBounds(orig.mDrawable.getBounds());
- mDrawable.setLevel(orig.mDrawable.getLevel());
+
+ mDrawable = clone;
mThemeAttrs = orig.mThemeAttrs;
mInsetL = orig.mInsetL;
mInsetT = orig.mInsetT;
@@ -1417,6 +1492,11 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
mGravity = orig.mGravity;
mId = orig.mId;
}
+
+ public boolean canApplyTheme() {
+ return mThemeAttrs != null
+ || (mDrawable != null && mDrawable.canApplyTheme());
+ }
}
static class LayerState extends ConstantState {
@@ -1476,7 +1556,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final int N = mNum;
for (int i = 0; i < N; i++) {
final ChildDrawable layer = array[i];
- if (layer.mThemeAttrs != null || layer.mDrawable.canApplyTheme()) {
+ if (layer.canApplyTheme()) {
return true;
}
}
@@ -1507,9 +1587,29 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mChildren;
final int N = mNum;
- int op = N > 0 ? array[0].mDrawable.getOpacity() : PixelFormat.TRANSPARENT;
- for (int i = 1; i < N; i++) {
- op = Drawable.resolveOpacity(op, array[i].mDrawable.getOpacity());
+
+ // Seek to the first non-null drawable.
+ int firstIndex = -1;
+ for (int i = 0; i < N; i++) {
+ if (array[i].mDrawable != null) {
+ firstIndex = i;
+ break;
+ }
+ }
+
+ int op;
+ if (firstIndex >= 0) {
+ op = array[firstIndex].mDrawable.getOpacity();
+ } else {
+ op = PixelFormat.TRANSPARENT;
+ }
+
+ // Merge all remaining non-null drawables.
+ for (int i = firstIndex + 1; i < N; i++) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ op = Drawable.resolveOpacity(op, dr.getOpacity());
+ }
}
mOpacity = op;
@@ -1526,7 +1626,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final int N = mNum;
boolean isStateful = false;
for (int i = 0; i < N; i++) {
- if (array[i].mDrawable.isStateful()) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.isStateful()) {
isStateful = true;
break;
}
@@ -1541,7 +1642,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final ChildDrawable[] array = mChildren;
final int N = mNum;
for (int i = 0; i < N; i++) {
- if (array[i].mDrawable.getConstantState() == null) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.getConstantState() == null) {
return false;
}
}
@@ -1561,9 +1663,12 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
final int N = mNum;
int pixelCount = 0;
for (int i = 0; i < N; i++) {
- final ConstantState state = array[i].mDrawable.getConstantState();
- if (state != null) {
- pixelCount += state.addAtlasableBitmaps(atlasList);
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null) {
+ final ConstantState state = dr.getConstantState();
+ if (state != null) {
+ pixelCount += state.addAtlasableBitmaps(atlasList);
+ }
}
}
return pixelCount;
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index b32dcc6..feb8052 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -380,7 +380,7 @@ public final class PdfRenderer implements AutoCloseable {
final long transformPtr = (transform != null) ? transform.native_instance : 0;
- nativeRenderPage(mNativeDocument, mNativePage, destination.getSkBitmap(), contentLeft,
+ nativeRenderPage(mNativeDocument, mNativePage, destination, contentLeft,
contentTop, contentRight, contentBottom, transformPtr, renderMode);
}
@@ -425,7 +425,7 @@ public final class PdfRenderer implements AutoCloseable {
private static native void nativeClose(long documentPtr);
private static native int nativeGetPageCount(long documentPtr);
private static native boolean nativeScaleForPrinting(long documentPtr);
- private static native void nativeRenderPage(long documentPtr, long pagePtr, long destPtr,
+ private static native void nativeRenderPage(long documentPtr, long pagePtr, Bitmap dest,
int destLeft, int destTop, int destRight, int destBottom, long matrixPtr, int renderMode);
private static native long nativeOpenPageAndGetSize(long documentPtr, int pageIndex,
Point outSize);
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
index c5b6a68..b931774 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -19,6 +19,8 @@ package android.security;
import com.android.org.conscrypt.OpenSSLEngine;
import com.android.org.conscrypt.OpenSSLKeyHolder;
+import libcore.util.EmptyArray;
+
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
@@ -46,6 +48,7 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@@ -112,13 +115,6 @@ public class AndroidKeyStore extends KeyStoreSpi {
if (keymasterAlgorithm == -1) {
throw new UnrecoverableKeyException("Key algorithm unknown");
}
- @KeyStoreKeyConstraints.AlgorithmEnum int keyAlgorithm;
- try {
- keyAlgorithm = KeyStoreKeyConstraints.Algorithm.fromKeymaster(keymasterAlgorithm);
- } catch (IllegalArgumentException e) {
- throw (UnrecoverableKeyException)
- new UnrecoverableKeyException("Unsupported key algorithm").initCause(e);
- }
int keymasterDigest =
keyCharacteristics.hwEnforced.getInt(KeymasterDefs.KM_TAG_DIGEST, -1);
@@ -126,20 +122,11 @@ public class AndroidKeyStore extends KeyStoreSpi {
keymasterDigest =
keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_DIGEST, -1);
}
- @KeyStoreKeyConstraints.DigestEnum Integer digest = null;
- if (keymasterDigest != -1) {
- try {
- digest = KeyStoreKeyConstraints.Digest.fromKeymaster(keymasterDigest);
- } catch (IllegalArgumentException e) {
- throw (UnrecoverableKeyException)
- new UnrecoverableKeyException("Unsupported digest").initCause(e);
- }
- }
String keyAlgorithmString;
try {
- keyAlgorithmString = KeyStoreKeyConstraints.Algorithm.toJCASecretKeyAlgorithm(
- keyAlgorithm, digest);
+ keyAlgorithmString = KeymasterUtils.getJcaSecretKeyAlgorithm(
+ keymasterAlgorithm, keymasterDigest);
} catch (IllegalArgumentException e) {
throw (UnrecoverableKeyException)
new UnrecoverableKeyException("Unsupported secret key type").initCause(e);
@@ -456,90 +443,92 @@ public class AndroidKeyStore extends KeyStoreSpi {
}
String keyAlgorithmString = key.getAlgorithm();
- @KeyStoreKeyConstraints.AlgorithmEnum int keyAlgorithm;
- @KeyStoreKeyConstraints.DigestEnum Integer digest;
+ int keymasterAlgorithm;
+ int keymasterDigest;
try {
- keyAlgorithm =
- KeyStoreKeyConstraints.Algorithm.fromJCASecretKeyAlgorithm(keyAlgorithmString);
- digest = KeyStoreKeyConstraints.Digest.fromJCASecretKeyAlgorithm(keyAlgorithmString);
+ keymasterAlgorithm = KeymasterUtils.getKeymasterAlgorithmFromJcaSecretKeyAlgorithm(
+ keyAlgorithmString);
+ keymasterDigest =
+ KeymasterUtils.getKeymasterDigestfromJcaSecretKeyAlgorithm(keyAlgorithmString);
} catch (IllegalArgumentException e) {
throw new KeyStoreException("Unsupported secret key algorithm: " + keyAlgorithmString);
}
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM,
- KeyStoreKeyConstraints.Algorithm.toKeymaster(keyAlgorithm));
+ args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm);
- @KeyStoreKeyConstraints.DigestEnum int digests;
+ int[] keymasterDigests;
if (params.isDigestsSpecified()) {
// Digest(s) specified in parameters
- if (digest != null) {
+ keymasterDigests =
+ KeymasterUtils.getKeymasterDigestsFromJcaDigestAlgorithms(params.getDigests());
+ if (keymasterDigest != -1) {
// Digest also specified in the JCA key algorithm name.
- if ((params.getDigests() & digest) != digest) {
+ if (!com.android.internal.util.ArrayUtils.contains(
+ keymasterDigests, keymasterDigest)) {
throw new KeyStoreException("Key digest mismatch"
+ ". Key: " + keyAlgorithmString
- + ", parameter spec: "
- + KeyStoreKeyConstraints.Digest.allToString(params.getDigests()));
+ + ", parameter spec: " + Arrays.asList(params.getDigests()));
}
}
- digests = params.getDigests();
} else {
// No digest specified in parameters
- if (digest != null) {
+ if (keymasterDigest != -1) {
// Digest specified in the JCA key algorithm name.
- digests = digest;
+ keymasterDigests = new int[] {keymasterDigest};
} else {
- digests = 0;
+ keymasterDigests = EmptyArray.INT;
}
}
- for (int keymasterDigest : KeyStoreKeyConstraints.Digest.allToKeymaster(digests)) {
- args.addInt(KeymasterDefs.KM_TAG_DIGEST, keymasterDigest);
- }
- if (digests != 0) {
+ args.addInts(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests);
+ if (keymasterDigests.length > 0) {
// TODO: Remove MAC length constraint once Keymaster API no longer requires it.
// This code will blow up if mode than one digest is specified.
- Integer digestOutputSizeBytes =
- KeyStoreKeyConstraints.Digest.getOutputSizeBytes(digest);
- if (digestOutputSizeBytes != null) {
+ int digestOutputSizeBytes =
+ KeymasterUtils.getDigestOutputSizeBytes(keymasterDigests[0]);
+ if (digestOutputSizeBytes != -1) {
// TODO: Switch to bits instead of bytes, once this is fixed in Keymaster
args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, digestOutputSizeBytes);
}
}
- if (keyAlgorithm == KeyStoreKeyConstraints.Algorithm.HMAC) {
- if (digests == 0) {
+ if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
+ if (keymasterDigests.length == 0) {
throw new KeyStoreException("At least one digest algorithm must be specified"
+ " for key algorithm " + keyAlgorithmString);
}
}
- @KeyStoreKeyConstraints.PurposeEnum int purposes = params.getPurposes();
- @KeyStoreKeyConstraints.BlockModeEnum int blockModes = params.getBlockModes();
- if (((purposes & KeyStoreKeyConstraints.Purpose.ENCRYPT) != 0)
+ @KeyStoreKeyProperties.PurposeEnum int purposes = params.getPurposes();
+ int[] keymasterBlockModes = KeymasterUtils.getKeymasterBlockModesFromJcaBlockModes(
+ params.getBlockModes());
+ if (((purposes & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
&& (params.isRandomizedEncryptionRequired())) {
- @KeyStoreKeyConstraints.BlockModeEnum int incompatibleBlockModes =
- blockModes & ~KeyStoreKeyConstraints.BlockMode.IND_CPA_COMPATIBLE_MODES;
- if (incompatibleBlockModes != 0) {
- throw new KeyStoreException("Randomized encryption (IND-CPA) required but may be"
- + " violated by block mode(s): "
- + KeyStoreKeyConstraints.BlockMode.allToString(incompatibleBlockModes)
- + ". See KeyStoreParameter documentation.");
+ for (int keymasterBlockMode : keymasterBlockModes) {
+ if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatible(keymasterBlockMode)) {
+ throw new KeyStoreException(
+ "Randomized encryption (IND-CPA) required but may be violated by block"
+ + " mode: "
+ + KeymasterUtils.getJcaBlockModeFromKeymasterBlockMode(
+ keymasterBlockMode)
+ + ". See KeyStoreParameter documentation.");
+ }
}
}
- for (int keymasterPurpose : KeyStoreKeyConstraints.Purpose.allToKeymaster(purposes)) {
+ for (int keymasterPurpose : KeyStoreKeyProperties.Purpose.allToKeymaster(purposes)) {
args.addInt(KeymasterDefs.KM_TAG_PURPOSE, keymasterPurpose);
}
- for (int keymasterBlockMode : KeyStoreKeyConstraints.BlockMode.allToKeymaster(blockModes)) {
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockMode);
- }
- for (int keymasterPadding :
- KeyStoreKeyConstraints.Padding.allToKeymaster(params.getPaddings())) {
- args.addInt(KeymasterDefs.KM_TAG_PADDING, keymasterPadding);
- }
+ args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
+ int[] keymasterPaddings = ArrayUtils.concat(
+ KeymasterUtils.getKeymasterPaddingsFromJcaEncryptionPaddings(
+ params.getEncryptionPaddings()),
+ KeymasterUtils.getKeymasterPaddingsFromJcaSignaturePaddings(
+ params.getSignaturePaddings()));
+ args.addInts(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
if (params.getUserAuthenticators() == 0) {
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
} else {
args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
- KeyStoreKeyConstraints.UserAuthenticator.allToKeymaster(
+ KeyStoreKeyProperties.UserAuthenticator.allToKeymaster(
params.getUserAuthenticators()));
}
if (params.isInvalidatedOnNewFingerprintEnrolled()) {
@@ -563,7 +552,7 @@ public class AndroidKeyStore extends KeyStoreSpi {
// TODO: Remove this once keymaster does not require us to specify the size of imported key.
args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, keyMaterial.length * 8);
- if (((purposes & KeyStoreKeyConstraints.Purpose.ENCRYPT) != 0)
+ if (((purposes & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
&& (!params.isRandomizedEncryptionRequired())) {
// Permit caller-provided IV when encrypting with this key
args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
diff --git a/keystore/java/android/security/ArrayUtils.java b/keystore/java/android/security/ArrayUtils.java
new file mode 100644
index 0000000..2047d3f
--- /dev/null
+++ b/keystore/java/android/security/ArrayUtils.java
@@ -0,0 +1,62 @@
+package android.security;
+
+import libcore.util.EmptyArray;
+
+/**
+ * @hide
+ */
+abstract class ArrayUtils {
+ private ArrayUtils() {}
+
+ public static String[] nullToEmpty(String[] array) {
+ return (array != null) ? array : EmptyArray.STRING;
+ }
+
+ public static String[] cloneIfNotEmpty(String[] array) {
+ return ((array != null) && (array.length > 0)) ? array.clone() : array;
+ }
+
+ public static byte[] concat(byte[] arr1, byte[] arr2) {
+ return concat(arr1, 0, (arr1 != null) ? arr1.length : 0,
+ arr2, 0, (arr2 != null) ? arr2.length : 0);
+ }
+
+ public static byte[] concat(byte[] arr1, int offset1, int len1, byte[] arr2, int offset2,
+ int len2) {
+ if (len1 == 0) {
+ return subarray(arr2, offset2, len2);
+ } else if (len2 == 0) {
+ return subarray(arr1, offset1, len1);
+ } else {
+ byte[] result = new byte[len1 + len2];
+ System.arraycopy(arr1, offset1, result, 0, len1);
+ System.arraycopy(arr2, offset2, result, len1, len2);
+ return result;
+ }
+ }
+
+ public static byte[] subarray(byte[] arr, int offset, int len) {
+ if (len == 0) {
+ return EmptyArray.BYTE;
+ }
+ if ((offset == 0) && (len == arr.length)) {
+ return arr;
+ }
+ byte[] result = new byte[len];
+ System.arraycopy(arr, offset, result, 0, len);
+ return result;
+ }
+
+ public static int[] concat(int[] arr1, int[] arr2) {
+ if ((arr1 == null) || (arr1.length == 0)) {
+ return arr2;
+ } else if ((arr2 == null) || (arr2.length == 0)) {
+ return arr1;
+ } else {
+ int[] result = new int[arr1.length + arr2.length];
+ System.arraycopy(arr1, 0, result, 0, arr1.length);
+ System.arraycopy(arr2, 0, result, arr1.length, arr2.length);
+ return result;
+ }
+ }
+}
diff --git a/keystore/java/android/security/CryptoOperationException.java b/keystore/java/android/security/CryptoOperationException.java
index 00c142f..1c9d005 100644
--- a/keystore/java/android/security/CryptoOperationException.java
+++ b/keystore/java/android/security/CryptoOperationException.java
@@ -25,8 +25,6 @@ package android.security;
* permitted to throw a checked exception during operation. Because crypto operations can fail
* for a variety of reasons after initialization, this base class provides type-safety for unchecked
* exceptions that may be thrown in those cases.
- *
- * @hide
*/
public class CryptoOperationException extends RuntimeException {
diff --git a/keystore/java/android/security/EcIesParameterSpec.java b/keystore/java/android/security/EcIesParameterSpec.java
index 0f19812..3826679 100644
--- a/keystore/java/android/security/EcIesParameterSpec.java
+++ b/keystore/java/android/security/EcIesParameterSpec.java
@@ -46,8 +46,6 @@ import javax.crypto.Mac;
* MAC algorithm specified by {@link #getDemMacAlgorithm()} (e.g., {@code HmacSHA1} for standard
* DEM1).</li>
* </ul>
- *
- * @hide
*/
public class EcIesParameterSpec implements AlgorithmParameterSpec {
@@ -124,6 +122,8 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
/**
* Returns KEM EC curve name (e.g., {@code secp256r1}) or {@code null} if not specified.
+ *
+ * @hide
*/
public String getKemCurveName() {
return mKemCurveName;
@@ -200,6 +200,8 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
* Sets KEM EC curve name. For example, {@code P-256} or {@code secp256r1}.
*
* <p>NOTE: Only curves with cofactor of {@code 1} are supported.
+ *
+ * @hide
*/
public Builder setKemCurveName(String name) {
mKemCurveName = name;
diff --git a/keystore/java/android/security/KeyExpiredException.java b/keystore/java/android/security/KeyExpiredException.java
index 35a5acc..a02dc33 100644
--- a/keystore/java/android/security/KeyExpiredException.java
+++ b/keystore/java/android/security/KeyExpiredException.java
@@ -19,8 +19,6 @@ package android.security;
/**
* Indicates that a cryptographic operation failed because the employed key's validity end date
* is in the past.
- *
- * @hide
*/
public class KeyExpiredException extends CryptoOperationException {
diff --git a/keystore/java/android/security/KeyGeneratorSpec.java b/keystore/java/android/security/KeyGeneratorSpec.java
index 4eedb24..7ecc47e 100644
--- a/keystore/java/android/security/KeyGeneratorSpec.java
+++ b/keystore/java/android/security/KeyGeneratorSpec.java
@@ -37,23 +37,21 @@ import javax.crypto.SecretKey;
* <p>After generation, the {@code keyStoreAlias} is used with the
* {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
* interface to retrieve the {@link SecretKey}.
- *
- * @hide
*/
public class KeyGeneratorSpec implements AlgorithmParameterSpec {
private final Context mContext;
private final String mKeystoreAlias;
private final int mFlags;
- private final Integer mKeySize;
+ private final int mKeySize;
private final Date mKeyValidityStart;
private final Date mKeyValidityForOriginationEnd;
private final Date mKeyValidityForConsumptionEnd;
- private final @KeyStoreKeyConstraints.PurposeEnum int mPurposes;
- private final @KeyStoreKeyConstraints.PaddingEnum int mPaddings;
- private final @KeyStoreKeyConstraints.BlockModeEnum int mBlockModes;
+ private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
+ private final String[] mEncryptionPaddings;
+ private final String[] mBlockModes;
private final boolean mRandomizedEncryptionRequired;
- private final @KeyStoreKeyConstraints.UserAuthenticatorEnum int mUserAuthenticators;
+ private final @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
private final int mUserAuthenticationValidityDurationSeconds;
private final boolean mInvalidatedOnNewFingerprintEnrolled;
@@ -61,15 +59,15 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
Context context,
String keyStoreAlias,
int flags,
- Integer keySize,
+ int keySize,
Date keyValidityStart,
Date keyValidityForOriginationEnd,
Date keyValidityForConsumptionEnd,
- @KeyStoreKeyConstraints.PurposeEnum int purposes,
- @KeyStoreKeyConstraints.PaddingEnum int paddings,
- @KeyStoreKeyConstraints.BlockModeEnum int blockModes,
+ @KeyStoreKeyProperties.PurposeEnum int purposes,
+ String[] encryptionPaddings,
+ String[] blockModes,
boolean randomizedEncryptionRequired,
- @KeyStoreKeyConstraints.UserAuthenticatorEnum int userAuthenticators,
+ @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators,
int userAuthenticationValidityDurationSeconds,
boolean invalidatedOnNewFingerprintEnrolled) {
if (context == null) {
@@ -90,8 +88,9 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
mPurposes = purposes;
- mPaddings = paddings;
- mBlockModes = blockModes;
+ mEncryptionPaddings =
+ ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
+ mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
mRandomizedEncryptionRequired = randomizedEncryptionRequired;
mUserAuthenticators = userAuthenticators;
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
@@ -121,9 +120,9 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
}
/**
- * Gets the requested key size or {@code null} if the default size should be used.
+ * Returns the requested key size or {@code -1} if default size should be used.
*/
- public Integer getKeySize() {
+ public int getKeySize() {
return mKeySize;
}
@@ -157,22 +156,22 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
/**
* Gets the set of purposes for which the key can be used.
*/
- public @KeyStoreKeyConstraints.PurposeEnum int getPurposes() {
+ public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
return mPurposes;
}
/**
- * Gets the set of padding schemes to which the key is restricted.
+ * Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
*/
- public @KeyStoreKeyConstraints.PaddingEnum int getPaddings() {
- return mPaddings;
+ public String[] getEncryptionPaddings() {
+ return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
}
/**
- * Gets the set of block modes to which the key is restricted.
+ * Gets the set of block modes with which the key can be used.
*/
- public @KeyStoreKeyConstraints.BlockModeEnum int getBlockModes() {
- return mBlockModes;
+ public String[] getBlockModes() {
+ return ArrayUtils.cloneIfNotEmpty(mBlockModes);
}
/**
@@ -194,7 +193,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* @return user authenticators or {@code 0} if the key can be used without user authentication.
*/
- public @KeyStoreKeyConstraints.UserAuthenticatorEnum int getUserAuthenticators() {
+ public @KeyStoreKeyProperties.UserAuthenticatorEnum int getUserAuthenticators() {
return mUserAuthenticators;
}
@@ -215,8 +214,6 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
* authenticators protecting access to this key.
*
* @see #getUserAuthenticators()
- *
- * @hide
*/
public boolean isInvalidatedOnNewFingerprintEnrolled() {
return mInvalidatedOnNewFingerprintEnrolled;
@@ -233,15 +230,15 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
private final Context mContext;
private String mKeystoreAlias;
private int mFlags;
- private Integer mKeySize;
+ private int mKeySize = -1;
private Date mKeyValidityStart;
private Date mKeyValidityForOriginationEnd;
private Date mKeyValidityForConsumptionEnd;
- private @KeyStoreKeyConstraints.PurposeEnum int mPurposes;
- private @KeyStoreKeyConstraints.PaddingEnum int mPaddings;
- private @KeyStoreKeyConstraints.BlockModeEnum int mBlockModes;
+ private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
+ private String[] mEncryptionPaddings;
+ private String[] mBlockModes;
private boolean mRandomizedEncryptionRequired = true;
- private @KeyStoreKeyConstraints.UserAuthenticatorEnum int mUserAuthenticators;
+ private @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
private int mUserAuthenticationValidityDurationSeconds = -1;
private boolean mInvalidatedOnNewFingerprintEnrolled;
@@ -349,34 +346,35 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
}
/**
- * Restricts the key to being used only for the provided set of purposes.
+ * Sets the set of purposes for which the key can be used.
*
- * <p>This restriction must be specified. There is no default.
+ * <p>This must be specified for all keys. There is no default.
*/
- public Builder setPurposes(@KeyStoreKeyConstraints.PurposeEnum int purposes) {
+ public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) {
mPurposes = purposes;
return this;
}
/**
- * Restricts the key to being used only with the provided padding schemes. Attempts to use
- * the key with any other padding will be rejected.
+ * Sets the set of padding schemes with which the key can be used when
+ * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
+ * rejected.
*
- * <p>This restriction must be specified for keys which are used for encryption/decryption.
+ * <p>This must be specified for keys which are used for encryption/decryption.
*/
- public Builder setPaddings(@KeyStoreKeyConstraints.PaddingEnum int paddings) {
- mPaddings = paddings;
+ public Builder setEncryptionPaddings(String... paddings) {
+ mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
return this;
}
/**
- * Restricts the key to being used only with the provided block modes. Attempts to use the
- * key with any other block modes will be rejected.
+ * Sets the set of block modes with which the key can be used when encrypting/decrypting.
+ * Attempts to use the key with any other block modes will be rejected.
*
- * <p>This restriction must be specified for keys which are used for encryption/decryption.
+ * <p>This must be specified for encryption/decryption keys.
*/
- public Builder setBlockModes(@KeyStoreKeyConstraints.BlockModeEnum int blockModes) {
- mBlockModes = blockModes;
+ public Builder setBlockModes(String... blockModes) {
+ mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
return this;
}
@@ -429,7 +427,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
* @see #setUserAuthenticationValidityDurationSeconds(int)
*/
public Builder setUserAuthenticators(
- @KeyStoreKeyConstraints.UserAuthenticatorEnum int userAuthenticators) {
+ @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators) {
mUserAuthenticators = userAuthenticators;
return this;
}
@@ -458,8 +456,6 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
* <p>By default, enrolling a new fingerprint does not invalidate the key.
*
* @see #setUserAuthenticators(Set)
- *
- * @hide
*/
public Builder setInvalidatedOnNewFingerprintEnrolled(boolean invalidated) {
mInvalidatedOnNewFingerprintEnrolled = invalidated;
@@ -480,7 +476,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
mKeyValidityForOriginationEnd,
mKeyValidityForConsumptionEnd,
mPurposes,
- mPaddings,
+ mEncryptionPaddings,
mBlockModes,
mRandomizedEncryptionRequired,
mUserAuthenticators,
diff --git a/keystore/java/android/security/KeyNotYetValidException.java b/keystore/java/android/security/KeyNotYetValidException.java
index f1c2cac..964cd7e 100644
--- a/keystore/java/android/security/KeyNotYetValidException.java
+++ b/keystore/java/android/security/KeyNotYetValidException.java
@@ -19,8 +19,6 @@ package android.security;
/**
* Indicates that a cryptographic operation failed because the employed key's validity start date
* is in the future.
- *
- * @hide
*/
public class KeyNotYetValidException extends CryptoOperationException {
diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
index 4ca220d..e297d26 100644
--- a/keystore/java/android/security/KeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -78,17 +78,19 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
private final Date mKeyValidityForConsumptionEnd;
- private final @KeyStoreKeyConstraints.PurposeEnum int mPurposes;
+ private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
- private final @KeyStoreKeyConstraints.DigestEnum int mDigests;
+ private final String[] mDigests;
- private final @KeyStoreKeyConstraints.PaddingEnum int mPaddings;
+ private final String[] mEncryptionPaddings;
- private final @KeyStoreKeyConstraints.BlockModeEnum int mBlockModes;
+ private final String[] mSignaturePaddings;
+
+ private final String[] mBlockModes;
private final boolean mRandomizedEncryptionRequired;
- private final @KeyStoreKeyConstraints.UserAuthenticatorEnum int mUserAuthenticators;
+ private final @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
private final int mUserAuthenticationValidityDurationSeconds;
@@ -132,12 +134,13 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
Date keyValidityStart,
Date keyValidityForOriginationEnd,
Date keyValidityForConsumptionEnd,
- @KeyStoreKeyConstraints.PurposeEnum int purposes,
- @KeyStoreKeyConstraints.DigestEnum int digests,
- @KeyStoreKeyConstraints.PaddingEnum int paddings,
- @KeyStoreKeyConstraints.BlockModeEnum int blockModes,
+ @KeyStoreKeyProperties.PurposeEnum int purposes,
+ String[] digests,
+ String[] encryptionPaddings,
+ String[] signaturePaddings,
+ String[] blockModes,
boolean randomizedEncryptionRequired,
- @KeyStoreKeyConstraints.UserAuthenticatorEnum int userAuthenticators,
+ @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators,
int userAuthenticationValidityDurationSeconds,
boolean invalidatedOnNewFingerprintEnrolled) {
if (context == null) {
@@ -174,9 +177,11 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
mPurposes = purposes;
- mDigests = digests;
- mPaddings = paddings;
- mBlockModes = blockModes;
+ mDigests = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(digests));
+ mEncryptionPaddings =
+ ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
+ mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
+ mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
mRandomizedEncryptionRequired = randomizedEncryptionRequired;
mUserAuthenticators = userAuthenticators;
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
@@ -204,14 +209,16 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
startDate,
endDate,
endDate,
- 0,
- 0,
- 0,
- 0,
- true,
- 0,
- -1,
- false);
+ 0, // purposes
+ null, // digests
+ null, // encryption paddings
+ null, // signature paddings
+ null, // block modes
+ false, // randomized encryption required
+ 0, // user authenticators
+ -1, // user authentication validity duration (seconds)
+ false // invalidate on new fingerprint enrolled
+ );
}
/**
@@ -304,8 +311,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* Gets the time instant before which the key pair is not yet valid.
*
* @return instant or {@code null} if not restricted.
- *
- * @hide
*/
public Date getKeyValidityStart() {
return mKeyValidityStart;
@@ -316,8 +321,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* verification.
*
* @return instant or {@code null} if not restricted.
- *
- * @hide
*/
public Date getKeyValidityForConsumptionEnd() {
return mKeyValidityForConsumptionEnd;
@@ -327,8 +330,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* Gets the time instant after which the key pair is no longer valid for encryption and signing.
*
* @return instant or {@code null} if not restricted.
- *
- * @hide
*/
public Date getKeyValidityForOriginationEnd() {
return mKeyValidityForOriginationEnd;
@@ -336,38 +337,37 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
/**
* Gets the set of purposes for which the key can be used.
- *
- * @hide
*/
- public @KeyStoreKeyConstraints.PurposeEnum int getPurposes() {
+ public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
return mPurposes;
}
/**
- * Gets the set of digests to which the key is restricted.
- *
- * @hide
+ * Gets the set of digest algorithms with which the key can be used.
*/
- public @KeyStoreKeyConstraints.DigestEnum int getDigests() {
- return mDigests;
+ public String[] getDigests() {
+ return ArrayUtils.cloneIfNotEmpty(mDigests);
}
/**
- * Gets the set of padding schemes to which the key is restricted.
- *
- * @hide
+ * Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
*/
- public @KeyStoreKeyConstraints.PaddingEnum int getPaddings() {
- return mPaddings;
+ public String[] getEncryptionPaddings() {
+ return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
}
/**
- * Gets the set of block modes to which the key is restricted.
- *
- * @hide
+ * Gets the set of padding schemes with which the key can be used when signing/verifying.
*/
- public @KeyStoreKeyConstraints.BlockModeEnum int getBlockModes() {
- return mBlockModes;
+ public String[] getSignaturePaddings() {
+ return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
+ }
+
+ /**
+ * Gets the set of block modes with which the key can be used.
+ */
+ public String[] getBlockModes() {
+ return ArrayUtils.cloneIfNotEmpty(mBlockModes);
}
/**
@@ -378,8 +378,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* weaknesses due to which ciphertext may leak information about plaintext. For example, if a
* given plaintext always produces the same ciphertext, an attacker may see the repeated
* ciphertexts and be able to deduce something about the plaintext.
- *
- * @hide
*/
public boolean isRandomizedEncryptionRequired() {
return mRandomizedEncryptionRequired;
@@ -393,10 +391,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* restricted.
*
* @return user authenticators or {@code 0} if the key can be used without user authentication.
- *
- * @hide
*/
- public @KeyStoreKeyConstraints.UserAuthenticatorEnum int getUserAuthenticators() {
+ public @KeyStoreKeyProperties.UserAuthenticatorEnum int getUserAuthenticators() {
return mUserAuthenticators;
}
@@ -409,8 +405,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
*
* @return duration in seconds or {@code -1} if not restricted. {@code 0} means authentication
* is required for every use of the key.
- *
- * @hide
*/
public int getUserAuthenticationValidityDurationSeconds() {
return mUserAuthenticationValidityDurationSeconds;
@@ -422,8 +416,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* authenticators protecting access to this key.
*
* @see #getUserAuthenticators()
- *
- * @hide
*/
public boolean isInvalidatedOnNewFingerprintEnrolled() {
return mInvalidatedOnNewFingerprintEnrolled;
@@ -477,17 +469,19 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
private Date mKeyValidityForConsumptionEnd;
- private @KeyStoreKeyConstraints.PurposeEnum int mPurposes;
+ private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
+
+ private String[] mDigests;
- private @KeyStoreKeyConstraints.DigestEnum int mDigests;
+ private String[] mEncryptionPaddings;
- private @KeyStoreKeyConstraints.PaddingEnum int mPaddings;
+ private String[] mSignaturePaddings;
- private @KeyStoreKeyConstraints.BlockModeEnum int mBlockModes;
+ private String[] mBlockModes;
private boolean mRandomizedEncryptionRequired = true;
- private @KeyStoreKeyConstraints.UserAuthenticatorEnum int mUserAuthenticators;
+ private @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
private int mUserAuthenticationValidityDurationSeconds = -1;
@@ -624,8 +618,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* <p>By default, the key is valid at any instant.
*
* @see #setKeyValidityEnd(Date)
- *
- * @hide
*/
public Builder setKeyValidityStart(Date startDate) {
mKeyValidityStart = startDate;
@@ -640,8 +632,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* @see #setKeyValidityStart(Date)
* @see #setKeyValidityForConsumptionEnd(Date)
* @see #setKeyValidityForOriginationEnd(Date)
- *
- * @hide
*/
public Builder setKeyValidityEnd(Date endDate) {
setKeyValidityForOriginationEnd(endDate);
@@ -655,8 +645,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* <p>By default, the key is valid at any instant.
*
* @see #setKeyValidityForConsumptionEnd(Date)
- *
- * @hide
*/
public Builder setKeyValidityForOriginationEnd(Date endDate) {
mKeyValidityForOriginationEnd = endDate;
@@ -670,8 +658,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* <p>By default, the key is valid at any instant.
*
* @see #setKeyValidityForOriginationEnd(Date)
- *
- * @hide
*/
public Builder setKeyValidityForConsumptionEnd(Date endDate) {
mKeyValidityForConsumptionEnd = endDate;
@@ -679,53 +665,58 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
}
/**
- * Restricts the key to being used only for the provided set of purposes.
- *
- * <p>This restriction must be specified. There is no default.
+ * Sets the set of purposes for which the key can be used.
*
- * @hide
+ * <p>This must be specified for all keys. There is no default.
*/
- public Builder setPurposes(@KeyStoreKeyConstraints.PurposeEnum int purposes) {
+ public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) {
mPurposes = purposes;
return this;
}
/**
- * Restricts the key to being used only with the provided digests. Attempts to use the key
- * with any other digests be rejected.
+ * Sets the set of digests with which the key can be used when signing/verifying. Attempts
+ * to use the key with any other digest will be rejected.
*
- * <p>This restriction must be specified for keys which are used for signing/verification.
- *
- * @hide
+ * <p>This must be specified for keys which are used for signing/verification.
*/
- public Builder setDigests(@KeyStoreKeyConstraints.DigestEnum int digests) {
- mDigests = digests;
+ public Builder setDigests(String... digests) {
+ mDigests = ArrayUtils.cloneIfNotEmpty(digests);
return this;
}
/**
- * Restricts the key to being used only with the provided padding schemes. Attempts to use
- * the key with any other padding will be rejected.
- *
- * <p>This restriction must be specified for keys which are used for encryption/decryption.
+ * Sets the set of padding schemes with which the key can be used when
+ * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
+ * rejected.
*
- * @hide
+ * <p>This must be specified for keys which are used for encryption/decryption.
*/
- public Builder setPaddings(@KeyStoreKeyConstraints.PaddingEnum int paddings) {
- mPaddings = paddings;
+ public Builder setEncryptionPaddings(String... paddings) {
+ mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
return this;
}
/**
- * Restricts the key to being used only with the provided block mode when encrypting or
- * decrypting. Attempts to use the key with any other block modes will be rejected.
+ * Sets the set of padding schemes with which the key can be used when
+ * signing/verifying. Attempts to use the key with any other padding scheme will be
+ * rejected.
*
- * <p>This restriction must be specified for keys which are used for encryption/decryption.
+ * <p>This must be specified for RSA keys which are used for signing/verification.
+ */
+ public Builder setSignaturePaddings(String... paddings) {
+ mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
+ return this;
+ }
+
+ /**
+ * Sets the set of block modes with which the key can be used when encrypting/decrypting.
+ * Attempts to use the key with any other block modes will be rejected.
*
- * @hide
+ * <p>This must be specified for encryption/decryption keys.
*/
- public Builder setBlockModes(@KeyStoreKeyConstraints.BlockModeEnum int blockModes) {
- mBlockModes = blockModes;
+ public Builder setBlockModes(String... blockModes) {
+ mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
return this;
}
@@ -748,8 +739,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* <li>If you are using RSA encryption without padding, consider switching to padding
* schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li>
* </ul>
- *
- * @hide
*/
public Builder setRandomizedEncryptionRequired(boolean required) {
mRandomizedEncryptionRequired = required;
@@ -769,11 +758,9 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* without user authentication.
*
* @see #setUserAuthenticationValidityDurationSeconds(int)
- *
- * @hide
*/
public Builder setUserAuthenticators(
- @KeyStoreKeyConstraints.UserAuthenticatorEnum int userAuthenticators) {
+ @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators) {
mUserAuthenticators = userAuthenticators;
return this;
}
@@ -791,8 +778,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* every use of the key.
*
* @see #setUserAuthenticators(int)
- *
- * @hide
*/
public Builder setUserAuthenticationValidityDurationSeconds(int seconds) {
mUserAuthenticationValidityDurationSeconds = seconds;
@@ -807,8 +792,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* <p>By default, enrolling a new fingerprint does not invalidate the key.
*
* @see #setUserAuthenticators(Set)
- *
- * @hide
*/
public Builder setInvalidatedOnNewFingerprintEnrolled(boolean invalidated) {
mInvalidatedOnNewFingerprintEnrolled = invalidated;
@@ -837,7 +820,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
mKeyValidityForConsumptionEnd,
mPurposes,
mDigests,
- mPaddings,
+ mEncryptionPaddings,
+ mSignaturePaddings,
mBlockModes,
mRandomizedEncryptionRequired,
mUserAuthenticators,
diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java
index 487eac0..7bc6378 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/KeyStoreCipherSpi.java
@@ -48,68 +48,67 @@ import javax.crypto.spec.IvParameterSpec;
public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCryptoOperation {
public abstract static class AES extends KeyStoreCipherSpi {
- protected AES(@KeyStoreKeyConstraints.BlockModeEnum int blockMode,
- @KeyStoreKeyConstraints.PaddingEnum int padding, boolean ivUsed) {
- super(KeyStoreKeyConstraints.Algorithm.AES,
- blockMode,
- padding,
+ protected AES(int keymasterBlockMode, int keymasterPadding, boolean ivUsed) {
+ super(KeymasterDefs.KM_ALGORITHM_AES,
+ keymasterBlockMode,
+ keymasterPadding,
16,
ivUsed);
}
public abstract static class ECB extends AES {
- protected ECB(@KeyStoreKeyConstraints.PaddingEnum int padding) {
- super(KeyStoreKeyConstraints.BlockMode.ECB, padding, false);
+ protected ECB(int keymasterPadding) {
+ super(KeymasterDefs.KM_MODE_ECB, keymasterPadding, false);
}
public static class NoPadding extends ECB {
public NoPadding() {
- super(KeyStoreKeyConstraints.Padding.NONE);
+ super(KeymasterDefs.KM_PAD_NONE);
}
}
public static class PKCS7Padding extends ECB {
public PKCS7Padding() {
- super(KeyStoreKeyConstraints.Padding.PKCS7);
+ super(KeymasterDefs.KM_PAD_PKCS7);
}
}
}
public abstract static class CBC extends AES {
- protected CBC(@KeyStoreKeyConstraints.BlockModeEnum int padding) {
- super(KeyStoreKeyConstraints.BlockMode.CBC, padding, true);
+ protected CBC(int keymasterPadding) {
+ super(KeymasterDefs.KM_MODE_CBC, keymasterPadding, true);
}
public static class NoPadding extends CBC {
public NoPadding() {
- super(KeyStoreKeyConstraints.Padding.NONE);
+ super(KeymasterDefs.KM_PAD_NONE);
}
}
public static class PKCS7Padding extends CBC {
public PKCS7Padding() {
- super(KeyStoreKeyConstraints.Padding.PKCS7);
+ super(KeymasterDefs.KM_PAD_PKCS7);
}
}
}
public abstract static class CTR extends AES {
- protected CTR(@KeyStoreKeyConstraints.BlockModeEnum int padding) {
- super(KeyStoreKeyConstraints.BlockMode.CTR, padding, true);
+ protected CTR(int keymasterPadding) {
+ super(KeymasterDefs.KM_MODE_CTR, keymasterPadding, true);
}
public static class NoPadding extends CTR {
public NoPadding() {
- super(KeyStoreKeyConstraints.Padding.NONE);
+ super(KeymasterDefs.KM_PAD_NONE);
}
}
}
}
private final KeyStore mKeyStore;
- private final @KeyStoreKeyConstraints.AlgorithmEnum int mAlgorithm;
- private final @KeyStoreKeyConstraints.BlockModeEnum int mBlockMode;
- private final @KeyStoreKeyConstraints.PaddingEnum int mPadding;
+ private final int mKeymasterAlgorithm;
+ private final int mKeymasterBlockMode;
+ private final int mKeymasterPadding;
private final int mBlockSizeBytes;
/** Whether this transformation requires an IV. */
@@ -138,15 +137,15 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
private KeyStoreCryptoOperationChunkedStreamer mMainDataStreamer;
protected KeyStoreCipherSpi(
- @KeyStoreKeyConstraints.AlgorithmEnum int algorithm,
- @KeyStoreKeyConstraints.BlockModeEnum int blockMode,
- @KeyStoreKeyConstraints.PaddingEnum int padding,
+ int keymasterAlgorithm,
+ int keymasterBlockMode,
+ int keymasterPadding,
int blockSizeBytes,
boolean ivUsed) {
mKeyStore = KeyStore.getInstance();
- mAlgorithm = algorithm;
- mBlockMode = blockMode;
- mPadding = padding;
+ mKeymasterAlgorithm = keymasterAlgorithm;
+ mKeymasterBlockMode = keymasterBlockMode;
+ mKeymasterPadding = keymasterPadding;
mBlockSizeBytes = blockSizeBytes;
mIvRequired = ivUsed;
}
@@ -236,9 +235,9 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
}
KeymasterArguments keymasterInputArgs = new KeymasterArguments();
- keymasterInputArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, mAlgorithm);
- keymasterInputArgs.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, mBlockMode);
- keymasterInputArgs.addInt(KeymasterDefs.KM_TAG_PADDING, mPadding);
+ keymasterInputArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
+ keymasterInputArgs.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
+ keymasterInputArgs.addInt(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
addAlgorithmSpecificParametersToBegin(keymasterInputArgs);
KeymasterArguments keymasterOutputArgs = new KeymasterArguments();
diff --git a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
index 1f8b7e4..aafd2fa 100644
--- a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
@@ -19,6 +19,8 @@ package android.security;
import android.os.IBinder;
import android.security.keymaster.OperationResult;
+import libcore.util.EmptyArray;
+
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -95,7 +97,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
// Too much input for one chunk -- extract one max-sized chunk and feed it into the
// update operation.
inputBytesInChunk = mMaxChunkSize - mBufferedLength;
- chunk = concat(mBuffered, mBufferedOffset, mBufferedLength,
+ chunk = ArrayUtils.concat(mBuffered, mBufferedOffset, mBufferedLength,
input, inputOffset, inputBytesInChunk);
} else {
// All of available input fits into one chunk.
@@ -108,7 +110,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
} else {
// Need to combine buffered data with input data into one array.
inputBytesInChunk = inputLength;
- chunk = concat(mBuffered, mBufferedOffset, mBufferedLength,
+ chunk = ArrayUtils.concat(mBuffered, mBufferedOffset, mBufferedLength,
input, inputOffset, inputBytesInChunk);
}
}
@@ -197,7 +199,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
// Flush all buffered input and provided input into keystore/keymaster.
byte[] output = update(input, inputOffset, inputLength);
- output = concat(output, flush());
+ output = ArrayUtils.concat(output, flush());
OperationResult opResult = mKeyStoreStream.finish();
if (opResult == null) {
@@ -206,7 +208,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
throw KeyStore.getKeyStoreException(opResult.resultCode);
}
- return concat(output, opResult.output);
+ return ArrayUtils.concat(output, opResult.output);
}
/**
@@ -215,11 +217,11 @@ public class KeyStoreCryptoOperationChunkedStreamer {
*/
public byte[] flush() throws KeyStoreException {
if (mBufferedLength <= 0) {
- return EMPTY_BYTE_ARRAY;
+ return EmptyArray.BYTE;
}
- byte[] chunk = subarray(mBuffered, mBufferedOffset, mBufferedLength);
- mBuffered = EMPTY_BYTE_ARRAY;
+ byte[] chunk = ArrayUtils.subarray(mBuffered, mBufferedOffset, mBufferedLength);
+ mBuffered = EmptyArray.BYTE;
mBufferedLength = 0;
mBufferedOffset = 0;
@@ -238,46 +240,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
+ " . Provided: " + chunk.length + ", consumed: " + opResult.inputConsumed);
}
- return (opResult.output != null) ? opResult.output : EMPTY_BYTE_ARRAY;
- }
-
- private static byte[] concat(byte[] arr1, byte[] arr2) {
- if ((arr1 == null) || (arr1.length == 0)) {
- return arr2;
- } else if ((arr2 == null) || (arr2.length == 0)) {
- return arr1;
- } else {
- byte[] result = new byte[arr1.length + arr2.length];
- System.arraycopy(arr1, 0, result, 0, arr1.length);
- System.arraycopy(arr2, 0, result, arr1.length, arr2.length);
- return result;
- }
- }
-
- private static byte[] concat(byte[] arr1, int offset1, int len1, byte[] arr2, int offset2,
- int len2) {
- if (len1 == 0) {
- return subarray(arr2, offset2, len2);
- } else if (len2 == 0) {
- return subarray(arr1, offset1, len1);
- } else {
- byte[] result = new byte[len1 + len2];
- System.arraycopy(arr1, offset1, result, 0, len1);
- System.arraycopy(arr2, offset2, result, len1, len2);
- return result;
- }
- }
-
- private static byte[] subarray(byte[] arr, int offset, int len) {
- if (len == 0) {
- return EMPTY_BYTE_ARRAY;
- }
- if ((offset == 0) && (len == arr.length)) {
- return arr;
- }
- byte[] result = new byte[len];
- System.arraycopy(arr, offset, result, 0, len);
- return result;
+ return (opResult.output != null) ? opResult.output : EmptyArray.BYTE;
}
/**
diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/KeyStoreHmacSpi.java
index f69e7d1..a19bbda 100644
--- a/keystore/java/android/security/KeyStoreHmacSpi.java
+++ b/keystore/java/android/security/KeyStoreHmacSpi.java
@@ -37,36 +37,36 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
public static class HmacSHA1 extends KeyStoreHmacSpi {
public HmacSHA1() {
- super(KeyStoreKeyConstraints.Digest.SHA1);
+ super(KeymasterDefs.KM_DIGEST_SHA1);
}
}
public static class HmacSHA224 extends KeyStoreHmacSpi {
public HmacSHA224() {
- super(KeyStoreKeyConstraints.Digest.SHA224);
+ super(KeymasterDefs.KM_DIGEST_SHA_2_224);
}
}
public static class HmacSHA256 extends KeyStoreHmacSpi {
public HmacSHA256() {
- super(KeyStoreKeyConstraints.Digest.SHA256);
+ super(KeymasterDefs.KM_DIGEST_SHA_2_256);
}
}
public static class HmacSHA384 extends KeyStoreHmacSpi {
public HmacSHA384() {
- super(KeyStoreKeyConstraints.Digest.SHA384);
+ super(KeymasterDefs.KM_DIGEST_SHA_2_384);
}
}
public static class HmacSHA512 extends KeyStoreHmacSpi {
public HmacSHA512() {
- super(KeyStoreKeyConstraints.Digest.SHA512);
+ super(KeymasterDefs.KM_DIGEST_SHA_2_512);
}
}
private final KeyStore mKeyStore = KeyStore.getInstance();
- private final @KeyStoreKeyConstraints.DigestEnum int mDigest;
+ private final int mKeymasterDigest;
private final int mMacSizeBytes;
private String mKeyAliasInKeyStore;
@@ -76,9 +76,9 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
private IBinder mOperationToken;
private Long mOperationHandle;
- protected KeyStoreHmacSpi(@KeyStoreKeyConstraints.DigestEnum int digest) {
- mDigest = digest;
- mMacSizeBytes = KeyStoreKeyConstraints.Digest.getOutputSizeBytes(digest);
+ protected KeyStoreHmacSpi(int keymasterDigest) {
+ mKeymasterDigest = keymasterDigest;
+ mMacSizeBytes = KeymasterUtils.getDigestOutputSizeBytes(keymasterDigest);
}
@Override
@@ -129,8 +129,8 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
}
KeymasterArguments keymasterArgs = new KeymasterArguments();
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeyStoreKeyConstraints.Algorithm.HMAC);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mDigest);
+ keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC);
+ keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
OperationResult opResult = mKeyStore.begin(mKeyAliasInKeyStore,
KeymasterDefs.KM_PURPOSE_SIGN,
diff --git a/keystore/java/android/security/KeyStoreKeyCharacteristics.java b/keystore/java/android/security/KeyStoreKeyCharacteristics.java
deleted file mode 100644
index 1f5d400..0000000
--- a/keystore/java/android/security/KeyStoreKeyCharacteristics.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2015 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.security;
-
-import android.annotation.IntDef;
-import android.security.keymaster.KeymasterDefs;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Characteristics of {@code AndroidKeyStore} keys.
- *
- * @hide
- */
-public abstract class KeyStoreKeyCharacteristics {
- private KeyStoreKeyCharacteristics() {}
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({Origin.GENERATED, Origin.IMPORTED})
- public @interface OriginEnum {}
-
- /**
- * Origin of the key.
- */
- public static abstract class Origin {
- private Origin() {}
-
- /** Key was generated inside AndroidKeyStore. */
- public static final int GENERATED = 1 << 0;
-
- /** Key was imported into AndroidKeyStore. */
- public static final int IMPORTED = 1 << 1;
-
- /**
- * @hide
- */
- public static @OriginEnum int fromKeymaster(int origin) {
- switch (origin) {
- case KeymasterDefs.KM_ORIGIN_HARDWARE:
- return GENERATED;
- case KeymasterDefs.KM_ORIGIN_IMPORTED:
- return IMPORTED;
- default:
- throw new IllegalArgumentException("Unknown origin: " + origin);
- }
- }
- }
-}
diff --git a/keystore/java/android/security/KeyStoreKeyConstraints.java b/keystore/java/android/security/KeyStoreKeyConstraints.java
deleted file mode 100644
index 98ac3e7..0000000
--- a/keystore/java/android/security/KeyStoreKeyConstraints.java
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * Copyright (C) 2015 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.security;
-
-import android.annotation.IntDef;
-import android.security.keymaster.KeymasterDefs;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Collection;
-import java.util.Locale;
-
-/**
- * Constraints for {@code AndroidKeyStore} keys.
- *
- * @hide
- */
-public abstract class KeyStoreKeyConstraints {
- private KeyStoreKeyConstraints() {}
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true,
- value = {Purpose.ENCRYPT, Purpose.DECRYPT, Purpose.SIGN, Purpose.VERIFY})
- public @interface PurposeEnum {}
-
- /**
- * Purpose of key.
- */
- public static abstract class Purpose {
- private Purpose() {}
-
- /**
- * Purpose: encryption.
- */
- public static final int ENCRYPT = 1 << 0;
-
- /**
- * Purpose: decryption.
- */
- public static final int DECRYPT = 1 << 1;
-
- /**
- * Purpose: signing.
- */
- public static final int SIGN = 1 << 2;
-
- /**
- * Purpose: signature verification.
- */
- public static final int VERIFY = 1 << 3;
-
- /**
- * @hide
- */
- public static int toKeymaster(@PurposeEnum int purpose) {
- switch (purpose) {
- case ENCRYPT:
- return KeymasterDefs.KM_PURPOSE_ENCRYPT;
- case DECRYPT:
- return KeymasterDefs.KM_PURPOSE_DECRYPT;
- case SIGN:
- return KeymasterDefs.KM_PURPOSE_SIGN;
- case VERIFY:
- return KeymasterDefs.KM_PURPOSE_VERIFY;
- default:
- throw new IllegalArgumentException("Unknown purpose: " + purpose);
- }
- }
-
- /**
- * @hide
- */
- public static @PurposeEnum int fromKeymaster(int purpose) {
- switch (purpose) {
- case KeymasterDefs.KM_PURPOSE_ENCRYPT:
- return ENCRYPT;
- case KeymasterDefs.KM_PURPOSE_DECRYPT:
- return DECRYPT;
- case KeymasterDefs.KM_PURPOSE_SIGN:
- return SIGN;
- case KeymasterDefs.KM_PURPOSE_VERIFY:
- return VERIFY;
- default:
- throw new IllegalArgumentException("Unknown purpose: " + purpose);
- }
- }
-
- /**
- * @hide
- */
- public static int[] allToKeymaster(@PurposeEnum int purposes) {
- int[] result = getSetFlags(purposes);
- for (int i = 0; i < result.length; i++) {
- result[i] = toKeymaster(result[i]);
- }
- return result;
- }
-
- /**
- * @hide
- */
- public static @PurposeEnum int allFromKeymaster(Collection<Integer> purposes) {
- @PurposeEnum int result = 0;
- for (int keymasterPurpose : purposes) {
- result |= fromKeymaster(keymasterPurpose);
- }
- return result;
- }
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({Algorithm.AES, Algorithm.HMAC, Algorithm.RSA, Algorithm.EC})
- public @interface AlgorithmEnum {}
-
- /**
- * Key algorithm.
- */
- public static abstract class Algorithm {
- private Algorithm() {}
-
- /**
- * Key algorithm: AES.
- */
- public static final int AES = 1 << 0;
-
- /**
- * Key algorithm: HMAC.
- */
- public static final int HMAC = 1 << 1;
-
- /**
- * Key algorithm: RSA.
- */
- public static final int RSA = 1 << 2;
-
- /**
- * Key algorithm: EC.
- */
- public static final int EC = 1 << 3;
-
- /**
- * @hide
- */
- public static int toKeymaster(@AlgorithmEnum int algorithm) {
- switch (algorithm) {
- case AES:
- return KeymasterDefs.KM_ALGORITHM_AES;
- case HMAC:
- return KeymasterDefs.KM_ALGORITHM_HMAC;
- case RSA:
- return KeymasterDefs.KM_ALGORITHM_RSA;
- case EC:
- return KeymasterDefs.KM_ALGORITHM_EC;
- default:
- throw new IllegalArgumentException("Unknown algorithm: " + algorithm);
- }
- }
-
- /**
- * @hide
- */
- public static @AlgorithmEnum int fromKeymaster(int algorithm) {
- switch (algorithm) {
- case KeymasterDefs.KM_ALGORITHM_AES:
- return AES;
- case KeymasterDefs.KM_ALGORITHM_HMAC:
- return HMAC;
- case KeymasterDefs.KM_ALGORITHM_RSA:
- return RSA;
- case KeymasterDefs.KM_ALGORITHM_EC:
- return EC;
- default:
- throw new IllegalArgumentException("Unknown algorithm: " + algorithm);
- }
- }
-
- /**
- * @hide
- */
- public static String toString(@AlgorithmEnum int algorithm) {
- switch (algorithm) {
- case AES:
- return "AES";
- case HMAC:
- return "HMAC";
- case RSA:
- return "RSA";
- case EC:
- return "EC";
- default:
- throw new IllegalArgumentException("Unknown algorithm: " + algorithm);
- }
- }
-
- /**
- * @hide
- */
- public static @AlgorithmEnum int fromJCASecretKeyAlgorithm(String algorithm) {
- if (algorithm == null) {
- throw new NullPointerException("algorithm == null");
- } else if ("AES".equalsIgnoreCase(algorithm)) {
- return AES;
- } else if (algorithm.toLowerCase(Locale.US).startsWith("hmac")) {
- return HMAC;
- } else {
- throw new IllegalArgumentException(
- "Unsupported secret key algorithm: " + algorithm);
- }
- }
-
- /**
- * @hide
- */
- public static String toJCASecretKeyAlgorithm(@AlgorithmEnum int algorithm,
- @DigestEnum Integer digest) {
- switch (algorithm) {
- case AES:
- return "AES";
- case HMAC:
- if (digest == null) {
- throw new IllegalArgumentException("HMAC digest not specified");
- }
- switch (digest) {
- case Digest.MD5:
- return "HmacMD5";
- case Digest.SHA1:
- return "HmacSHA1";
- case Digest.SHA224:
- return "HmacSHA224";
- case Digest.SHA256:
- return "HmacSHA256";
- case Digest.SHA384:
- return "HmacSHA384";
- case Digest.SHA512:
- return "HmacSHA512";
- default:
- throw new IllegalArgumentException(
- "Unsupported HMAC digest: " + digest);
- }
- default:
- throw new IllegalArgumentException("Unsupported key algorithm: " + algorithm);
- }
- }
-
- /**
- * @hide
- */
- public static String toJCAKeyPairAlgorithm(@AlgorithmEnum int algorithm) {
- switch (algorithm) {
- case RSA:
- return "RSA";
- case EC:
- return "EC";
- default:
- throw new IllegalArgumentException("Unsupported key alorithm: " + algorithm);
- }
- }
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true,
- value = {
- Padding.NONE,
- Padding.PKCS7,
- Padding.RSA_PKCS1_ENCRYPTION,
- Padding.RSA_PKCS1_SIGNATURE,
- Padding.RSA_OAEP,
- Padding.RSA_PSS,
- })
- public @interface PaddingEnum {}
-
- /**
- * Padding for signing and encryption.
- */
- public static abstract class Padding {
- private Padding() {}
-
- /**
- * No padding.
- */
- public static final int NONE = 1 << 0;
-
- /**
- * PKCS#7 padding.
- */
- public static final int PKCS7 = 1 << 1;
-
- /**
- * RSA PKCS#1 v1.5 padding for encryption/decryption.
- */
- public static final int RSA_PKCS1_ENCRYPTION = 1 << 2;
-
- /**
- * RSA PKCS#1 v1.5 padding for signatures.
- */
- public static final int RSA_PKCS1_SIGNATURE = 1 << 3;
-
- /**
- * RSA Optimal Asymmetric Encryption Padding (OAEP).
- */
- public static final int RSA_OAEP = 1 << 4;
-
- /**
- * RSA PKCS#1 v2.1 Probabilistic Signature Scheme (PSS) padding.
- */
- public static final int RSA_PSS = 1 << 5;
-
- /**
- * @hide
- */
- public static int toKeymaster(int padding) {
- switch (padding) {
- case NONE:
- return KeymasterDefs.KM_PAD_NONE;
- case PKCS7:
- return KeymasterDefs.KM_PAD_PKCS7;
- case RSA_PKCS1_ENCRYPTION:
- return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT;
- case RSA_PKCS1_SIGNATURE:
- return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN;
- case RSA_OAEP:
- return KeymasterDefs.KM_PAD_RSA_OAEP;
- case RSA_PSS:
- return KeymasterDefs.KM_PAD_RSA_PSS;
- default:
- throw new IllegalArgumentException("Unknown padding: " + padding);
- }
- }
-
- /**
- * @hide
- */
- public static @PaddingEnum int fromKeymaster(int padding) {
- switch (padding) {
- case KeymasterDefs.KM_PAD_NONE:
- return NONE;
- case KeymasterDefs.KM_PAD_PKCS7:
- return PKCS7;
- case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
- return RSA_PKCS1_ENCRYPTION;
- case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN:
- return RSA_PKCS1_SIGNATURE;
- case KeymasterDefs.KM_PAD_RSA_OAEP:
- return RSA_OAEP;
- case KeymasterDefs.KM_PAD_RSA_PSS:
- return RSA_PSS;
- default:
- throw new IllegalArgumentException("Unknown padding: " + padding);
- }
- }
-
- /**
- * @hide
- */
- public static String toString(@PaddingEnum int padding) {
- switch (padding) {
- case NONE:
- return "NONE";
- case PKCS7:
- return "PKCS#7";
- case RSA_PKCS1_ENCRYPTION:
- return "RSA PKCS#1 (encryption)";
- case RSA_PKCS1_SIGNATURE:
- return "RSA PKCS#1 (signature)";
- case RSA_OAEP:
- return "RSA OAEP";
- case RSA_PSS:
- return "RSA PSS";
- default:
- throw new IllegalArgumentException("Unknown padding: " + padding);
- }
- }
-
- /**
- * @hide
- */
- public static @PaddingEnum int fromJCACipherPadding(String padding) {
- String paddingLower = padding.toLowerCase(Locale.US);
- if ("nopadding".equals(paddingLower)) {
- return NONE;
- } else if ("pkcs7padding".equals(paddingLower)) {
- return PKCS7;
- } else if ("pkcs1padding".equals(paddingLower)) {
- return RSA_PKCS1_ENCRYPTION;
- } else if (("oaeppadding".equals(paddingLower))
- || ((paddingLower.startsWith("oaepwith"))
- && (paddingLower.endsWith("padding")))) {
- return RSA_OAEP;
- } else {
- throw new IllegalArgumentException("Unknown padding: " + padding);
- }
- }
-
- /**
- * @hide
- */
- public static int[] allToKeymaster(@PaddingEnum int paddings) {
- int[] result = getSetFlags(paddings);
- for (int i = 0; i < result.length; i++) {
- result[i] = toKeymaster(result[i]);
- }
- return result;
- }
-
- /**
- * @hide
- */
- public static @PaddingEnum int allFromKeymaster(Collection<Integer> paddings) {
- @PaddingEnum int result = 0;
- for (int keymasterPadding : paddings) {
- result |= fromKeymaster(keymasterPadding);
- }
- return result;
- }
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true,
- value = {
- Digest.NONE,
- Digest.MD5,
- Digest.SHA1,
- Digest.SHA224,
- Digest.SHA256,
- Digest.SHA384,
- Digest.SHA512,
- })
- public @interface DigestEnum {}
-
- /**
- * Digests that can be used with a key when signing or generating Message Authentication
- * Codes (MACs).
- */
- public static abstract class Digest {
- private Digest() {}
-
- /**
- * No digest: sign/authenticate the raw message.
- */
- public static final int NONE = 1 << 0;
-
- /**
- * MD5 digest.
- */
- public static final int MD5 = 1 << 1;
-
- /**
- * SHA-1 digest.
- */
- public static final int SHA1 = 1 << 2;
-
- /**
- * SHA-2 224 (aka SHA-224) digest.
- */
- public static final int SHA224 = 1 << 3;
-
- /**
- * SHA-2 256 (aka SHA-256) digest.
- */
- public static final int SHA256 = 1 << 4;
-
- /**
- * SHA-2 384 (aka SHA-384) digest.
- */
- public static final int SHA384 = 1 << 5;
-
- /**
- * SHA-2 512 (aka SHA-512) digest.
- */
- public static final int SHA512 = 1 << 6;
-
- /**
- * @hide
- */
- public static String toString(@DigestEnum int digest) {
- switch (digest) {
- case NONE:
- return "NONE";
- case MD5:
- return "MD5";
- case SHA1:
- return "SHA-1";
- case SHA224:
- return "SHA-224";
- case SHA256:
- return "SHA-256";
- case SHA384:
- return "SHA-384";
- case SHA512:
- return "SHA-512";
- default:
- throw new IllegalArgumentException("Unknown digest: " + digest);
- }
- }
-
- /**
- * @hide
- */
- public static String allToString(@DigestEnum int digests) {
- StringBuilder result = new StringBuilder("[");
- boolean firstValue = true;
- for (@DigestEnum int digest : getSetFlags(digests)) {
- if (firstValue) {
- firstValue = false;
- } else {
- result.append(", ");
- }
- result.append(toString(digest));
- }
- result.append(']');
- return result.toString();
- }
-
- /**
- * @hide
- */
- public static int toKeymaster(@DigestEnum int digest) {
- switch (digest) {
- case NONE:
- return KeymasterDefs.KM_DIGEST_NONE;
- case MD5:
- return KeymasterDefs.KM_DIGEST_MD5;
- case SHA1:
- return KeymasterDefs.KM_DIGEST_SHA1;
- case SHA224:
- return KeymasterDefs.KM_DIGEST_SHA_2_224;
- case SHA256:
- return KeymasterDefs.KM_DIGEST_SHA_2_256;
- case SHA384:
- return KeymasterDefs.KM_DIGEST_SHA_2_384;
- case SHA512:
- return KeymasterDefs.KM_DIGEST_SHA_2_512;
- default:
- throw new IllegalArgumentException("Unknown digest: " + digest);
- }
- }
-
- /**
- * @hide
- */
- public static @DigestEnum int fromKeymaster(int digest) {
- switch (digest) {
- case KeymasterDefs.KM_DIGEST_NONE:
- return NONE;
- case KeymasterDefs.KM_DIGEST_MD5:
- return MD5;
- case KeymasterDefs.KM_DIGEST_SHA1:
- return SHA1;
- case KeymasterDefs.KM_DIGEST_SHA_2_224:
- return SHA224;
- case KeymasterDefs.KM_DIGEST_SHA_2_256:
- return SHA256;
- case KeymasterDefs.KM_DIGEST_SHA_2_384:
- return SHA384;
- case KeymasterDefs.KM_DIGEST_SHA_2_512:
- return SHA512;
- default:
- throw new IllegalArgumentException("Unknown digest: " + digest);
- }
- }
-
- /**
- * @hide
- */
- public static int[] allToKeymaster(@DigestEnum int digests) {
- int[] result = getSetFlags(digests);
- for (int i = 0; i < result.length; i++) {
- result[i] = toKeymaster(result[i]);
- }
- return result;
- }
-
- /**
- * @hide
- */
- public static @DigestEnum int allFromKeymaster(Collection<Integer> digests) {
- @DigestEnum int result = 0;
- for (int keymasterDigest : digests) {
- result |= fromKeymaster(keymasterDigest);
- }
- return result;
- }
-
- /**
- * @hide
- */
- public static @DigestEnum Integer fromJCASecretKeyAlgorithm(String algorithm) {
- String algorithmLower = algorithm.toLowerCase(Locale.US);
- if (algorithmLower.startsWith("hmac")) {
- String digestLower = algorithmLower.substring("hmac".length());
- if ("md5".equals(digestLower)) {
- return MD5;
- } else if ("sha1".equals(digestLower)) {
- return SHA1;
- } else if ("sha224".equals(digestLower)) {
- return SHA224;
- } else if ("sha256".equals(digestLower)) {
- return SHA256;
- } else if ("sha384".equals(digestLower)) {
- return SHA384;
- } else if ("sha512".equals(digestLower)) {
- return SHA512;
- } else {
- throw new IllegalArgumentException("Unsupported digest: " + digestLower);
- }
- } else {
- return null;
- }
- }
-
- /**
- * @hide
- */
- public static String toJCASignatureAlgorithmDigest(@DigestEnum int digest) {
- switch (digest) {
- case NONE:
- return "NONE";
- case MD5:
- return "MD5";
- case SHA1:
- return "SHA1";
- case SHA224:
- return "SHA224";
- case SHA256:
- return "SHA256";
- case SHA384:
- return "SHA384";
- case SHA512:
- return "SHA512";
- default:
- throw new IllegalArgumentException("Unknown digest: " + digest);
- }
- }
-
- /**
- * @hide
- */
- public static Integer getOutputSizeBytes(@DigestEnum int digest) {
- switch (digest) {
- case NONE:
- return null;
- case MD5:
- return 128 / 8;
- case SHA1:
- return 160 / 8;
- case SHA224:
- return 224 / 8;
- case SHA256:
- return 256 / 8;
- case SHA384:
- return 384 / 8;
- case SHA512:
- return 512 / 8;
- default:
- throw new IllegalArgumentException("Unknown digest: " + digest);
- }
- }
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true,
- value = {BlockMode.ECB, BlockMode.CBC, BlockMode.CTR, BlockMode.GCM})
- public @interface BlockModeEnum {}
-
- /**
- * Block modes that can be used when encrypting/decrypting using a key.
- */
- public static abstract class BlockMode {
- private BlockMode() {}
-
- /** Electronic Codebook (ECB) block mode. */
- public static final int ECB = 1 << 0;
-
- /** Cipher Block Chaining (CBC) block mode. */
- public static final int CBC = 1 << 1;
-
- /** Counter (CTR) block mode. */
- public static final int CTR = 1 << 2;
-
- /** Galois/Counter Mode (GCM) block mode. */
- public static final int GCM = 1 << 3;
-
- /**
- * Set of block modes compatible with IND-CPA if used correctly.
- *
- * @hide
- */
- public static final @BlockModeEnum int IND_CPA_COMPATIBLE_MODES =
- CBC | CTR | GCM;
-
- /**
- * @hide
- */
- public static int toKeymaster(@BlockModeEnum int mode) {
- switch (mode) {
- case ECB:
- return KeymasterDefs.KM_MODE_ECB;
- case CBC:
- return KeymasterDefs.KM_MODE_CBC;
- case CTR:
- return KeymasterDefs.KM_MODE_CTR;
- case GCM:
- return KeymasterDefs.KM_MODE_GCM;
- default:
- throw new IllegalArgumentException("Unknown block mode: " + mode);
- }
- }
-
- /**
- * @hide
- */
- public static @BlockModeEnum int fromKeymaster(int mode) {
- switch (mode) {
- case KeymasterDefs.KM_MODE_ECB:
- return ECB;
- case KeymasterDefs.KM_MODE_CBC:
- return CBC;
- case KeymasterDefs.KM_MODE_CTR:
- return CTR;
- case KeymasterDefs.KM_MODE_GCM:
- return GCM;
- default:
- throw new IllegalArgumentException("Unknown block mode: " + mode);
- }
- }
-
- /**
- * @hide
- */
- public static int[] allToKeymaster(@BlockModeEnum int modes) {
- int[] result = getSetFlags(modes);
- for (int i = 0; i < result.length; i++) {
- result[i] = toKeymaster(result[i]);
- }
- return result;
- }
-
- /**
- * @hide
- */
- public static @BlockModeEnum int allFromKeymaster(Collection<Integer> modes) {
- @BlockModeEnum int result = 0;
- for (int keymasterMode : modes) {
- result |= fromKeymaster(keymasterMode);
- }
- return result;
- }
-
- /**
- * @hide
- */
- public static String toString(@BlockModeEnum int mode) {
- switch (mode) {
- case ECB:
- return "ECB";
- case CBC:
- return "CBC";
- case CTR:
- return "CTR";
- case GCM:
- return "GCM";
- default:
- throw new IllegalArgumentException("Unknown block mode: " + mode);
- }
- }
-
- /**
- * @hide
- */
- public static String allToString(@BlockModeEnum int modes) {
- StringBuilder result = new StringBuilder("[");
- boolean firstValue = true;
- for (@BlockModeEnum int mode : getSetFlags(modes)) {
- if (firstValue) {
- firstValue = false;
- } else {
- result.append(", ");
- }
- result.append(toString(mode));
- }
- result.append(']');
- return result.toString();
- }
-
- /**
- * @hide
- */
- public static @BlockModeEnum int fromJCAMode(String mode) {
- String modeLower = mode.toLowerCase(Locale.US);
- if ("ecb".equals(modeLower)) {
- return ECB;
- } else if ("cbc".equals(modeLower)) {
- return CBC;
- } else if ("ctr".equals(modeLower)) {
- return CTR;
- } else if ("gcm".equals(modeLower)) {
- return GCM;
- } else {
- throw new IllegalArgumentException("Unknown block mode: " + mode);
- }
- }
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true,
- value = {UserAuthenticator.LOCK_SCREEN})
- public @interface UserAuthenticatorEnum {}
-
- /**
- * User authenticators which can be used to restrict/protect access to keys.
- */
- public static abstract class UserAuthenticator {
- private UserAuthenticator() {}
-
- /** Lock screen. */
- public static final int LOCK_SCREEN = 1 << 0;
-
- /** Fingerprint reader/sensor. */
- public static final int FINGERPRINT_READER = 1 << 1;
-
- /**
- * @hide
- */
- public static int toKeymaster(@UserAuthenticatorEnum int userAuthenticator) {
- switch (userAuthenticator) {
- case LOCK_SCREEN:
- return KeymasterDefs.HW_AUTH_PASSWORD;
- case FINGERPRINT_READER:
- return KeymasterDefs.HW_AUTH_FINGERPRINT;
- default:
- throw new IllegalArgumentException(
- "Unknown user authenticator: " + userAuthenticator);
- }
- }
-
- /**
- * @hide
- */
- public static @UserAuthenticatorEnum int fromKeymaster(int userAuthenticator) {
- switch (userAuthenticator) {
- case KeymasterDefs.HW_AUTH_PASSWORD:
- return LOCK_SCREEN;
- case FINGERPRINT_READER:
- return FINGERPRINT_READER;
- default:
- throw new IllegalArgumentException(
- "Unknown user authenticator: " + userAuthenticator);
- }
- }
-
- /**
- * @hide
- */
- public static int allToKeymaster(@UserAuthenticatorEnum int userAuthenticators) {
- int result = 0;
- int userAuthenticator = 1;
- while (userAuthenticators != 0) {
- if ((userAuthenticators & 1) != 0) {
- result |= toKeymaster(userAuthenticator);
- }
- userAuthenticators >>>= 1;
- userAuthenticator <<= 1;
- }
- return result;
- }
-
- /**
- * @hide
- */
- public static @UserAuthenticatorEnum int allFromKeymaster(int userAuthenticators) {
- @UserAuthenticatorEnum int result = 0;
- int userAuthenticator = 1;
- while (userAuthenticators != 0) {
- if ((userAuthenticators & 1) != 0) {
- result |= fromKeymaster(userAuthenticator);
- }
- userAuthenticators >>>= 1;
- userAuthenticator <<= 1;
- }
- return result;
- }
-
- /**
- * @hide
- */
- public static String toString(@UserAuthenticatorEnum int userAuthenticator) {
- switch (userAuthenticator) {
- case LOCK_SCREEN:
- return "LOCK_SCREEN";
- case FINGERPRINT_READER:
- return "FINGERPRINT_READER";
- default:
- throw new IllegalArgumentException(
- "Unknown user authenticator: " + userAuthenticator);
- }
- }
- }
-
- private static final int[] EMPTY_INT_ARRAY = new int[0];
-
- private static int[] getSetFlags(int flags) {
- if (flags == 0) {
- return EMPTY_INT_ARRAY;
- }
- int result[] = new int[getSetBitCount(flags)];
- int resultOffset = 0;
- int flag = 1;
- while (flags != 0) {
- if ((flags & 1) != 0) {
- result[resultOffset] = flag;
- resultOffset++;
- }
- flags >>>= 1;
- flag <<= 1;
- }
- return result;
- }
-
- private static int getSetBitCount(int value) {
- if (value == 0) {
- return 0;
- }
- int result = 0;
- while (value != 0) {
- if ((value & 1) != 0) {
- result++;
- }
- value >>>= 1;
- }
- return result;
- }
-}
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
index b39d16d..72c485a 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -37,68 +37,68 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
public static class AES extends KeyStoreKeyGeneratorSpi {
public AES() {
- super(KeyStoreKeyConstraints.Algorithm.AES, 128);
+ super(KeymasterDefs.KM_ALGORITHM_AES, 128);
}
}
protected static abstract class HmacBase extends KeyStoreKeyGeneratorSpi {
- protected HmacBase(@KeyStoreKeyConstraints.DigestEnum int digest) {
- super(KeyStoreKeyConstraints.Algorithm.HMAC,
- digest,
- KeyStoreKeyConstraints.Digest.getOutputSizeBytes(digest) * 8);
+ protected HmacBase(int keymasterDigest) {
+ super(KeymasterDefs.KM_ALGORITHM_HMAC,
+ keymasterDigest,
+ KeymasterUtils.getDigestOutputSizeBytes(keymasterDigest) * 8);
}
}
public static class HmacSHA1 extends HmacBase {
public HmacSHA1() {
- super(KeyStoreKeyConstraints.Digest.SHA1);
+ super(KeymasterDefs.KM_DIGEST_SHA1);
}
}
public static class HmacSHA224 extends HmacBase {
public HmacSHA224() {
- super(KeyStoreKeyConstraints.Digest.SHA224);
+ super(KeymasterDefs.KM_DIGEST_SHA_2_224);
}
}
public static class HmacSHA256 extends HmacBase {
public HmacSHA256() {
- super(KeyStoreKeyConstraints.Digest.SHA256);
+ super(KeymasterDefs.KM_DIGEST_SHA_2_256);
}
}
public static class HmacSHA384 extends HmacBase {
public HmacSHA384() {
- super(KeyStoreKeyConstraints.Digest.SHA384);
+ super(KeymasterDefs.KM_DIGEST_SHA_2_384);
}
}
public static class HmacSHA512 extends HmacBase {
public HmacSHA512() {
- super(KeyStoreKeyConstraints.Digest.SHA512);
+ super(KeymasterDefs.KM_DIGEST_SHA_2_512);
}
}
private final KeyStore mKeyStore = KeyStore.getInstance();
- private final @KeyStoreKeyConstraints.AlgorithmEnum int mAlgorithm;
- private final @KeyStoreKeyConstraints.DigestEnum Integer mDigest;
+ private final int mKeymasterAlgorithm;
+ private final int mKeymasterDigest;
private final int mDefaultKeySizeBits;
private KeyGeneratorSpec mSpec;
private SecureRandom mRng;
protected KeyStoreKeyGeneratorSpi(
- @KeyStoreKeyConstraints.AlgorithmEnum int algorithm,
+ int keymasterAlgorithm,
int defaultKeySizeBits) {
- this(algorithm, null, defaultKeySizeBits);
+ this(keymasterAlgorithm, -1, defaultKeySizeBits);
}
protected KeyStoreKeyGeneratorSpi(
- @KeyStoreKeyConstraints.AlgorithmEnum int algorithm,
- @KeyStoreKeyConstraints.DigestEnum Integer digest,
+ int keymasterAlgorithm,
+ int keymasterDigest,
int defaultKeySizeBits) {
- mAlgorithm = algorithm;
- mDigest = digest;
+ mKeymasterAlgorithm = keymasterAlgorithm;
+ mKeymasterDigest = keymasterDigest;
mDefaultKeySizeBits = defaultKeySizeBits;
}
@@ -117,58 +117,55 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
}
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM,
- KeyStoreKeyConstraints.Algorithm.toKeymaster(mAlgorithm));
- if (mDigest != null) {
- args.addInt(KeymasterDefs.KM_TAG_DIGEST,
- KeyStoreKeyConstraints.Digest.toKeymaster(mDigest));
- Integer digestOutputSizeBytes =
- KeyStoreKeyConstraints.Digest.getOutputSizeBytes(mDigest);
- if (digestOutputSizeBytes != null) {
+ args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
+ if (mKeymasterDigest != -1) {
+ args.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
+ int digestOutputSizeBytes =
+ KeymasterUtils.getDigestOutputSizeBytes(mKeymasterDigest);
+ if (digestOutputSizeBytes != -1) {
// TODO: Remove MAC length constraint once Keymaster API no longer requires it.
// TODO: Switch to bits instead of bytes, once this is fixed in Keymaster
args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, digestOutputSizeBytes);
}
}
- if (mAlgorithm == KeyStoreKeyConstraints.Algorithm.HMAC) {
- if (mDigest == null) {
- throw new IllegalStateException("Digest algorithm must be specified for key"
- + " algorithm " + KeyStoreKeyConstraints.Algorithm.toString(mAlgorithm));
+ if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
+ if (mKeymasterDigest == -1) {
+ throw new IllegalStateException("Digest algorithm must be specified for HMAC key");
}
}
- int keySizeBits = (spec.getKeySize() != null) ? spec.getKeySize() : mDefaultKeySizeBits;
+ int keySizeBits = (spec.getKeySize() != -1) ? spec.getKeySize() : mDefaultKeySizeBits;
args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, keySizeBits);
- @KeyStoreKeyConstraints.PurposeEnum int purposes = spec.getPurposes();
- @KeyStoreKeyConstraints.BlockModeEnum int blockModes = spec.getBlockModes();
- if (((purposes & KeyStoreKeyConstraints.Purpose.ENCRYPT) != 0)
+ @KeyStoreKeyProperties.PurposeEnum int purposes = spec.getPurposes();
+ int[] keymasterBlockModes = KeymasterUtils.getKeymasterBlockModesFromJcaBlockModes(
+ spec.getBlockModes());
+ if (((purposes & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
&& (spec.isRandomizedEncryptionRequired())) {
- @KeyStoreKeyConstraints.BlockModeEnum int incompatibleBlockModes =
- blockModes & ~KeyStoreKeyConstraints.BlockMode.IND_CPA_COMPATIBLE_MODES;
- if (incompatibleBlockModes != 0) {
- throw new IllegalStateException(
- "Randomized encryption (IND-CPA) required but may be violated by block"
- + " mode(s): "
- + KeyStoreKeyConstraints.BlockMode.allToString(incompatibleBlockModes)
- + ". See KeyGeneratorSpec documentation.");
+ for (int keymasterBlockMode : keymasterBlockModes) {
+ if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatible(keymasterBlockMode)) {
+ throw new IllegalStateException(
+ "Randomized encryption (IND-CPA) required but may be violated by block"
+ + " mode: "
+ + KeymasterUtils.getJcaBlockModeFromKeymasterBlockMode(
+ keymasterBlockMode)
+ + ". See KeyGeneratorSpec documentation.");
+ }
}
}
for (int keymasterPurpose :
- KeyStoreKeyConstraints.Purpose.allToKeymaster(purposes)) {
+ KeyStoreKeyProperties.Purpose.allToKeymaster(purposes)) {
args.addInt(KeymasterDefs.KM_TAG_PURPOSE, keymasterPurpose);
}
- for (int keymasterBlockMode : KeyStoreKeyConstraints.BlockMode.allToKeymaster(blockModes)) {
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockMode);
- }
- for (int keymasterPadding :
- KeyStoreKeyConstraints.Padding.allToKeymaster(spec.getPaddings())) {
- args.addInt(KeymasterDefs.KM_TAG_PADDING, keymasterPadding);
- }
+ args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
+ args.addInts(
+ KeymasterDefs.KM_TAG_PADDING,
+ KeymasterUtils.getKeymasterPaddingsFromJcaEncryptionPaddings(
+ spec.getEncryptionPaddings()));
if (spec.getUserAuthenticators() == 0) {
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
} else {
args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
- KeyStoreKeyConstraints.UserAuthenticator.allToKeymaster(
+ KeyStoreKeyProperties.UserAuthenticator.allToKeymaster(
spec.getUserAuthenticators()));
}
if (spec.isInvalidatedOnNewFingerprintEnrolled()) {
@@ -189,7 +186,7 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
(spec.getKeyValidityForConsumptionEnd() != null)
? spec.getKeyValidityForConsumptionEnd() : new Date(Long.MAX_VALUE));
- if (((purposes & KeyStoreKeyConstraints.Purpose.ENCRYPT) != 0)
+ if (((purposes & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
&& (!spec.isRandomizedEncryptionRequired())) {
// Permit caller-provided IV when encrypting with this key
args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
@@ -210,7 +207,7 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
throw KeyStore.getCryptoOperationException(errorCode);
}
String keyAlgorithmJCA =
- KeyStoreKeyConstraints.Algorithm.toJCASecretKeyAlgorithm(mAlgorithm, mDigest);
+ KeymasterUtils.getJcaSecretKeyAlgorithm(mKeymasterAlgorithm, mKeymasterDigest);
return new KeyStoreSecretKey(keyAliasInKeystore, keyAlgorithmJCA);
}
diff --git a/keystore/java/android/security/KeyStoreKeyProperties.java b/keystore/java/android/security/KeyStoreKeyProperties.java
new file mode 100644
index 0000000..b1f330f
--- /dev/null
+++ b/keystore/java/android/security/KeyStoreKeyProperties.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2015 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.security;
+
+import android.annotation.IntDef;
+import android.security.keymaster.KeymasterDefs;
+
+import libcore.util.EmptyArray;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collection;
+
+/**
+ * Properties of {@code AndroidKeyStore} keys.
+ */
+public abstract class KeyStoreKeyProperties {
+ private KeyStoreKeyProperties() {}
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true,
+ value = {Purpose.ENCRYPT, Purpose.DECRYPT, Purpose.SIGN, Purpose.VERIFY})
+ public @interface PurposeEnum {}
+
+ /**
+ * Purpose of key.
+ */
+ public static abstract class Purpose {
+ private Purpose() {}
+
+ /**
+ * Purpose: encryption.
+ */
+ public static final int ENCRYPT = 1 << 0;
+
+ /**
+ * Purpose: decryption.
+ */
+ public static final int DECRYPT = 1 << 1;
+
+ /**
+ * Purpose: signing.
+ */
+ public static final int SIGN = 1 << 2;
+
+ /**
+ * Purpose: signature verification.
+ */
+ public static final int VERIFY = 1 << 3;
+
+ /**
+ * @hide
+ */
+ public static int toKeymaster(@PurposeEnum int purpose) {
+ switch (purpose) {
+ case ENCRYPT:
+ return KeymasterDefs.KM_PURPOSE_ENCRYPT;
+ case DECRYPT:
+ return KeymasterDefs.KM_PURPOSE_DECRYPT;
+ case SIGN:
+ return KeymasterDefs.KM_PURPOSE_SIGN;
+ case VERIFY:
+ return KeymasterDefs.KM_PURPOSE_VERIFY;
+ default:
+ throw new IllegalArgumentException("Unknown purpose: " + purpose);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static @PurposeEnum int fromKeymaster(int purpose) {
+ switch (purpose) {
+ case KeymasterDefs.KM_PURPOSE_ENCRYPT:
+ return ENCRYPT;
+ case KeymasterDefs.KM_PURPOSE_DECRYPT:
+ return DECRYPT;
+ case KeymasterDefs.KM_PURPOSE_SIGN:
+ return SIGN;
+ case KeymasterDefs.KM_PURPOSE_VERIFY:
+ return VERIFY;
+ default:
+ throw new IllegalArgumentException("Unknown purpose: " + purpose);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static int[] allToKeymaster(@PurposeEnum int purposes) {
+ int[] result = getSetFlags(purposes);
+ for (int i = 0; i < result.length; i++) {
+ result[i] = toKeymaster(result[i]);
+ }
+ return result;
+ }
+
+ /**
+ * @hide
+ */
+ public static @PurposeEnum int allFromKeymaster(Collection<Integer> purposes) {
+ @PurposeEnum int result = 0;
+ for (int keymasterPurpose : purposes) {
+ result |= fromKeymaster(keymasterPurpose);
+ }
+ return result;
+ }
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true,
+ value = {UserAuthenticator.LOCK_SCREEN, UserAuthenticator.FINGERPRINT_READER})
+ public @interface UserAuthenticatorEnum {}
+
+ /**
+ * User authenticators which can be used to restrict/protect access to keys.
+ */
+ public static abstract class UserAuthenticator {
+ private UserAuthenticator() {}
+
+ /** Lock screen. */
+ public static final int LOCK_SCREEN = 1 << 0;
+
+ /** Fingerprint reader/sensor. */
+ public static final int FINGERPRINT_READER = 1 << 1;
+
+ /**
+ * @hide
+ */
+ public static int toKeymaster(@UserAuthenticatorEnum int userAuthenticator) {
+ switch (userAuthenticator) {
+ case LOCK_SCREEN:
+ return KeymasterDefs.HW_AUTH_PASSWORD;
+ case FINGERPRINT_READER:
+ return KeymasterDefs.HW_AUTH_FINGERPRINT;
+ default:
+ throw new IllegalArgumentException(
+ "Unknown user authenticator: " + userAuthenticator);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static @UserAuthenticatorEnum int fromKeymaster(int userAuthenticator) {
+ switch (userAuthenticator) {
+ case KeymasterDefs.HW_AUTH_PASSWORD:
+ return LOCK_SCREEN;
+ case KeymasterDefs.HW_AUTH_FINGERPRINT:
+ return FINGERPRINT_READER;
+ default:
+ throw new IllegalArgumentException(
+ "Unknown user authenticator: " + userAuthenticator);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static int allToKeymaster(@UserAuthenticatorEnum int userAuthenticators) {
+ int result = 0;
+ int userAuthenticator = 1;
+ while (userAuthenticators != 0) {
+ if ((userAuthenticators & 1) != 0) {
+ result |= toKeymaster(userAuthenticator);
+ }
+ userAuthenticators >>>= 1;
+ userAuthenticator <<= 1;
+ }
+ return result;
+ }
+
+ /**
+ * @hide
+ */
+ public static @UserAuthenticatorEnum int allFromKeymaster(int userAuthenticators) {
+ @UserAuthenticatorEnum int result = 0;
+ int userAuthenticator = 1;
+ while (userAuthenticators != 0) {
+ if ((userAuthenticators & 1) != 0) {
+ result |= fromKeymaster(userAuthenticator);
+ }
+ userAuthenticators >>>= 1;
+ userAuthenticator <<= 1;
+ }
+ return result;
+ }
+
+ /**
+ * @hide
+ */
+ public static String toString(@UserAuthenticatorEnum int userAuthenticator) {
+ switch (userAuthenticator) {
+ case LOCK_SCREEN:
+ return "LOCK_SCREEN";
+ case FINGERPRINT_READER:
+ return "FINGERPRINT_READER";
+ default:
+ throw new IllegalArgumentException(
+ "Unknown user authenticator: " + userAuthenticator);
+ }
+ }
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({Origin.GENERATED, Origin.IMPORTED})
+ public @interface OriginEnum {}
+
+ /**
+ * Origin of the key.
+ */
+ public static abstract class Origin {
+ private Origin() {}
+
+ /** Key was generated inside AndroidKeyStore. */
+ public static final int GENERATED = 1 << 0;
+
+ /** Key was imported into AndroidKeyStore. */
+ public static final int IMPORTED = 1 << 1;
+
+ /**
+ * @hide
+ */
+ public static @OriginEnum int fromKeymaster(int origin) {
+ switch (origin) {
+ case KeymasterDefs.KM_ORIGIN_HARDWARE:
+ return GENERATED;
+ case KeymasterDefs.KM_ORIGIN_IMPORTED:
+ return IMPORTED;
+ default:
+ throw new IllegalArgumentException("Unknown origin: " + origin);
+ }
+ }
+ }
+
+ private static int[] getSetFlags(int flags) {
+ if (flags == 0) {
+ return EmptyArray.INT;
+ }
+ int result[] = new int[getSetBitCount(flags)];
+ int resultOffset = 0;
+ int flag = 1;
+ while (flags != 0) {
+ if ((flags & 1) != 0) {
+ result[resultOffset] = flag;
+ resultOffset++;
+ }
+ flags >>>= 1;
+ flag <<= 1;
+ }
+ return result;
+ }
+
+ private static int getSetBitCount(int value) {
+ if (value == 0) {
+ return 0;
+ }
+ int result = 0;
+ while (value != 0) {
+ if ((value & 1) != 0) {
+ result++;
+ }
+ value >>>= 1;
+ }
+ return result;
+ }
+}
diff --git a/keystore/java/android/security/KeyStoreKeySpec.java b/keystore/java/android/security/KeyStoreKeySpec.java
index 65bb236..a89e4dd 100644
--- a/keystore/java/android/security/KeyStoreKeySpec.java
+++ b/keystore/java/android/security/KeyStoreKeySpec.java
@@ -22,24 +22,22 @@ import java.util.Date;
/**
* Information about a key from the <a href="{@docRoot}training/articles/keystore.html">Android
* KeyStore</a>.
- *
- * @hide
*/
public class KeyStoreKeySpec implements KeySpec {
private final String mKeystoreAlias;
private final int mKeySize;
private final boolean mTeeBacked;
- private final @KeyStoreKeyCharacteristics.OriginEnum int mOrigin;
+ private final @KeyStoreKeyProperties.OriginEnum int mOrigin;
private final Date mKeyValidityStart;
private final Date mKeyValidityForOriginationEnd;
private final Date mKeyValidityForConsumptionEnd;
- private final @KeyStoreKeyConstraints.PurposeEnum int mPurposes;
- private final @KeyStoreKeyConstraints.AlgorithmEnum int mAlgorithm;
- private final @KeyStoreKeyConstraints.PaddingEnum int mPaddings;
- private final @KeyStoreKeyConstraints.DigestEnum int mDigests;
- private final @KeyStoreKeyConstraints.BlockModeEnum int mBlockModes;
- private final @KeyStoreKeyConstraints.UserAuthenticatorEnum int mUserAuthenticators;
- private final @KeyStoreKeyConstraints.UserAuthenticatorEnum int mTeeEnforcedUserAuthenticators;
+ private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
+ private final String[] mEncryptionPaddings;
+ private final String[] mSignaturePaddings;
+ private final String[] mDigests;
+ private final String[] mBlockModes;
+ private final @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
+ private final @KeyStoreKeyProperties.UserAuthenticatorEnum int mTeeEnforcedUserAuthenticators;
private final int mUserAuthenticationValidityDurationSeconds;
private final boolean mInvalidatedOnNewFingerprintEnrolled;
@@ -48,18 +46,18 @@ public class KeyStoreKeySpec implements KeySpec {
*/
KeyStoreKeySpec(String keystoreKeyAlias,
boolean teeBacked,
- @KeyStoreKeyCharacteristics.OriginEnum int origin,
+ @KeyStoreKeyProperties.OriginEnum int origin,
int keySize,
Date keyValidityStart,
Date keyValidityForOriginationEnd,
Date keyValidityForConsumptionEnd,
- @KeyStoreKeyConstraints.PurposeEnum int purposes,
- @KeyStoreKeyConstraints.AlgorithmEnum int algorithm,
- @KeyStoreKeyConstraints.PaddingEnum int paddings,
- @KeyStoreKeyConstraints.DigestEnum int digests,
- @KeyStoreKeyConstraints.BlockModeEnum int blockModes,
- @KeyStoreKeyConstraints.UserAuthenticatorEnum int userAuthenticators,
- @KeyStoreKeyConstraints.UserAuthenticatorEnum int teeEnforcedUserAuthenticators,
+ @KeyStoreKeyProperties.PurposeEnum int purposes,
+ String[] encryptionPaddings,
+ String[] signaturePaddings,
+ String[] digests,
+ String[] blockModes,
+ @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators,
+ @KeyStoreKeyProperties.UserAuthenticatorEnum int teeEnforcedUserAuthenticators,
int userAuthenticationValidityDurationSeconds,
boolean invalidatedOnNewFingerprintEnrolled) {
mKeystoreAlias = keystoreKeyAlias;
@@ -70,10 +68,12 @@ public class KeyStoreKeySpec implements KeySpec {
mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
mPurposes = purposes;
- mAlgorithm = algorithm;
- mPaddings = paddings;
- mDigests = digests;
- mBlockModes = blockModes;
+ mEncryptionPaddings =
+ ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
+ mSignaturePaddings =
+ ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
+ mDigests = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(digests));
+ mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
mUserAuthenticators = userAuthenticators;
mTeeEnforcedUserAuthenticators = teeEnforcedUserAuthenticators;
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
@@ -98,7 +98,7 @@ public class KeyStoreKeySpec implements KeySpec {
/**
* Gets the origin of the key.
*/
- public @KeyStoreKeyCharacteristics.OriginEnum int getOrigin() {
+ public @KeyStoreKeyProperties.OriginEnum int getOrigin() {
return mOrigin;
}
@@ -139,36 +139,36 @@ public class KeyStoreKeySpec implements KeySpec {
/**
* Gets the set of purposes for which the key can be used.
*/
- public @KeyStoreKeyConstraints.PurposeEnum int getPurposes() {
+ public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
return mPurposes;
}
/**
- * Gets the algorithm of the key.
+ * Gets the set of block modes with which the key can be used.
*/
- public @KeyStoreKeyConstraints.AlgorithmEnum int getAlgorithm() {
- return mAlgorithm;
+ public String[] getBlockModes() {
+ return ArrayUtils.cloneIfNotEmpty(mBlockModes);
}
/**
- * Gets the set of block modes with which the key can be used.
+ * Gets the set of padding modes with which the key can be used when encrypting/decrypting.
*/
- public @KeyStoreKeyConstraints.BlockModeEnum int getBlockModes() {
- return mBlockModes;
+ public String[] getEncryptionPaddings() {
+ return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
}
/**
- * Gets the set of padding modes with which the key can be used.
+ * Gets the set of padding modes with which the key can be used when signing/verifying.
*/
- public @KeyStoreKeyConstraints.PaddingEnum int getPaddings() {
- return mPaddings;
+ public String[] getSignaturePaddings() {
+ return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
}
/**
* Gets the set of digest algorithms with which the key can be used.
*/
- public @KeyStoreKeyConstraints.DigestEnum int getDigests() {
- return mDigests;
+ public String[] getDigests() {
+ return ArrayUtils.cloneIfNotEmpty(mDigests);
}
/**
@@ -177,7 +177,7 @@ public class KeyStoreKeySpec implements KeySpec {
*
* @return user authenticators or {@code 0} if the key can be used without user authentication.
*/
- public @KeyStoreKeyConstraints.UserAuthenticatorEnum int getUserAuthenticators() {
+ public @KeyStoreKeyProperties.UserAuthenticatorEnum int getUserAuthenticators() {
return mUserAuthenticators;
}
@@ -186,7 +186,7 @@ public class KeyStoreKeySpec implements KeySpec {
* key. This is a subset of the user authentications returned by
* {@link #getUserAuthenticators()}.
*/
- public @KeyStoreKeyConstraints.UserAuthenticatorEnum int getTeeEnforcedUserAuthenticators() {
+ public @KeyStoreKeyProperties.UserAuthenticatorEnum int getTeeEnforcedUserAuthenticators() {
return mTeeEnforcedUserAuthenticators;
}
diff --git a/keystore/java/android/security/KeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java
index 751eef5..c24b74f 100644
--- a/keystore/java/android/security/KeyStoreParameter.java
+++ b/keystore/java/android/security/KeyStoreParameter.java
@@ -43,12 +43,13 @@ public final class KeyStoreParameter implements ProtectionParameter {
private final Date mKeyValidityStart;
private final Date mKeyValidityForOriginationEnd;
private final Date mKeyValidityForConsumptionEnd;
- private final @KeyStoreKeyConstraints.PurposeEnum int mPurposes;
- private final @KeyStoreKeyConstraints.PaddingEnum int mPaddings;
- private final @KeyStoreKeyConstraints.DigestEnum Integer mDigests;
- private final @KeyStoreKeyConstraints.BlockModeEnum int mBlockModes;
+ private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
+ private final String[] mEncryptionPaddings;
+ private final String[] mSignaturePaddings;
+ private final String[] mDigests;
+ private final String[] mBlockModes;
private final boolean mRandomizedEncryptionRequired;
- private final @KeyStoreKeyConstraints.UserAuthenticatorEnum int mUserAuthenticators;
+ private final @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
private final int mUserAuthenticationValidityDurationSeconds;
private final boolean mInvalidatedOnNewFingerprintEnrolled;
@@ -56,12 +57,13 @@ public final class KeyStoreParameter implements ProtectionParameter {
Date keyValidityStart,
Date keyValidityForOriginationEnd,
Date keyValidityForConsumptionEnd,
- @KeyStoreKeyConstraints.PurposeEnum int purposes,
- @KeyStoreKeyConstraints.PaddingEnum int paddings,
- @KeyStoreKeyConstraints.DigestEnum Integer digests,
- @KeyStoreKeyConstraints.BlockModeEnum int blockModes,
+ @KeyStoreKeyProperties.PurposeEnum int purposes,
+ String[] encryptionPaddings,
+ String[] signaturePaddings,
+ String[] digests,
+ String[] blockModes,
boolean randomizedEncryptionRequired,
- @KeyStoreKeyConstraints.UserAuthenticatorEnum int userAuthenticators,
+ @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators,
int userAuthenticationValidityDurationSeconds,
boolean invalidatedOnNewFingerprintEnrolled) {
if ((userAuthenticationValidityDurationSeconds < 0)
@@ -75,9 +77,12 @@ public final class KeyStoreParameter implements ProtectionParameter {
mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
mPurposes = purposes;
- mPaddings = paddings;
- mDigests = digests;
- mBlockModes = blockModes;
+ mEncryptionPaddings =
+ ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
+ mSignaturePaddings =
+ ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
+ mDigests = ArrayUtils.cloneIfNotEmpty(digests);
+ mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
mRandomizedEncryptionRequired = randomizedEncryptionRequired;
mUserAuthenticators = userAuthenticators;
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
@@ -103,7 +108,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* Gets the time instant before which the key is not yet valid.
*
* @return instant or {@code null} if not restricted.
- * @hide
*/
public Date getKeyValidityStart() {
return mKeyValidityStart;
@@ -113,8 +117,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* Gets the time instant after which the key is no long valid for decryption and verification.
*
* @return instant or {@code null} if not restricted.
- *
- * @hide
*/
public Date getKeyValidityForConsumptionEnd() {
return mKeyValidityForConsumptionEnd;
@@ -124,8 +126,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* Gets the time instant after which the key is no long valid for encryption and signing.
*
* @return instant or {@code null} if not restricted.
- *
- * @hide
*/
public Date getKeyValidityForOriginationEnd() {
return mKeyValidityForOriginationEnd;
@@ -133,56 +133,55 @@ public final class KeyStoreParameter implements ProtectionParameter {
/**
* Gets the set of purposes for which the key can be used.
- *
- * @hide
*/
- public @KeyStoreKeyConstraints.PurposeEnum int getPurposes() {
+ public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
return mPurposes;
}
/**
- * Gets the set of padding schemes to which the key is restricted.
- *
- * @hide
+ * Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
+ */
+ public String[] getEncryptionPaddings() {
+ return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
+ }
+
+ /**
+ * Gets the set of padding schemes with which the key can be used when signing or verifying
+ * signatures.
*/
- public @KeyStoreKeyConstraints.PaddingEnum int getPaddings() {
- return mPaddings;
+ public String[] getSignaturePaddings() {
+ return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
}
/**
- * Gets the set of digests to which the key is restricted.
+ * Gets the set of digest algorithms with which the key can be used.
*
- * @throws IllegalStateException if this restriction has not been specified.
+ * @throws IllegalStateException if this set has not been specified.
*
* @see #isDigestsSpecified()
- *
- * @hide
*/
- public @KeyStoreKeyConstraints.DigestEnum int getDigests() {
+ public String[] getDigests() {
if (mDigests == null) {
throw new IllegalStateException("Digests not specified");
}
- return mDigests;
+ return ArrayUtils.cloneIfNotEmpty(mDigests);
}
/**
- * Returns {@code true} if digest restrictions have been specified.
+ * Returns {@code true} if the set of digest algorithms with which the key can be used has been
+ * specified.
*
* @see #getDigests()
- *
- * @hide
*/
public boolean isDigestsSpecified() {
return mDigests != null;
}
/**
- * Gets the set of block modes to which the key is restricted.
- *
- * @hide
+ * Gets the set of block modes with which the key can be used.
*/
- public @KeyStoreKeyConstraints.BlockModeEnum int getBlockModes() {
- return mBlockModes;
+ public String[] getBlockModes() {
+ return ArrayUtils.cloneIfNotEmpty(mBlockModes);
}
/**
@@ -193,8 +192,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* weaknesses due to which ciphertext may leak information about plaintext. For example, if a
* given plaintext always produces the same ciphertext, an attacker may see the repeated
* ciphertexts and be able to deduce something about the plaintext.
- *
- * @hide
*/
public boolean isRandomizedEncryptionRequired() {
return mRandomizedEncryptionRequired;
@@ -205,10 +202,8 @@ public final class KeyStoreParameter implements ProtectionParameter {
* used iff the user has authenticated to at least one of these user authenticators.
*
* @return user authenticators or {@code 0} if the key can be used without user authentication.
- *
- * @hide
*/
- public @KeyStoreKeyConstraints.UserAuthenticatorEnum int getUserAuthenticators() {
+ public @KeyStoreKeyProperties.UserAuthenticatorEnum int getUserAuthenticators() {
return mUserAuthenticators;
}
@@ -218,8 +213,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
*
* @return duration in seconds or {@code -1} if not restricted. {@code 0} means authentication
* is required for every use of the key.
- *
- * @hide
*/
public int getUserAuthenticationValidityDurationSeconds() {
return mUserAuthenticationValidityDurationSeconds;
@@ -231,8 +224,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* authenticators protecting access to this key.
*
* @see #getUserAuthenticators()
- *
- * @hide
*/
public boolean isInvalidatedOnNewFingerprintEnrolled() {
return mInvalidatedOnNewFingerprintEnrolled;
@@ -260,12 +251,13 @@ public final class KeyStoreParameter implements ProtectionParameter {
private Date mKeyValidityStart;
private Date mKeyValidityForOriginationEnd;
private Date mKeyValidityForConsumptionEnd;
- private @KeyStoreKeyConstraints.PurposeEnum int mPurposes;
- private @KeyStoreKeyConstraints.PaddingEnum int mPaddings;
- private @KeyStoreKeyConstraints.DigestEnum Integer mDigests;
- private @KeyStoreKeyConstraints.BlockModeEnum int mBlockModes;
+ private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
+ private String[] mEncryptionPaddings;
+ private String[] mSignaturePaddings;
+ private String[] mDigests;
+ private String[] mBlockModes;
private boolean mRandomizedEncryptionRequired = true;
- private @KeyStoreKeyConstraints.UserAuthenticatorEnum int mUserAuthenticators;
+ private @KeyStoreKeyProperties.UserAuthenticatorEnum int mUserAuthenticators;
private int mUserAuthenticationValidityDurationSeconds = -1;
private boolean mInvalidatedOnNewFingerprintEnrolled;
@@ -304,8 +296,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* <p>By default, the key is valid at any instant.
*
* @see #setKeyValidityEnd(Date)
- *
- * @hide
*/
public Builder setKeyValidityStart(Date startDate) {
mKeyValidityStart = startDate;
@@ -320,8 +310,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* @see #setKeyValidityStart(Date)
* @see #setKeyValidityForConsumptionEnd(Date)
* @see #setKeyValidityForOriginationEnd(Date)
- *
- * @hide
*/
public Builder setKeyValidityEnd(Date endDate) {
setKeyValidityForOriginationEnd(endDate);
@@ -335,8 +323,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* <p>By default, the key is valid at any instant.
*
* @see #setKeyValidityForConsumptionEnd(Date)
- *
- * @hide
*/
public Builder setKeyValidityForOriginationEnd(Date endDate) {
mKeyValidityForOriginationEnd = endDate;
@@ -350,8 +336,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* <p>By default, the key is valid at any instant.
*
* @see #setKeyValidityForOriginationEnd(Date)
- *
- * @hide
*/
public Builder setKeyValidityForConsumptionEnd(Date endDate) {
mKeyValidityForConsumptionEnd = endDate;
@@ -359,55 +343,60 @@ public final class KeyStoreParameter implements ProtectionParameter {
}
/**
- * Restricts the key to being used only for the provided set of purposes.
+ * Sets the set of purposes for which the key can be used.
*
- * <p>This restriction must be specified. There is no default.
- *
- * @hide
+ * <p>This must be specified for all keys. There is no default.
*/
- public Builder setPurposes(@KeyStoreKeyConstraints.PurposeEnum int purposes) {
+ public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) {
mPurposes = purposes;
return this;
}
/**
- * Restricts the key to being used only with the provided padding schemes. Attempts to use
- * the key with any other padding will be rejected.
- *
- * <p>This restriction must be specified for keys which are used for encryption/decryption.
+ * Sets the set of padding schemes with which the key can be used when
+ * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
+ * rejected.
*
- * @hide
+ * <p>This must be specified for keys which are used for encryption/decryption.
*/
- public Builder setPaddings(@KeyStoreKeyConstraints.PaddingEnum int paddings) {
- mPaddings = paddings;
+ public Builder setEncryptionPaddings(String... paddings) {
+ mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
return this;
}
/**
- * Restricts the key to being used only with the provided digests when generating signatures
- * or HMACs. Attempts to use the key with any other digest will be rejected.
+ * Sets the set of padding schemes with which the key can be used when
+ * signing/verifying. Attempts to use the key with any other padding scheme will be
+ * rejected.
*
- * <p>For HMAC keys, the default is to restrict to the digest specified in
- * {@link Key#getAlgorithm()}. For asymmetric signing keys this constraint must be specified
- * because there is no default.
- *
- * @hide
+ * <p>This must be specified for RSA keys which are used for signing/verification.
*/
- public Builder setDigests(@KeyStoreKeyConstraints.DigestEnum int digests) {
- mDigests = digests;
+ public Builder setSignaturePaddings(String... paddings) {
+ mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
return this;
}
+
/**
- * Restricts the key to being used only with the provided block modes. Attempts to use the
- * key with any other block modes will be rejected.
+ * Sets the set of digests with which the key can be used when signing/verifying or
+ * generating MACs. Attempts to use the key with any other digest will be rejected.
*
- * <p>This restriction must be specified for symmetric encryption/decryption keys.
+ * <p>For HMAC keys, the default is the digest specified in {@link Key#getAlgorithm()}. For
+ * asymmetric signing keys this constraint must be specified.
+ */
+ public Builder setDigests(String... digests) {
+ mDigests = ArrayUtils.cloneIfNotEmpty(digests);
+ return this;
+ }
+
+ /**
+ * Sets the set of block modes with which the key can be used when encrypting/decrypting.
+ * Attempts to use the key with any other block modes will be rejected.
*
- * @hide
+ * <p>This must be specified for encryption/decryption keys.
*/
- public Builder setBlockModes(@KeyStoreKeyConstraints.BlockModeEnum int blockModes) {
- mBlockModes = blockModes;
+ public Builder setBlockModes(String... blockModes) {
+ mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
return this;
}
@@ -444,8 +433,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* <li>If you are using RSA encryption without padding, consider switching to padding
* schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li>
* </ul>
- *
- * @hide
*/
public Builder setRandomizedEncryptionRequired(boolean required) {
mRandomizedEncryptionRequired = required;
@@ -462,11 +449,9 @@ public final class KeyStoreParameter implements ProtectionParameter {
* without user authentication.
*
* @see #setUserAuthenticationValidityDurationSeconds(int)
- *
- * @hide
*/
public Builder setUserAuthenticators(
- @KeyStoreKeyConstraints.UserAuthenticatorEnum int userAuthenticators) {
+ @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators) {
mUserAuthenticators = userAuthenticators;
return this;
}
@@ -481,8 +466,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* every use of the key.
*
* @see #setUserAuthenticators(int)
- *
- * @hide
*/
public Builder setUserAuthenticationValidityDurationSeconds(int seconds) {
mUserAuthenticationValidityDurationSeconds = seconds;
@@ -497,8 +480,6 @@ public final class KeyStoreParameter implements ProtectionParameter {
* <p>By default, enrolling a new fingerprint does not invalidate the key.
*
* @see #setUserAuthenticators(Set)
- *
- * @hide
*/
public Builder setInvalidatedOnNewFingerprintEnrolled(boolean invalidated) {
mInvalidatedOnNewFingerprintEnrolled = invalidated;
@@ -517,7 +498,8 @@ public final class KeyStoreParameter implements ProtectionParameter {
mKeyValidityForOriginationEnd,
mKeyValidityForConsumptionEnd,
mPurposes,
- mPaddings,
+ mEncryptionPaddings,
+ mSignaturePaddings,
mDigests,
mBlockModes,
mRandomizedEncryptionRequired,
diff --git a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
index a5e87d1..4be0638 100644
--- a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
+++ b/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
@@ -19,10 +19,14 @@ package android.security;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterDefs;
+import libcore.util.EmptyArray;
+
import java.security.InvalidKeyException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactorySpi;
@@ -71,84 +75,90 @@ public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
}
boolean teeBacked;
- @KeyStoreKeyCharacteristics.OriginEnum int origin;
+ @KeyStoreKeyProperties.OriginEnum int origin;
int keySize;
- @KeyStoreKeyConstraints.PurposeEnum int purposes;
- @KeyStoreKeyConstraints.AlgorithmEnum int algorithm;
- @KeyStoreKeyConstraints.PaddingEnum int paddings;
- @KeyStoreKeyConstraints.DigestEnum int digests;
- @KeyStoreKeyConstraints.BlockModeEnum int blockModes;
- @KeyStoreKeyConstraints.UserAuthenticatorEnum int userAuthenticators;
- @KeyStoreKeyConstraints.UserAuthenticatorEnum int teeEnforcedUserAuthenticators;
+ @KeyStoreKeyProperties.PurposeEnum int purposes;
+ String[] encryptionPaddings;
+ String[] digests;
+ String[] blockModes;
+ @KeyStoreKeyProperties.UserAuthenticatorEnum int userAuthenticators;
+ @KeyStoreKeyProperties.UserAuthenticatorEnum int teeEnforcedUserAuthenticators;
try {
if (keyCharacteristics.hwEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
teeBacked = true;
- origin = KeyStoreKeyCharacteristics.Origin.fromKeymaster(
+ origin = KeyStoreKeyProperties.Origin.fromKeymaster(
keyCharacteristics.hwEnforced.getInt(KeymasterDefs.KM_TAG_ORIGIN, -1));
} else if (keyCharacteristics.swEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
teeBacked = false;
- origin = KeyStoreKeyCharacteristics.Origin.fromKeymaster(
+ origin = KeyStoreKeyProperties.Origin.fromKeymaster(
keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_ORIGIN, -1));
} else {
throw new InvalidKeySpecException("Key origin not available");
}
- Integer keySizeInteger =
- KeymasterUtils.getInt(keyCharacteristics, KeymasterDefs.KM_TAG_KEY_SIZE);
+ Integer keySizeInteger = keyCharacteristics.getInteger(KeymasterDefs.KM_TAG_KEY_SIZE);
if (keySizeInteger == null) {
throw new InvalidKeySpecException("Key size not available");
}
keySize = keySizeInteger;
- purposes = KeyStoreKeyConstraints.Purpose.allFromKeymaster(
- KeymasterUtils.getInts(keyCharacteristics, KeymasterDefs.KM_TAG_PURPOSE));
- Integer alg = KeymasterUtils.getInt(keyCharacteristics, KeymasterDefs.KM_TAG_ALGORITHM);
- if (alg == null) {
- throw new InvalidKeySpecException("Key algorithm not available");
+ purposes = KeyStoreKeyProperties.Purpose.allFromKeymaster(
+ keyCharacteristics.getInts(KeymasterDefs.KM_TAG_PURPOSE));
+
+ List<String> encryptionPaddingsList = new ArrayList<String>();
+ for (int keymasterPadding : keyCharacteristics.getInts(KeymasterDefs.KM_TAG_PADDING)) {
+ String jcaPadding;
+ try {
+ jcaPadding = KeymasterUtils.getJcaEncryptionPaddingFromKeymasterPadding(
+ keymasterPadding);
+ } catch (IllegalArgumentException e) {
+ throw new InvalidKeySpecException(
+ "Unsupported encryption padding: " + keymasterPadding);
+ }
+ encryptionPaddingsList.add(jcaPadding);
}
- algorithm = KeyStoreKeyConstraints.Algorithm.fromKeymaster(alg);
- paddings = KeyStoreKeyConstraints.Padding.allFromKeymaster(
- KeymasterUtils.getInts(keyCharacteristics, KeymasterDefs.KM_TAG_PADDING));
- digests = KeyStoreKeyConstraints.Digest.allFromKeymaster(
- KeymasterUtils.getInts(keyCharacteristics, KeymasterDefs.KM_TAG_DIGEST));
- blockModes = KeyStoreKeyConstraints.BlockMode.allFromKeymaster(
- KeymasterUtils.getInts(keyCharacteristics, KeymasterDefs.KM_TAG_BLOCK_MODE));
-
- @KeyStoreKeyConstraints.UserAuthenticatorEnum
+ encryptionPaddings =
+ encryptionPaddingsList.toArray(new String[encryptionPaddingsList.size()]);
+
+ digests = KeymasterUtils.getJcaDigestAlgorithmsFromKeymasterDigests(
+ keyCharacteristics.getInts(KeymasterDefs.KM_TAG_DIGEST));
+ blockModes = KeymasterUtils.getJcaBlockModesFromKeymasterBlockModes(
+ keyCharacteristics.getInts(KeymasterDefs.KM_TAG_BLOCK_MODE));
+
+ @KeyStoreKeyProperties.UserAuthenticatorEnum
int swEnforcedKeymasterUserAuthenticators =
keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
- @KeyStoreKeyConstraints.UserAuthenticatorEnum
+ @KeyStoreKeyProperties.UserAuthenticatorEnum
int hwEnforcedKeymasterUserAuthenticators =
keyCharacteristics.hwEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
- @KeyStoreKeyConstraints.UserAuthenticatorEnum
+ @KeyStoreKeyProperties.UserAuthenticatorEnum
int keymasterUserAuthenticators =
swEnforcedKeymasterUserAuthenticators | hwEnforcedKeymasterUserAuthenticators;
- userAuthenticators = KeyStoreKeyConstraints.UserAuthenticator.allFromKeymaster(
+ userAuthenticators = KeyStoreKeyProperties.UserAuthenticator.allFromKeymaster(
keymasterUserAuthenticators);
teeEnforcedUserAuthenticators =
- KeyStoreKeyConstraints.UserAuthenticator.allFromKeymaster(
+ KeyStoreKeyProperties.UserAuthenticator.allFromKeymaster(
hwEnforcedKeymasterUserAuthenticators);
} catch (IllegalArgumentException e) {
throw new InvalidKeySpecException("Unsupported key characteristic", e);
}
- Date keyValidityStart =
- KeymasterUtils.getDate(keyCharacteristics, KeymasterDefs.KM_TAG_ACTIVE_DATETIME);
+ Date keyValidityStart = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME);
if ((keyValidityStart != null) && (keyValidityStart.getTime() <= 0)) {
keyValidityStart = null;
}
- Date keyValidityForOriginationEnd = KeymasterUtils.getDate(keyCharacteristics,
- KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME);
+ Date keyValidityForOriginationEnd =
+ keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME);
if ((keyValidityForOriginationEnd != null)
&& (keyValidityForOriginationEnd.getTime() == Long.MAX_VALUE)) {
keyValidityForOriginationEnd = null;
}
- Date keyValidityForConsumptionEnd = KeymasterUtils.getDate(keyCharacteristics,
- KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME);
+ Date keyValidityForConsumptionEnd =
+ keyCharacteristics.getDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME);
if ((keyValidityForConsumptionEnd != null)
&& (keyValidityForConsumptionEnd.getTime() == Long.MAX_VALUE)) {
keyValidityForConsumptionEnd = null;
}
- Integer userAuthenticationValidityDurationSeconds =
- KeymasterUtils.getInt(keyCharacteristics, KeymasterDefs.KM_TAG_AUTH_TIMEOUT);
+ int userAuthenticationValidityDurationSeconds =
+ keyCharacteristics.getInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, -1);
// TODO: Populate the value below from key characteristics once Keymaster is ready.
boolean invalidatedOnNewFingerprintEnrolled = false;
@@ -161,14 +171,13 @@ public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
keyValidityForOriginationEnd,
keyValidityForConsumptionEnd,
purposes,
- algorithm,
- paddings,
+ encryptionPaddings,
+ EmptyArray.STRING, // no signature paddings -- this is symmetric crypto
digests,
blockModes,
userAuthenticators,
teeEnforcedUserAuthenticators,
- ((userAuthenticationValidityDurationSeconds != null)
- ? userAuthenticationValidityDurationSeconds : -1),
+ userAuthenticationValidityDurationSeconds,
invalidatedOnNewFingerprintEnrolled);
}
diff --git a/keystore/java/android/security/KeymasterUtils.java b/keystore/java/android/security/KeymasterUtils.java
index 3143d4d..67f75c2 100644
--- a/keystore/java/android/security/KeymasterUtils.java
+++ b/keystore/java/android/security/KeymasterUtils.java
@@ -16,48 +16,327 @@
package android.security;
-import android.security.keymaster.KeyCharacteristics;
+import android.security.keymaster.KeymasterDefs;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import libcore.util.EmptyArray;
+
+import java.util.Collection;
+import java.util.Locale;
/**
* @hide
*/
public abstract class KeymasterUtils {
+
private KeymasterUtils() {}
- public static Integer getInt(KeyCharacteristics keyCharacteristics, int tag) {
- if (keyCharacteristics.hwEnforced.containsTag(tag)) {
- return keyCharacteristics.hwEnforced.getInt(tag, -1);
- } else if (keyCharacteristics.swEnforced.containsTag(tag)) {
- return keyCharacteristics.swEnforced.getInt(tag, -1);
+ public static int getKeymasterAlgorithmFromJcaSecretKeyAlgorithm(String jcaKeyAlgorithm) {
+ if ("AES".equalsIgnoreCase(jcaKeyAlgorithm)) {
+ return KeymasterDefs.KM_ALGORITHM_AES;
+ } else if (jcaKeyAlgorithm.toUpperCase(Locale.US).startsWith("HMAC")) {
+ return KeymasterDefs.KM_ALGORITHM_HMAC;
} else {
- return null;
+ throw new IllegalArgumentException(
+ "Unsupported secret key algorithm: " + jcaKeyAlgorithm);
+ }
+ }
+
+ public static String getJcaSecretKeyAlgorithm(int keymasterAlgorithm, int keymasterDigest) {
+ switch (keymasterAlgorithm) {
+ case KeymasterDefs.KM_ALGORITHM_AES:
+ if (keymasterDigest != -1) {
+ throw new IllegalArgumentException(
+ "Digest not supported for AES key: " + keymasterDigest);
+ }
+ return "AES";
+ case KeymasterDefs.KM_ALGORITHM_HMAC:
+ switch (keymasterDigest) {
+ case KeymasterDefs.KM_DIGEST_SHA1:
+ return "HmacSHA1";
+ case KeymasterDefs.KM_DIGEST_SHA_2_224:
+ return "HmacSHA224";
+ case KeymasterDefs.KM_DIGEST_SHA_2_256:
+ return "HmacSHA256";
+ case KeymasterDefs.KM_DIGEST_SHA_2_384:
+ return "HmacSHA384";
+ case KeymasterDefs.KM_DIGEST_SHA_2_512:
+ return "HmacSHA512";
+ default:
+ throw new IllegalArgumentException(
+ "Unsupported HMAC digest: " + keymasterDigest);
+ }
+ default:
+ throw new IllegalArgumentException("Unsupported algorithm: " + keymasterAlgorithm);
}
}
- public static List<Integer> getInts(KeyCharacteristics keyCharacteristics, int tag) {
- List<Integer> result = new ArrayList<Integer>();
- result.addAll(keyCharacteristics.hwEnforced.getInts(tag));
- result.addAll(keyCharacteristics.swEnforced.getInts(tag));
+ public static String getJcaKeyPairAlgorithmFromKeymasterAlgorithm(int keymasterAlgorithm) {
+ switch (keymasterAlgorithm) {
+ case KeymasterDefs.KM_ALGORITHM_RSA:
+ return "RSA";
+ case KeymasterDefs.KM_ALGORITHM_EC:
+ return "EC";
+ default:
+ throw new IllegalArgumentException("Unsupported algorithm: " + keymasterAlgorithm);
+ }
+ }
+
+ public static int getKeymasterDigestfromJcaSecretKeyAlgorithm(String jcaKeyAlgorithm) {
+ String algorithmUpper = jcaKeyAlgorithm.toUpperCase(Locale.US);
+ if (algorithmUpper.startsWith("HMAC")) {
+ String digestUpper = algorithmUpper.substring("HMAC".length());
+ switch (digestUpper) {
+ case "MD5":
+ return KeymasterDefs.KM_DIGEST_MD5;
+ case "SHA1":
+ return KeymasterDefs.KM_DIGEST_SHA1;
+ case "SHA224":
+ return KeymasterDefs.KM_DIGEST_SHA_2_224;
+ case "SHA256":
+ return KeymasterDefs.KM_DIGEST_SHA_2_256;
+ case "SHA384":
+ return KeymasterDefs.KM_DIGEST_SHA_2_384;
+ case "SHA512":
+ return KeymasterDefs.KM_DIGEST_SHA_2_512;
+ default:
+ throw new IllegalArgumentException("Unsupported HMAC digest: " + digestUpper);
+ }
+ } else {
+ return -1;
+ }
+ }
+
+ public static int getKeymasterDigestFromJcaDigestAlgorithm(String jcaDigestAlgorithm) {
+ if (jcaDigestAlgorithm.equalsIgnoreCase("SHA-1")) {
+ return KeymasterDefs.KM_DIGEST_SHA1;
+ } else if (jcaDigestAlgorithm.equalsIgnoreCase("SHA-224")) {
+ return KeymasterDefs.KM_DIGEST_SHA_2_224;
+ } else if (jcaDigestAlgorithm.equalsIgnoreCase("SHA-256")) {
+ return KeymasterDefs.KM_DIGEST_SHA_2_256;
+ } else if (jcaDigestAlgorithm.equalsIgnoreCase("SHA-384")) {
+ return KeymasterDefs.KM_DIGEST_SHA_2_384;
+ } else if (jcaDigestAlgorithm.equalsIgnoreCase("SHA-512")) {
+ return KeymasterDefs.KM_DIGEST_SHA_2_512;
+ } else if (jcaDigestAlgorithm.equalsIgnoreCase("NONE")) {
+ return KeymasterDefs.KM_DIGEST_NONE;
+ } else if (jcaDigestAlgorithm.equalsIgnoreCase("MD5")) {
+ return KeymasterDefs.KM_DIGEST_MD5;
+ } else {
+ throw new IllegalArgumentException(
+ "Unsupported digest algorithm: " + jcaDigestAlgorithm);
+ }
+ }
+
+ public static String getJcaDigestAlgorithmFromKeymasterDigest(int keymasterDigest) {
+ switch (keymasterDigest) {
+ case KeymasterDefs.KM_DIGEST_NONE:
+ return "NONE";
+ case KeymasterDefs.KM_DIGEST_MD5:
+ return "MD5";
+ case KeymasterDefs.KM_DIGEST_SHA1:
+ return "SHA-1";
+ case KeymasterDefs.KM_DIGEST_SHA_2_224:
+ return "SHA-224";
+ case KeymasterDefs.KM_DIGEST_SHA_2_256:
+ return "SHA-256";
+ case KeymasterDefs.KM_DIGEST_SHA_2_384:
+ return "SHA-384";
+ case KeymasterDefs.KM_DIGEST_SHA_2_512:
+ return "SHA-512";
+ default:
+ throw new IllegalArgumentException(
+ "Unsupported digest algorithm: " + keymasterDigest);
+ }
+ }
+
+ public static String[] getJcaDigestAlgorithmsFromKeymasterDigests(
+ Collection<Integer> keymasterDigests) {
+ if (keymasterDigests.isEmpty()) {
+ return EmptyArray.STRING;
+ }
+ String[] result = new String[keymasterDigests.size()];
+ int offset = 0;
+ for (int keymasterDigest : keymasterDigests) {
+ result[offset] = getJcaDigestAlgorithmFromKeymasterDigest(keymasterDigest);
+ offset++;
+ }
return result;
}
- public static Date getDate(KeyCharacteristics keyCharacteristics, int tag) {
- Date result = keyCharacteristics.hwEnforced.getDate(tag, null);
- if (result == null) {
- result = keyCharacteristics.swEnforced.getDate(tag, null);
+ public static int[] getKeymasterDigestsFromJcaDigestAlgorithms(String[] jcaDigestAlgorithms) {
+ if ((jcaDigestAlgorithms == null) || (jcaDigestAlgorithms.length == 0)) {
+ return EmptyArray.INT;
+ }
+ int[] result = new int[jcaDigestAlgorithms.length];
+ int offset = 0;
+ for (String jcaDigestAlgorithm : jcaDigestAlgorithms) {
+ result[offset] = getKeymasterDigestFromJcaDigestAlgorithm(jcaDigestAlgorithm);
+ offset++;
}
return result;
}
- public static boolean getBoolean(KeyCharacteristics keyCharacteristics, int tag) {
- if (keyCharacteristics.hwEnforced.containsTag(tag)) {
- return keyCharacteristics.hwEnforced.getBoolean(tag, false);
+ public static int getDigestOutputSizeBytes(int keymasterDigest) {
+ switch (keymasterDigest) {
+ case KeymasterDefs.KM_DIGEST_NONE:
+ return -1;
+ case KeymasterDefs.KM_DIGEST_MD5:
+ return 128 / 8;
+ case KeymasterDefs.KM_DIGEST_SHA1:
+ return 160 / 8;
+ case KeymasterDefs.KM_DIGEST_SHA_2_224:
+ return 224 / 8;
+ case KeymasterDefs.KM_DIGEST_SHA_2_256:
+ return 256 / 8;
+ case KeymasterDefs.KM_DIGEST_SHA_2_384:
+ return 384 / 8;
+ case KeymasterDefs.KM_DIGEST_SHA_2_512:
+ return 512 / 8;
+ default:
+ throw new IllegalArgumentException("Unknown digest: " + keymasterDigest);
+ }
+ }
+
+ public static int getKeymasterBlockModeFromJcaBlockMode(String jcaBlockMode) {
+ if ("ECB".equalsIgnoreCase(jcaBlockMode)) {
+ return KeymasterDefs.KM_MODE_ECB;
+ } else if ("CBC".equalsIgnoreCase(jcaBlockMode)) {
+ return KeymasterDefs.KM_MODE_CBC;
+ } else if ("CTR".equalsIgnoreCase(jcaBlockMode)) {
+ return KeymasterDefs.KM_MODE_CTR;
+ } else if ("GCM".equalsIgnoreCase(jcaBlockMode)) {
+ return KeymasterDefs.KM_MODE_GCM;
} else {
- return keyCharacteristics.swEnforced.getBoolean(tag, false);
+ throw new IllegalArgumentException("Unsupported block mode: " + jcaBlockMode);
}
}
+
+ public static String getJcaBlockModeFromKeymasterBlockMode(int keymasterBlockMode) {
+ switch (keymasterBlockMode) {
+ case KeymasterDefs.KM_MODE_ECB:
+ return "ECB";
+ case KeymasterDefs.KM_MODE_CBC:
+ return "CBC";
+ case KeymasterDefs.KM_MODE_CTR:
+ return "CTR";
+ case KeymasterDefs.KM_MODE_GCM:
+ return "GCM";
+ default:
+ throw new IllegalArgumentException("Unsupported block mode: " + keymasterBlockMode);
+ }
+ }
+
+ public static String[] getJcaBlockModesFromKeymasterBlockModes(
+ Collection<Integer> keymasterBlockModes) {
+ if ((keymasterBlockModes == null) || (keymasterBlockModes.isEmpty())) {
+ return EmptyArray.STRING;
+ }
+ String[] result = new String[keymasterBlockModes.size()];
+ int offset = 0;
+ for (int keymasterBlockMode : keymasterBlockModes) {
+ result[offset] = getJcaBlockModeFromKeymasterBlockMode(keymasterBlockMode);
+ offset++;
+ }
+ return result;
+ }
+
+ public static int[] getKeymasterBlockModesFromJcaBlockModes(String[] jcaBlockModes) {
+ if ((jcaBlockModes == null) || (jcaBlockModes.length == 0)) {
+ return EmptyArray.INT;
+ }
+ int[] result = new int[jcaBlockModes.length];
+ for (int i = 0; i < jcaBlockModes.length; i++) {
+ result[i] = getKeymasterBlockModeFromJcaBlockMode(jcaBlockModes[i]);
+ }
+ return result;
+ }
+
+ public static boolean isKeymasterBlockModeIndCpaCompatible(int keymasterBlockMode) {
+ switch (keymasterBlockMode) {
+ case KeymasterDefs.KM_MODE_ECB:
+ return false;
+ case KeymasterDefs.KM_MODE_CBC:
+ case KeymasterDefs.KM_MODE_CTR:
+ case KeymasterDefs.KM_MODE_GCM:
+ return true;
+ default:
+ throw new IllegalArgumentException("Unsupported block mode: " + keymasterBlockMode);
+ }
+ }
+
+ public static int getKeymasterPaddingFromJcaEncryptionPadding(String jcaPadding) {
+ if ("NoPadding".equalsIgnoreCase(jcaPadding)) {
+ return KeymasterDefs.KM_PAD_NONE;
+ } else if ("PKCS7Padding".equalsIgnoreCase(jcaPadding)) {
+ return KeymasterDefs.KM_PAD_PKCS7;
+ } else if ("PKCS1Padding".equalsIgnoreCase(jcaPadding)) {
+ return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT;
+ } else if ("OEAPPadding".equalsIgnoreCase(jcaPadding)) {
+ return KeymasterDefs.KM_PAD_RSA_OAEP;
+ } else {
+ throw new IllegalArgumentException(
+ "Unsupported encryption padding scheme: " + jcaPadding);
+ }
+ }
+
+ public static String getJcaEncryptionPaddingFromKeymasterPadding(int keymasterPadding) {
+ switch (keymasterPadding) {
+ case KeymasterDefs.KM_PAD_NONE:
+ return "NoPadding";
+ case KeymasterDefs.KM_PAD_PKCS7:
+ return "PKCS7Padding";
+ case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
+ return "PKCS1Padding";
+ case KeymasterDefs.KM_PAD_RSA_OAEP:
+ return "OEAPPadding";
+ default:
+ throw new IllegalArgumentException(
+ "Unsupported encryption padding: " + keymasterPadding);
+ }
+ }
+
+ public static int getKeymasterPaddingFromJcaSignaturePadding(String jcaPadding) {
+ if ("PKCS#1".equalsIgnoreCase(jcaPadding)) {
+ return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN;
+ } if ("PSS".equalsIgnoreCase(jcaPadding)) {
+ return KeymasterDefs.KM_PAD_RSA_PSS;
+ } else {
+ throw new IllegalArgumentException(
+ "Unsupported signature padding scheme: " + jcaPadding);
+ }
+ }
+
+ public static String getJcaSignaturePaddingFromKeymasterPadding(int keymasterPadding) {
+ switch (keymasterPadding) {
+ case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN:
+ return "PKCS#1";
+ case KeymasterDefs.KM_PAD_RSA_PSS:
+ return "PSS";
+ default:
+ throw new IllegalArgumentException(
+ "Unsupported signature padding: " + keymasterPadding);
+ }
+ }
+
+ public static int[] getKeymasterPaddingsFromJcaEncryptionPaddings(String[] jcaPaddings) {
+ if ((jcaPaddings == null) || (jcaPaddings.length == 0)) {
+ return EmptyArray.INT;
+ }
+ int[] result = new int[jcaPaddings.length];
+ for (int i = 0; i < jcaPaddings.length; i++) {
+ result[i] = getKeymasterPaddingFromJcaEncryptionPadding(jcaPaddings[i]);
+ }
+ return result;
+ }
+
+ public static int[] getKeymasterPaddingsFromJcaSignaturePaddings(String[] jcaPaddings) {
+ if ((jcaPaddings == null) || (jcaPaddings.length == 0)) {
+ return EmptyArray.INT;
+ }
+ int[] result = new int[jcaPaddings.length];
+ for (int i = 0; i < jcaPaddings.length; i++) {
+ result[i] = getKeymasterPaddingFromJcaSignaturePadding(jcaPaddings[i]);
+ }
+ return result;
+ }
}
diff --git a/keystore/java/android/security/NewFingerprintEnrolledException.java b/keystore/java/android/security/NewFingerprintEnrolledException.java
index 6da4a2a..806b214 100644
--- a/keystore/java/android/security/NewFingerprintEnrolledException.java
+++ b/keystore/java/android/security/NewFingerprintEnrolledException.java
@@ -19,8 +19,6 @@ package android.security;
/**
* Indicates that a cryptographic operation could not be performed because the key used by the
* operation is permanently invalid because a new fingerprint was enrolled.
- *
- * @hide
*/
public class NewFingerprintEnrolledException extends CryptoOperationException {
diff --git a/keystore/java/android/security/UserNotAuthenticatedException.java b/keystore/java/android/security/UserNotAuthenticatedException.java
index e6342ef..f5f5f41 100644
--- a/keystore/java/android/security/UserNotAuthenticatedException.java
+++ b/keystore/java/android/security/UserNotAuthenticatedException.java
@@ -19,8 +19,6 @@ package android.security;
/**
* Indicates that a cryptographic operation could not be performed because the user has not been
* authenticated recently enough.
- *
- * @hide
*/
public class UserNotAuthenticatedException extends CryptoOperationException {
diff --git a/location/lib/java/com/android/location/provider/FusedLocationHardware.java b/location/lib/java/com/android/location/provider/FusedLocationHardware.java
index bc5a8a1..480a18c 100644
--- a/location/lib/java/com/android/location/provider/FusedLocationHardware.java
+++ b/location/lib/java/com/android/location/provider/FusedLocationHardware.java
@@ -34,7 +34,7 @@ import java.util.Map;
* Class that exposes IFusedLocationHardware functionality to unbundled services.
*/
public final class FusedLocationHardware {
- private final String TAG = "FusedLocationHardware";
+ private static final String TAG = "FusedLocationHardware";
private IFusedLocationHardware mLocationHardware;
@@ -52,6 +52,16 @@ public final class FusedLocationHardware {
public void onDiagnosticDataAvailable(String data) {
dispatchDiagnosticData(data);
}
+
+ @Override
+ public void onCapabilities(int capabilities) {
+ dispatchCapabilities(capabilities);
+ }
+
+ @Override
+ public void onStatusChanged(int status) {
+ dispatchStatus(status);
+ }
};
/**
@@ -164,6 +174,14 @@ public final class FusedLocationHardware {
}
}
+ public void flushBatchedLocations() {
+ try {
+ mLocationHardware.flushBatchedLocations();
+ } catch(RemoteException e) {
+ Log.e(TAG, "RemoteException at flushBatchedLocations");
+ }
+ }
+
public boolean supportsDiagnosticDataInjection() {
try {
return mLocationHardware.supportsDiagnosticDataInjection();
@@ -204,6 +222,8 @@ public final class FusedLocationHardware {
private class DispatcherHandler extends Handler {
public static final int DISPATCH_LOCATION = 1;
public static final int DISPATCH_DIAGNOSTIC_DATA = 2;
+ public static final int DISPATCH_CAPABILITIES = 3;
+ public static final int DISPATCH_STATUS = 4;
public DispatcherHandler(Looper looper) {
super(looper, null /*callback*/ , true /*async*/);
@@ -218,6 +238,13 @@ public final class FusedLocationHardware {
break;
case DISPATCH_DIAGNOSTIC_DATA:
command.dispatchDiagnosticData();
+ break;
+ case DISPATCH_CAPABILITIES:
+ command.dispatchCapabilities();
+ break;
+ case DISPATCH_STATUS:
+ command.dispatchStatus();
+ break;
default:
Log.e(TAG, "Invalid dispatch message");
break;
@@ -229,14 +256,20 @@ public final class FusedLocationHardware {
private final FusedLocationHardwareSink mSink;
private final Location[] mLocations;
private final String mData;
+ private final int mCapabilities;
+ private final int mStatus;
public MessageCommand(
FusedLocationHardwareSink sink,
Location[] locations,
- String data) {
+ String data,
+ int capabilities,
+ int status) {
mSink = sink;
mLocations = locations;
mData = data;
+ mCapabilities = capabilities;
+ mStatus = status;
}
public void dispatchLocation() {
@@ -246,6 +279,14 @@ public final class FusedLocationHardware {
public void dispatchDiagnosticData() {
mSink.onDiagnosticDataAvailable(mData);
}
+
+ public void dispatchCapabilities() {
+ mSink.onCapabilities(mCapabilities);
+ }
+
+ public void dispatchStatus() {
+ mSink.onStatusChanged(mStatus);
+ }
}
private void dispatchLocations(Location[] locations) {
@@ -258,7 +299,7 @@ public final class FusedLocationHardware {
Message message = Message.obtain(
entry.getValue(),
DispatcherHandler.DISPATCH_LOCATION,
- new MessageCommand(entry.getKey(), locations, null /*data*/));
+ new MessageCommand(entry.getKey(), locations, null /*data*/, 0, 0));
message.sendToTarget();
}
}
@@ -273,7 +314,37 @@ public final class FusedLocationHardware {
Message message = Message.obtain(
entry.getValue(),
DispatcherHandler.DISPATCH_DIAGNOSTIC_DATA,
- new MessageCommand(entry.getKey(), null /*locations*/, data));
+ new MessageCommand(entry.getKey(), null /*locations*/, data, 0, 0));
+ message.sendToTarget();
+ }
+ }
+
+ private void dispatchCapabilities(int capabilities) {
+ HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks;
+ synchronized(mSinkList) {
+ sinks = mSinkList;
+ }
+
+ for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) {
+ Message message = Message.obtain(
+ entry.getValue(),
+ DispatcherHandler.DISPATCH_CAPABILITIES,
+ new MessageCommand(entry.getKey(), null /*locations*/, null, capabilities, 0));
+ message.sendToTarget();
+ }
+ }
+
+ private void dispatchStatus(int status) {
+ HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks;
+ synchronized(mSinkList) {
+ sinks = mSinkList;
+ }
+
+ for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) {
+ Message message = Message.obtain(
+ entry.getValue(),
+ DispatcherHandler.DISPATCH_STATUS,
+ new MessageCommand(entry.getKey(), null /*locations*/, null, 0, status));
message.sendToTarget();
}
}
diff --git a/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java b/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java
index 2c39fa8..618d5d6 100644
--- a/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java
+++ b/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java
@@ -20,11 +20,47 @@ import android.location.Location;
/**
* Base class for sinks to interact with FusedLocationHardware.
+ *
+ * <p>Default implementations allow new methods to be added without crashing
+ * clients compiled against an old library version.
*/
-public abstract class FusedLocationHardwareSink {
- /*
- * Methods to provide a facade for IFusedLocationHardware
+public class FusedLocationHardwareSink {
+ /**
+ * Called when one or more locations are available from the FLP
+ * HAL.
+ */
+ public void onLocationAvailable(Location[] locations) {
+ // default do nothing
+ }
+
+ /**
+ * Called when diagnostic data is available from the FLP HAL.
+ */
+ public void onDiagnosticDataAvailable(String data) {
+ // default do nothing
+ }
+
+ /**
+ * Called when capabilities are available from the FLP HAL.
+ * Should be called once right after initialization.
+ *
+ * @param capabilities A bitmask of capabilities defined in
+ * fused_location.h.
+ */
+ public void onCapabilities(int capabilities) {
+ // default do nothing
+ }
+
+ /**
+ * Called when the status changes in the underlying FLP HAL
+ * implementation (the ability to compute location). This
+ * callback will only be made on API 23 or later.
+ *
+ * @param status One of FLP_STATUS_LOCATION_AVAILABLE or
+ * FLP_STATUS_LOCATION_UNAVAILABLE as defined in
+ * fused_location.h.
*/
- public abstract void onLocationAvailable(Location[] locations);
- public abstract void onDiagnosticDataAvailable(String data);
+ public void onStatusChanged(int status) {
+ // default do nothing
+ }
} \ No newline at end of file
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index b7a851f..fc0189c 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -53,6 +53,12 @@ public class AudioRecord
//---------------------------------------------------------
// Constants
//--------------------
+
+ /** Minimum value for sample rate */
+ private static final int SAMPLE_RATE_HZ_MIN = 4000;
+ /** Maximum value for sample rate */
+ private static final int SAMPLE_RATE_HZ_MAX = 96000;
+
/**
* indicates AudioRecord state is not successfully initialized.
*/
@@ -571,7 +577,7 @@ public class AudioRecord
//--------------
// sample rate
- if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) {
+ if ((sampleRateInHz < SAMPLE_RATE_HZ_MIN) || (sampleRateInHz > SAMPLE_RATE_HZ_MAX)) {
throw new IllegalArgumentException(sampleRateInHz
+ "Hz is not a supported sample rate.");
}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 9c6d640..fac69ea 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -214,6 +214,8 @@ public class AudioTrack
private final Object mPlayStateLock = new Object();
/**
* Sizes of the native audio buffer.
+ * These values are set during construction and can be stale.
+ * To obtain the current native audio buffer frame count use {@link #getNativeFrameCount()}.
*/
private int mNativeBufferSizeInBytes = 0;
private int mNativeBufferSizeInFrames = 0;
@@ -312,15 +314,20 @@ public class AudioTrack
* {@link AudioFormat#ENCODING_PCM_8BIT},
* and {@link AudioFormat#ENCODING_PCM_FLOAT}.
* @param bufferSizeInBytes the total size (in bytes) of the internal buffer where audio data is
- * read from for playback.
- * If track's creation mode is {@link #MODE_STREAM}, you can write data into
- * this buffer in chunks less than or equal to this size, and it is typical to use
- * chunks of 1/2 of the total size to permit double-buffering.
- * If the track's creation mode is {@link #MODE_STATIC},
+ * read from for playback. This should be a multiple of the frame size in bytes.
+ * <p> If the track's creation mode is {@link #MODE_STATIC},
* this is the maximum length sample, or audio clip, that can be played by this instance.
- * See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size
- * for the successful creation of an AudioTrack instance in streaming mode. Using values
- * smaller than getMinBufferSize() will result in an initialization failure.
+ * <p> If the track's creation mode is {@link #MODE_STREAM},
+ * this should be the desired buffer size
+ * for the <code>AudioTrack</code> to satisfy the application's
+ * natural latency requirements.
+ * If <code>bufferSizeInBytes</code> is less than the
+ * minimum buffer size for the output sink, it is automatically increased to the minimum
+ * buffer size.
+ * The method {@link #getNativeFrameCount()} returns the
+ * actual size in frames of the native buffer created, which
+ * determines the frequency to write
+ * to the streaming <code>AudioTrack</code> to avoid underrun.
* @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
* @throws java.lang.IllegalArgumentException
*/
@@ -512,8 +519,10 @@ public class AudioTrack
* {@link AudioManager#PROPERTY_OUTPUT_SAMPLE_RATE}), its channel configuration will be
* {@link AudioFormat#CHANNEL_OUT_STEREO} and the encoding will be
* {@link AudioFormat#ENCODING_PCM_16BIT}.
+ * <br>If the buffer size is not specified with {@link #setBufferSizeInBytes(int)},
+ * and the mode is {@link AudioTrack#MODE_STREAM}, the minimum buffer size is used.
* <br>If the transfer mode is not specified with {@link #setTransferMode(int)},
- * {@link AudioTrack#MODE_STREAM} will be used.
+ * <code>MODE_STREAM</code> will be used.
* <br>If the session ID is not specified with {@link #setSessionId(int)}, a new one will
* be generated.
*/
@@ -648,6 +657,13 @@ public class AudioTrack
.build();
}
try {
+ // If the buffer size is not specified in streaming mode,
+ // use a single frame for the buffer size and let the
+ // native code figure out the minimum buffer size.
+ if (mMode == MODE_STREAM && mBufferSizeInBytes == 0) {
+ mBufferSizeInBytes = mFormat.getChannelCount()
+ * mFormat.getBytesPerSample(mFormat.getEncoding());
+ }
return new AudioTrack(mAttributes, mFormat, mBufferSizeInBytes, mMode, mSessionId);
} catch (IllegalArgumentException e) {
throw new UnsupportedOperationException(e.getMessage());
@@ -986,19 +1002,22 @@ public class AudioTrack
}
/**
- * Returns the "native frame count", derived from the bufferSizeInBytes specified at
- * creation time and converted to frame units.
- * If track's creation mode is {@link #MODE_STATIC},
- * it is equal to the specified bufferSizeInBytes converted to frame units.
- * If track's creation mode is {@link #MODE_STREAM},
- * it is typically greater than or equal to the specified bufferSizeInBytes converted to frame
- * units; it may be rounded up to a larger value if needed by the target device implementation.
- * @deprecated Only accessible by subclasses, which are not recommended for AudioTrack.
- * See {@link AudioManager#getProperty(String)} for key
+ * Returns the "native frame count" of the <code>AudioTrack</code> buffer.
+ * <p> If the track's creation mode is {@link #MODE_STATIC},
+ * it is equal to the specified bufferSizeInBytes on construction, converted to frame units.
+ * A static track's native frame count will not change.
+ * <p> If the track's creation mode is {@link #MODE_STREAM},
+ * it is greater than or equal to the specified bufferSizeInBytes converted to frame units.
+ * For streaming tracks, this value may be rounded up to a larger value if needed by
+ * the target output sink, and
+ * if the track is subsequently routed to a different output sink, the native
+ * frame count may enlarge to accommodate.
+ * See also {@link AudioManager#getProperty(String)} for key
* {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
+ * @return current size in frames of the audio track buffer.
+ * @throws IllegalStateException
*/
- @Deprecated
- protected int getNativeFrameCount() {
+ public int getNativeFrameCount() throws IllegalStateException {
return native_get_native_frame_count();
}
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index ebf73da..ce06e65 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -124,6 +124,8 @@ public final class MediaCodecInfo {
private static final Range<Integer> SIZE_RANGE = Range.create(1, 32768);
private static final Range<Integer> FRAME_RATE_RANGE = Range.create(0, 960);
private static final Range<Integer> BITRATE_RANGE = Range.create(0, 500000000);
+ private static final int DEFAULT_MAX_SUPPORTED_INSTANCES = 32;
+ private static final int MAX_SUPPORTED_INSTANCES_LIMIT = 256;
// found stuff that is not supported by framework (=> this should not happen)
private static final int ERROR_UNRECOGNIZED = (1 << 0);
@@ -147,6 +149,7 @@ public final class MediaCodecInfo {
// CLASSIFICATION
private String mMime;
+ private int mMaxSupportedInstances;
// LEGACY FIELDS
@@ -366,6 +369,18 @@ public final class MediaCodecInfo {
return mMime;
}
+ /**
+ * Returns the max number of the supported concurrent codec instances.
+ * <p>
+ * This is a hint for an upper bound. Applications should not expect to successfully
+ * operate more instances than the returned value, but the actual number of
+ * concurrently operable instances may be less as it depends on the available
+ * resources at time of use.
+ */
+ public int getMaxSupportedInstances() {
+ return mMaxSupportedInstances;
+ }
+
private boolean isAudio() {
return mAudioCaps != null;
}
@@ -467,6 +482,15 @@ public final class MediaCodecInfo {
mEncoderCaps.setDefaultFormat(mDefaultFormat);
}
+ final Map<String, Object> global = MediaCodecList.getGlobalSettings();
+ mMaxSupportedInstances = Utils.parseIntSafely(
+ global.get("max-supported-instances"), DEFAULT_MAX_SUPPORTED_INSTANCES);
+
+ int maxInstances = Utils.parseIntSafely(
+ map.get("max-supported-instances"), mMaxSupportedInstances);
+ mMaxSupportedInstances =
+ Range.create(1, MAX_SUPPORTED_INSTANCES_LIMIT).clamp(maxInstances);
+
for (Feature feat: getValidFeatures()) {
String key = MediaFormat.KEY_FEATURE_ + feat.mName;
Integer yesNo = (Integer)map.get(key);
diff --git a/media/java/android/media/MediaCodecList.java b/media/java/android/media/MediaCodecList.java
index 7fd0186..f44e048 100644
--- a/media/java/android/media/MediaCodecList.java
+++ b/media/java/android/media/MediaCodecList.java
@@ -21,6 +21,7 @@ import android.util.Log;
import android.media.MediaCodecInfo;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Map;
/**
* Allows you to enumerate available codecs, each specified as a {@link MediaCodecInfo} object,
@@ -61,13 +62,19 @@ final public class MediaCodecList {
return sRegularCodecInfos[index];
}
+ /* package private */ static final Map<String, Object> getGlobalSettings() {
+ return sGlobalSettings;
+ }
+
private static Object sInitLock = new Object();
private static MediaCodecInfo[] sAllCodecInfos;
private static MediaCodecInfo[] sRegularCodecInfos;
+ private static Map<String, Object> sGlobalSettings;
private static final void initCodecList() {
synchronized (sInitLock) {
if (sRegularCodecInfos == null) {
+ sGlobalSettings = native_getGlobalSettings();
int count = native_getCodecCount();
ArrayList<MediaCodecInfo> regulars = new ArrayList<MediaCodecInfo>();
ArrayList<MediaCodecInfo> all = new ArrayList<MediaCodecInfo>();
@@ -112,6 +119,8 @@ final public class MediaCodecList {
/* package private */ static native final MediaCodecInfo.CodecCapabilities
getCodecCapabilities(int index, String type);
+ /* package private */ static native final Map<String, Object> native_getGlobalSettings();
+
/* package private */ static native final int findCodecByName(String codec);
/** @hide */
diff --git a/media/java/android/media/midi/package.html b/media/java/android/media/midi/package.html
new file mode 100644
index 0000000..9e7e8b1
--- /dev/null
+++ b/media/java/android/media/midi/package.html
@@ -0,0 +1,324 @@
+<html>
+<body>
+<p>Android MIDI User Guide</p>
+
+<h1 id=overview>Overview</h1>
+
+
+<p>This document describes how to use the Android MIDI API in Java.</p>
+
+<p>The Android MIDI package allows users to:</p>
+
+<ul>
+ <li> Connect a MIDI keyboard to Android to play a synthesizer or drive music apps.
+ <li> Connect alternative MIDI controllers to Android.
+ <li> Drive external MIDI synths from Android.
+ <li> Drive external peripherals, lights, show control, etc from Android.
+ <li> Generate music dynamically from games or music creation apps.
+ <li> Generate MIDI messages in one app and send them to a second app.
+ <li> Use an Android device running in <em>peripheral mode</em> as a multitouch controller connected to a laptop.
+</ul>
+
+<h2 id=the_api_features_include>The API features include:</h2>
+
+
+<ul>
+ <li> Enumeration of currently available devices. Information includes name, vendor,
+capabilities, etc.
+ <li> Provide notification when MIDI devices are plugged in or unplugged.
+ <li> Support efficient transmission of single or multiple short 1-3 byte MIDI
+messages.
+ <li> Support transmission of arbitrary length data for SysEx, etc.
+ <li> Timestamps to avoid jitter.
+ <li> Support direction connection or “patching” of devices for lower latency.
+</ul>
+
+<h2 id=transports_supported>Transports Supported</h2>
+
+
+<p>The API is “transport agnostic”. But there are several transports currently
+supported:</p>
+
+<ul>
+ <li> USB
+ <li> software routing
+ <li> BTLE
+</ul>
+
+<h1 id=android_midi_terminology>Android MIDI Terminology</h1>
+
+
+<h2 id=terminology>Terminology</h2>
+
+
+<p>A <strong>Device</strong> is a MIDI capable object that has zero or more InputPorts and OutputPorts.</p>
+
+<p>An <strong>InputPort</strong> has 16 channels and can <strong>receive</strong> MIDI messages from an OutputPort or an app.</p>
+
+<p>An <strong>OutputPort</strong> has 16 channels and can <strong>send</strong> MIDI messages to an InputPort or an app.</p>
+
+<p><strong>MidiService</strong> is a centralized process that keeps track of all devices and brokers
+communication between them.</p>
+
+<p><strong>MidiManager</strong> is a class that the application or a device manager calls to communicate with
+the MidiService.</p>
+
+<h1 id=writing_a_midi_application>Writing a MIDI Application</h1>
+
+
+<h2 id=the_midimanager>The MidiManager</h2>
+
+
+<p>The primary class for accessing the MIDI package is through the MidiManager.</p>
+
+<pre class=prettyprint>
+MidiManager m = (MidiManager)context.getSystemService(Context.MIDI_SERVICE);
+</pre>
+
+
+<h2 id=get_list_of_already_plugged_in_entities>Get List of Already Plugged In Entities</h2>
+
+
+<p>When an app starts, it can get a list of all the available MIDI devices. This
+information can be presented to a user, allowing them to choose a device.</p>
+
+<pre class=prettyprint>
+MidiDeviceInfo[] infos = m.getDeviceList();
+</pre>
+
+
+<h2 id=notification_of_midi_devices_hotplug_events>Notification of MIDI Devices HotPlug Events</h2>
+
+
+<p>The application can request notification when, for example, keyboards are
+plugged in or unplugged.</p>
+
+<pre class=prettyprint>
+m.registerDeviceCallback(new MidiManager.DeviceCallback() {
+ public void onDeviceAdded( MidiDeviceInfo info ) {
+ ...
+ }
+ public void onDeviceRemoved( MidiDeviceInfo info ) {
+ ...
+ }
+ });
+</pre>
+
+
+<h2 id=device_and_port_information>Device and Port Information</h2>
+
+
+<p>You can query the number of input and output ports.</p>
+
+<pre class=prettyprint>
+int numInputs = info.getInputPortCount();
+int numOutputs = info.getOutputPortCount();
+</pre>
+
+
+<p>Note that “input” and “output” are from the standpoint of the device. So a
+synthesizer will have an “input” port that receives messages. A keyboard will
+have an “output” port that sends messages.</p>
+
+<p>The MidiDeviceInfo has a bundle of properties.</p>
+
+<pre class=prettyprint>
+Bundle properties = info.getProperties();
+String manufacturer = properties
+ .getString(MidiDeviceInfo.PROPERTY_MANUFACTURER);
+</pre>
+
+
+<p>Other properties include PROPERTY_PRODUCT, PROPERTY_NAME,
+PROPERTY_SERIAL_NUMBER</p>
+
+<p>You can get the names of the ports from a PortInfo object.</p>
+
+<pre class=prettyprint>
+PortInfo portInfo = info.getInputPortInfo(i);
+String portName = portInfo.getName();
+</pre>
+
+
+<h2 id=open_a_midi_device>Open a MIDI Device</h2>
+
+
+<p>To access a MIDI device you need to open it first. The open is asynchronous so
+you need to provide a callback for completion. You can specify an optional
+Handler if you want the callback to occur on a specific Thread.</p>
+
+<pre class=prettyprint>
+m.openDevice(info, new MidiManager.DeviceOpenCallback() {
+ &#64;Override
+ public void onDeviceOpened(MidiDeviceInfo deviceInfo,
+ MidiDevice device) {
+ if (device == null) {
+ Log.e(TAG, "could not open " + deviceInfo);
+ } else {
+ ...
+ }, new Handler(Looper.getMainLooper())
+ );
+</pre>
+
+
+<h2 id=open_a_midi_input_port>Open a MIDI Input Port</h2>
+
+
+<p>If you want to send a message to a MIDI Device then you need to open an “input”
+port with exclusive access.</p>
+
+<pre class=prettyprint>
+MidiInputPort inputPort = device.openInputPort(index);
+</pre>
+
+
+<h2 id=send_a_noteon>Send a NoteOn</h2>
+
+
+<p>MIDI messages are sent as byte arrays. Here we encode a NoteOn message.</p>
+
+<pre class=prettyprint>
+byte[] buffer = new buffer[64];
+int numBytes = 0;
+buffer[numBytes++] = 0x90 + channel; // note on
+buffer[numBytes++] = pitch;
+buffer[numBytes++] = velocity;
+int offset = 0;
+// post is non-blocking
+inputPort.send(buffer, offset, numBytes);
+</pre>
+
+
+<p>Sometimes it is convenient to send MIDI messages with a timestamp. By
+scheduling events in the future we can mask scheduling jitter. Android MIDI
+timestamps are based on the monotonic nanosecond system timer. This is
+consistent with the other audio and input timers.</p>
+
+<p>Here we send a message with a timestamp 2 seconds in the future.</p>
+
+<pre class=prettyprint>
+long now = System.nanoTime();
+long future = now + (2 * 1000000000);
+inputPort.sendWithTimestamp(buffer, offset, numBytes, future);
+</pre>
+
+
+<p>If you want to cancel events that you have scheduled in the future then call
+flush().</p>
+
+<pre class=prettyprint>
+inputPort.flush(); // discard events
+</pre>
+
+
+<p>If there were any MIDI NoteOff message left in the buffer then they will be
+discarded and you may get stuck notes. So we recommend sending “all notes off”
+after doing a flush.</p>
+
+<h2 id=receive_a_note>Receive a Note</h2>
+
+
+<p>To receive MIDI data from a device you need to extend MidiReceiver. Then
+connect your receiver to an output port of the device.</p>
+
+<pre class=prettyprint>
+class MyReceiver extends MidiReceiver {
+ public void onReceive(byte[] data, int offset,
+ int count, long timestamp) throws IOException {
+ // parse MIDI or whatever
+ }
+}
+MidiOutputPort outputPort = device.openOutputPort(index);
+outputPort.connect(new MyReceiver());
+</pre>
+
+
+<p>The data that arrives is not validated or aligned in any particular way. It is
+raw MIDI data and can contain multiple messages or partial messages. It might
+contain System Real-Time messages, which can be interleaved inside other
+messages. Some applications have their own MIDI parsers so pre-parsing the data
+would be redundant. If an application wants the data parsed and aligned then
+they can use the MidiFramer utility.</p>
+
+<h1 id=creating_a_midi_virtual_device_service>Creating a MIDI Virtual Device Service</h1>
+
+
+<p>An app can provide a MIDI Service that can be used by other apps. For example,
+an app can provide a custom synthesizer that other apps can send messages to. </p>
+
+<h2 id=manifest_files>Manifest Files</h2>
+
+
+<p>An app declares that it will function as a MIDI server in the
+AndroidManifest.xml file.</p>
+
+<pre class=prettyprint>
+&lt;service android:name="<strong>MySynthDeviceService</strong>">
+ &lt;intent-filter>
+ &lt;action android:name="android.media.midi.MidiDeviceService" />
+ &lt;/intent-filter>
+ &lt;meta-data android:name="android.media.midi.MidiDeviceService"
+ android:resource="@xml/<strong>synth_device_info</strong>" />
+&lt;/service>
+</pre>
+
+
+<p>The details of the resource in this example is stored in
+“res/xml/synth_device_info.xml”.</p>
+
+<pre class=prettyprint>
+&lt;devices>
+ &lt;device manufacturer="MyCompany" product="MidiSynthBasic">
+ &lt;input-port name="input" />
+ &lt;/device>
+&lt;/devices>
+</pre>
+
+
+<h2 id=extend_midideviceservice>Extend MidiDeviceService</h2>
+
+
+<p>You then define your server by extending android.media.midi.MidiDeviceService.
+Let’s assume you have a MySynthEngine class that extends MidiReceiver.</p>
+
+<pre class=prettyprint>
+import android.media.midi.MidiDeviceService;
+import android.media.midi.MidiDeviceStatus;
+import android.media.midi.MidiReceiver;
+
+public class MidiSynthDeviceService extends MidiDeviceService {
+ private static final String TAG = "MidiSynthDeviceService";
+ private MySynthEngine mSynthEngine = new MySynthEngine();
+ &#64;Override
+ public void onCreate() {
+ super.onCreate();
+ }
+
+ &#64;Override
+ public void onDestroy() {
+ mSynthEngine.stop();
+ super.onDestroy();
+ }
+
+ &#64;Override
+ // Declare the receivers associated with your input ports.
+ public MidiReceiver[] onGetInputPortReceivers() {
+ return new MidiReceiver[] { mSynthEngine };
+ }
+
+ /**
+ * This will get called when clients connect or disconnect.
+ * You can use it to turn on your synth only when needed.
+ */
+ &#64;Override
+ public void onDeviceStatusChanged(MidiDeviceStatus status) {
+ if (status.isInputPortOpen(0)) {
+ mSynthEngine.start();
+ } else {
+ mSynthEngine.stop();
+ }
+ }
+}
+</pre>
+</body>
+</html>
diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp
index f8c349b..82dd48d 100644
--- a/media/jni/android_media_MediaCodecList.cpp
+++ b/media/jni/android_media_MediaCodecList.cpp
@@ -262,6 +262,27 @@ static jobject android_media_MediaCodecList_getCodecCapabilities(
return caps;
}
+static jobject android_media_MediaCodecList_getGlobalSettings(JNIEnv *env, jobject /* thiz */) {
+ sp<IMediaCodecList> mcl = getCodecList(env);
+ if (mcl == NULL) {
+ // Runtime exception already pending.
+ return NULL;
+ }
+
+ const sp<AMessage> settings = mcl->getGlobalSettings();
+ if (settings == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "cannot get global settings");
+ return NULL;
+ }
+
+ jobject settingsObj = NULL;
+ if (ConvertMessageToMap(env, settings, &settingsObj)) {
+ return NULL;
+ }
+
+ return settingsObj;
+}
+
static void android_media_MediaCodecList_native_init(JNIEnv* /* env */) {
}
@@ -277,6 +298,10 @@ static JNINativeMethod gMethods[] = {
"(ILjava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;",
(void *)android_media_MediaCodecList_getCodecCapabilities },
+ { "native_getGlobalSettings",
+ "()Ljava/util/Map;",
+ (void *)android_media_MediaCodecList_getGlobalSettings },
+
{ "findCodecByName", "(Ljava/lang/String;)I",
(void *)android_media_MediaCodecList_findCodecByName },
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 2f6bbf4..c6fa379 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -281,15 +281,16 @@ static jobject android_media_MediaMetadataRetriever_getFrameAtTime(JNIEnv *env,
return NULL;
}
- SkBitmap *bitmap = GraphicsJNI::getSkBitmap(env, jBitmap);
+ SkBitmap bitmap;
+ GraphicsJNI::getSkBitmap(env, jBitmap, &bitmap);
- bitmap->lockPixels();
- rotate((uint16_t*)bitmap->getPixels(),
+ bitmap.lockPixels();
+ rotate((uint16_t*)bitmap.getPixels(),
(uint16_t*)((char*)videoFrame + sizeof(VideoFrame)),
videoFrame->mWidth,
videoFrame->mHeight,
videoFrame->mRotationAngle);
- bitmap->unlockPixels();
+ bitmap.unlockPixels();
if (videoFrame->mDisplayWidth != videoFrame->mWidth ||
videoFrame->mDisplayHeight != videoFrame->mHeight) {
diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp
index ddb01a0..0521833 100644
--- a/native/graphics/jni/bitmap.cpp
+++ b/native/graphics/jni/bitmap.cpp
@@ -27,18 +27,16 @@ int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
}
- SkBitmap* bm = GraphicsJNI::getSkBitmap(env, jbitmap);
- if (NULL == bm) {
- return ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
- }
+ SkBitmap bm;
+ GraphicsJNI::getSkBitmap(env, jbitmap, &bm);
if (info) {
- info->width = bm->width();
- info->height = bm->height();
- info->stride = bm->rowBytes();
+ info->width = bm.width();
+ info->height = bm.height();
+ info->stride = bm.rowBytes();
info->flags = 0;
- switch (bm->colorType()) {
+ switch (bm.colorType()) {
case kN32_SkColorType:
info->format = ANDROID_BITMAP_FORMAT_RGBA_8888;
break;
@@ -64,17 +62,18 @@ int AndroidBitmap_lockPixels(JNIEnv* env, jobject jbitmap, void** addrPtr) {
return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
}
- SkBitmap* bm = GraphicsJNI::getSkBitmap(env, jbitmap);
- if (NULL == bm) {
+ SkPixelRef* pixelRef = GraphicsJNI::getSkPixelRef(env, jbitmap);
+ if (!pixelRef) {
return ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
}
- bm->lockPixels();
- void* addr = bm->getPixels();
+ pixelRef->lockPixels();
+ void* addr = pixelRef->pixels();
if (NULL == addr) {
- bm->unlockPixels();
+ pixelRef->unlockPixels();
return ANDROID_BITMAP_RESULT_ALLOCATION_FAILED;
}
+ pixelRef->ref();
if (addrPtr) {
*addrPtr = addr;
@@ -87,8 +86,8 @@ int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap) {
return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
}
- SkBitmap* bm = GraphicsJNI::getSkBitmap(env, jbitmap);
- if (NULL == bm) {
+ SkPixelRef* pixelRef = GraphicsJNI::getSkPixelRef(env, jbitmap);
+ if (!pixelRef) {
return ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
}
@@ -96,9 +95,11 @@ int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap) {
// bitmaps. Note that this will slow down read-only accesses to the
// bitmaps, but the NDK methods are primarily intended to be used for
// writes.
- bm->notifyPixelsChanged();
+ pixelRef->notifyPixelsChanged();
+
+ pixelRef->unlockPixels();
+ pixelRef->unref();
- bm->unlockPixels();
return ANDROID_BITMAP_RESULT_SUCCESS;
}
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index c5c5d82..c41a831 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -64,6 +64,5 @@
<item quantity="other">Αντιγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων.</item>
<item quantity="one">Αντιγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου.</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"Προετοιμασία για αντιγραφή…"</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-en-rAU/strings.xml b/packages/DocumentsUI/res/values-en-rAU/strings.xml
index b23cd21..74eaaa7 100644
--- a/packages/DocumentsUI/res/values-en-rAU/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rAU/strings.xml
@@ -64,6 +64,5 @@
<item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
<item quantity="one">Copying <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml
index b23cd21..74eaaa7 100644
--- a/packages/DocumentsUI/res/values-en-rGB/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml
@@ -64,6 +64,5 @@
<item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
<item quantity="one">Copying <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml
index b23cd21..74eaaa7 100644
--- a/packages/DocumentsUI/res/values-en-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml
@@ -64,6 +64,5 @@
<item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
<item quantity="one">Copying <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml
index 410bfb0..4d28802 100644
--- a/packages/DocumentsUI/res/values-in/strings.xml
+++ b/packages/DocumentsUI/res/values-in/strings.xml
@@ -64,6 +64,5 @@
<item quantity="other">Menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
<item quantity="one">Menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"Menyiapkan salinan..."</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
index 1f52c44..12c7240 100644
--- a/packages/DocumentsUI/res/values-iw/strings.xml
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -66,6 +66,5 @@
<item quantity="other">מעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
<item quantity="one">מעתיק קובץ <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"מתכונן להעתקה..."</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
index 849e3d2..5b7364f 100644
--- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -64,6 +64,5 @@
<item quantity="other">ກຳ​ລັງ​ອັດ​ສຳ​ເນົາ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟ​ລ໌.</item>
<item quantity="one">ກຳ​ລັງ​ອັດ​ສຳ​ເນົາ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟ​ລ໌.</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"ກຳ​ລັງ​ກຽມ​ອັດ​ສຳ​ເນົາ…"</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml
index 32bcce4..3a860a4 100644
--- a/packages/DocumentsUI/res/values-my-rMM/strings.xml
+++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml
@@ -64,6 +64,5 @@
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ဖိုင်များကို ကူးယူနေသည်။</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ဖိုင် ကူးယူနေသည်။</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"မိတ္တူကူးရန်ပြင်ဆင်နေ..."</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
index bad2f5f..7c300e3 100644
--- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml
+++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
@@ -64,6 +64,5 @@
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g>फाइलहरू प्रतिलिप गर्दै।</item>
<item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> फाइल प्रतिलिपि गर्दै।</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"प्रतिलिपिको लागि तयारी गर्दै ..."</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
index fe39ab8..b0bf5eb 100644
--- a/packages/DocumentsUI/res/values-tl/strings.xml
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -64,6 +64,5 @@
<item quantity="one">Kumokopya ng <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
<item quantity="other">Kumokopya ng <xliff:g id="COUNT_1">%1$d</xliff:g> na file.</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"Naghahanda para sa pagkopya…"</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index ccb5d4d..c3eaded 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -64,6 +64,5 @@
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl nusxalanmoqda</item>
<item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl nusxalanmoqda</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"Nuxsa olishga tayyorgarlik..."</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
index 2cbf655..3178117 100644
--- a/packages/DocumentsUI/res/values-zu/strings.xml
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -64,6 +64,5 @@
<item quantity="one">Ikopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
<item quantity="other">Ikopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
</plurals>
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
+ <string name="copy_preparing" msgid="3896202461003039386">"Ilungiselela ukukopisha..."</string>
</resources>
diff --git a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
index 7e09a5b..9b55e5b 100644
--- a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
+++ b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
@@ -46,7 +46,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="@dimen/eca_overlap"
- android:text="@string/kg_emergency_call_label"
+ android:text="@*android:string/lockscreen_emergency_call"
style="?android:attr/buttonBarButtonStyle"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/kg_status_line_font_size"
diff --git a/packages/Keyguard/res/values-el/strings.xml b/packages/Keyguard/res/values-el/strings.xml
index 22164ec..9ed05ee 100644
--- a/packages/Keyguard/res/values-el/strings.xml
+++ b/packages/Keyguard/res/values-el/strings.xml
@@ -110,6 +110,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"Καμία υπηρεσία."</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Κουμπί εναλλαγής μεθόδου εισόδου"</string>
<string name="airplane_mode" msgid="3122107900897202805">"Λειτουργία πτήσης"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Δεν αναγνωρίστηκε"</string>
</resources>
diff --git a/packages/Keyguard/res/values-en-rAU/strings.xml b/packages/Keyguard/res/values-en-rAU/strings.xml
index 7f8a18d..e856005 100644
--- a/packages/Keyguard/res/values-en-rAU/strings.xml
+++ b/packages/Keyguard/res/values-en-rAU/strings.xml
@@ -110,6 +110,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"No service."</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Switch input method button."</string>
<string name="airplane_mode" msgid="3122107900897202805">"Aeroplane mode"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Not recognised"</string>
</resources>
diff --git a/packages/Keyguard/res/values-en-rGB/strings.xml b/packages/Keyguard/res/values-en-rGB/strings.xml
index 7f8a18d..e856005 100644
--- a/packages/Keyguard/res/values-en-rGB/strings.xml
+++ b/packages/Keyguard/res/values-en-rGB/strings.xml
@@ -110,6 +110,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"No service."</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Switch input method button."</string>
<string name="airplane_mode" msgid="3122107900897202805">"Aeroplane mode"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Not recognised"</string>
</resources>
diff --git a/packages/Keyguard/res/values-en-rIN/strings.xml b/packages/Keyguard/res/values-en-rIN/strings.xml
index 7f8a18d..e856005 100644
--- a/packages/Keyguard/res/values-en-rIN/strings.xml
+++ b/packages/Keyguard/res/values-en-rIN/strings.xml
@@ -110,6 +110,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"No service."</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Switch input method button."</string>
<string name="airplane_mode" msgid="3122107900897202805">"Aeroplane mode"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Not recognised"</string>
</resources>
diff --git a/packages/Keyguard/res/values-in/strings.xml b/packages/Keyguard/res/values-in/strings.xml
index 2ec07e5..2c3a311 100644
--- a/packages/Keyguard/res/values-in/strings.xml
+++ b/packages/Keyguard/res/values-in/strings.xml
@@ -110,6 +110,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"Tidak ada layanan."</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tombol beralih metode masukan."</string>
<string name="airplane_mode" msgid="3122107900897202805">"Mode pesawat"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Tidak dikenali"</string>
</resources>
diff --git a/packages/Keyguard/res/values-iw/strings.xml b/packages/Keyguard/res/values-iw/strings.xml
index 30422de..e7e2264 100644
--- a/packages/Keyguard/res/values-iw/strings.xml
+++ b/packages/Keyguard/res/values-iw/strings.xml
@@ -114,6 +114,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"אין קליטה."</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"לחצן החלפת שיטת קלט."</string>
<string name="airplane_mode" msgid="3122107900897202805">"מצב טיסה"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"לא זוהתה"</string>
</resources>
diff --git a/packages/Keyguard/res/values-lo-rLA/strings.xml b/packages/Keyguard/res/values-lo-rLA/strings.xml
index 6adcca6..6b6eeab 100644
--- a/packages/Keyguard/res/values-lo-rLA/strings.xml
+++ b/packages/Keyguard/res/values-lo-rLA/strings.xml
@@ -110,6 +110,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"ບໍ່ມີບໍລິການ"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ປຸ່ມສະລັບຮູບແບບການປ້ອນຂໍ້ມູນ."</string>
<string name="airplane_mode" msgid="3122107900897202805">"ໂໝດໃນຍົນ"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"ບໍ່​ຈົດ​ຈຳ​ໄດ້"</string>
</resources>
diff --git a/packages/Keyguard/res/values-my-rMM/strings.xml b/packages/Keyguard/res/values-my-rMM/strings.xml
index 1313789..dfb7854 100644
--- a/packages/Keyguard/res/values-my-rMM/strings.xml
+++ b/packages/Keyguard/res/values-my-rMM/strings.xml
@@ -110,6 +110,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"ဆားဗစ် မရှိပါ"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ထည့်သွင်းခြင်းခလုတ်အား ပြောင်းခြင်း"</string>
<string name="airplane_mode" msgid="3122107900897202805">"လေယာဉ်ပေါ်သုံးစနစ်"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"အသိအမှတ်မပြုပါ"</string>
</resources>
diff --git a/packages/Keyguard/res/values-ne-rNP/strings.xml b/packages/Keyguard/res/values-ne-rNP/strings.xml
index 597ba48..6f7d9fb 100644
--- a/packages/Keyguard/res/values-ne-rNP/strings.xml
+++ b/packages/Keyguard/res/values-ne-rNP/strings.xml
@@ -110,6 +110,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"कुनै सेवा छैन।"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"इनपुट विधि बटन स्विच गर्नुहोस्।"</string>
<string name="airplane_mode" msgid="3122107900897202805">"हवाइजहाज मोड"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"चिनिएको छैन"</string>
</resources>
diff --git a/packages/Keyguard/res/values-tl/strings.xml b/packages/Keyguard/res/values-tl/strings.xml
index b883843..9ae81fc 100644
--- a/packages/Keyguard/res/values-tl/strings.xml
+++ b/packages/Keyguard/res/values-tl/strings.xml
@@ -110,6 +110,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"Walang serbisyo."</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Ilipat ang button na pamamaraan ng pag-input."</string>
<string name="airplane_mode" msgid="3122107900897202805">"Airplane mode"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Hindi nakilala"</string>
</resources>
diff --git a/packages/Keyguard/res/values-uz-rUZ/strings.xml b/packages/Keyguard/res/values-uz-rUZ/strings.xml
index ed4894a..dbf8ffc 100644
--- a/packages/Keyguard/res/values-uz-rUZ/strings.xml
+++ b/packages/Keyguard/res/values-uz-rUZ/strings.xml
@@ -110,6 +110,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"Aloqa yo‘q."</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Kiritish uslubi tugmasini almashtirish."</string>
<string name="airplane_mode" msgid="3122107900897202805">"Parvoz rejimi"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Aniqlanmadi"</string>
</resources>
diff --git a/packages/Keyguard/res/values-zh-rCN/strings.xml b/packages/Keyguard/res/values-zh-rCN/strings.xml
index 7cc6eb9..1feab4b 100644
--- a/packages/Keyguard/res/values-zh-rCN/strings.xml
+++ b/packages/Keyguard/res/values-zh-rCN/strings.xml
@@ -56,8 +56,7 @@
<string name="keyguard_accessibility_next_alarm" msgid="7269583073750518672">"下次闹钟时间已设置为<xliff:g id="ALARM">%1$s</xliff:g>"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
- <!-- no translation found for kg_emergency_call_label (635955021540347194) -->
- <skip />
+ <string name="kg_emergency_call_label" msgid="635955021540347194">"紧急呼救"</string>
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"忘记了图案"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"图案错误"</string>
<string name="kg_wrong_password" msgid="2333281762128113157">"密码错误"</string>
diff --git a/packages/Keyguard/res/values-zu/strings.xml b/packages/Keyguard/res/values-zu/strings.xml
index 328c3f7..690c397 100644
--- a/packages/Keyguard/res/values-zu/strings.xml
+++ b/packages/Keyguard/res/values-zu/strings.xml
@@ -110,6 +110,5 @@
<string name="keyguard_carrier_default" msgid="8700650403054042153">"Ayikho isevisi."</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Vula indlela yokungena yenkinobho"</string>
<string name="airplane_mode" msgid="3122107900897202805">"Isimo sendiza"</string>
- <!-- no translation found for fingerprint_not_recognized (2690661881608146617) -->
- <skip />
+ <string name="fingerprint_not_recognized" msgid="2690661881608146617">"Akubonwa"</string>
</resources>
diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml
index df221fa..e060b4a 100644
--- a/packages/Keyguard/res/values/strings.xml
+++ b/packages/Keyguard/res/values/strings.xml
@@ -122,8 +122,6 @@
<!-- Description of the Enter button in a KeyboardView. [CHAR LIMIT=NONE] -->
<string name="keyboardview_keycode_enter">Enter</string>
- <!-- Label shown on emergency call button in keyguard -->
- <string name="kg_emergency_call_label">Emergency</string>
<!-- Message shown in pattern unlock after some number of unsuccessful attempts -->
<string name="kg_forgot_pattern_button_text">Forgot Pattern</string>
<!-- Message shown when user enters wrong pattern -->
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 18615d9..147ac19 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -763,6 +763,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
mSwitchingUser = false;
startListeningForFingerprint();
}
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ // Ignore.
+ }
});
} catch (RemoteException e) {
// TODO Auto-generated catch block
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
new file mode 100644
index 0000000..3c4c646
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
@@ -0,0 +1,29 @@
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="23.0dp"
+ android:height="18.0dp"
+ android:viewportWidth="21.0"
+ android:viewportHeight="17.0">
+ <group android:translateX="2.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M9.9,11.6H7v-1.1H2.1v2.8c0,0.8,0.6,1.4,1.4,1.4h9.9c0.8,0,1.4,-0.6,1.4,-1.4v-2.8H9.9V11.6z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M14.1,4.2h-2.5V3.2l-1.1,-1.1H6.3L5.3,3.2v1H2.8C2,4.2,1.4,4.9,1.4,5.6v2.8c0,0.8,0.6,1.4,1.4,1.4H7V8.8h2.8v1.1h4.2 c0.8,0,1.4,-0.6,1.4,-1.4V5.6C15.5,4.9,14.8,4.2,14.1,4.2z M10.6,4.2H6.3V3.2h4.2V4.2z"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 23bb7a1..ac54fd6 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -389,6 +389,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"Απόρριψη"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> αποτελεί το παράθυρο διαλόγου ελέγχου έντασης"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Αγγίξτε για επαναφορά αρχικού."</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*android:string/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index bb80d8f..c25f837 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -387,6 +387,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"Deny"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*android:string/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index bb80d8f..c25f837 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -387,6 +387,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"Deny"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*android:string/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index bb80d8f..c25f837 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -387,6 +387,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"Deny"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*android:string/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 42aa273..3e6ff98 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -387,6 +387,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"Tolak"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> adalah dialog volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Sentuh untuk memulihkan aslinya."</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*android:string/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index df19b1b..f1cdcc3 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -389,6 +389,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"דחה"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> הוא תיבת הדו-שיח של עוצמת הקול"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"גע כדי לשחזר את עוצמת הקול המקורית."</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*android:string/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 26a717b..fc73134 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -387,6 +387,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"ປະຕິເສດ"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ແມ່ນ​ໜ້າ​ຕ່າງ​ລະ​ດັບ​ສຽງ"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ສໍາ​ຜັດ​ເພື່ອກູ້​ຄືນ​ຕົ້ນ​ສະ​ບັບ​."</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*android:string/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index df5365f..2be74a1b 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -387,6 +387,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"ငြင်းပယ်သည်"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် အသံဒိုင်ယာလော့ခ်ဖြစ်သည်"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"မူရင်းအားပြန်လည်သိမ်းဆည်းရန် ထိပါ။"</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*android:string/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 2c9324d..368fb1c 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -387,6 +387,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"अस्वीकार गर्नुहोस्"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> भोल्यूम संवाद हो"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"मूल पुनर्स्थापना गर्न छुनुहोस्।"</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*Android: स्ट्रिङ/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 9d25cc9..e944ae7 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -387,6 +387,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"Tanggihan"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ang volume dialog"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Pindutin upang ibalik ang orihinal."</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*android:string/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 8c3dac5..6ac4e9f 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -387,6 +387,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"Rad etish"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ovoz balandligini boshqaradi"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Aslini tiklash uchun bosing."</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*android:string/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index ae82abf..8734428 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -387,6 +387,5 @@
<string name="volumeui_prompt_deny" msgid="5720663643411696731">"Phika"</string>
<string name="volumeui_notification_title" msgid="4906770126345910955">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> yingxoxo yevolumu"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Thinta ukuze ubuyisele kokwangempela."</string>
- <!-- no translation found for volume_zen_switch_text (8149183012610587643) -->
- <skip />
+ <string name="volume_zen_switch_text" msgid="8149183012610587643">"@*android:string/zen_mode_feature_name"</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 7c199cd..b0d6178 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3288,8 +3288,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
mScrimController.setKeyguardShowing(true);
+ mIconPolicy.setKeyguardShowing(true);
} else {
mScrimController.setKeyguardShowing(false);
+ mIconPolicy.setKeyguardShowing(false);
}
mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
updateDozingState();
@@ -3724,6 +3726,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (!mKeyguardFadingAway) {
mIconController.appTransitionStarting(startTime, duration);
}
+ if (mIconPolicy != null) {
+ mIconPolicy.appTransitionStarting(startTime, duration);
+ }
}
private final class ShadeUpdates {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index ac93ced..fb42ba1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -16,16 +16,22 @@
package com.android.systemui.statusbar.phone;
+import android.app.ActivityManagerNative;
import android.app.AlarmManager;
+import android.app.IUserSwitchObserver;
import android.app.StatusBarManager;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.UserInfo;
import android.media.AudioManager;
import android.os.Handler;
+import android.os.IRemoteCallback;
+import android.os.RemoteException;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings.Global;
import android.telecom.TelecomManager;
import android.util.Log;
@@ -54,6 +60,7 @@ public class PhoneStatusBarPolicy {
private static final String SLOT_ZEN = "zen";
private static final String SLOT_VOLUME = "volume";
private static final String SLOT_ALARM_CLOCK = "alarm_clock";
+ private static final String SLOT_MANAGED_PROFILE = "managed_profile";
private final Context mContext;
private final StatusBarManager mService;
@@ -72,6 +79,10 @@ public class PhoneStatusBarPolicy {
private boolean mBluetoothEnabled = false;
+ private boolean mManagedProfileFocused = false;
+ private boolean mManagedProfileIconVisible = true;
+
+ private boolean mKeyguardVisible = true;
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
@@ -94,9 +105,6 @@ public class PhoneStatusBarPolicy {
else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
updateTTY(intent);
}
- else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
- updateAlarm();
- }
}
};
@@ -115,9 +123,15 @@ public class PhoneStatusBarPolicy {
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
- filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
+ // listen for user / profile change.
+ try {
+ ActivityManagerNative.getDefault().registerUserSwitchObserver(mUserSwitchListener);
+ } catch (RemoteException e) {
+ // Ignore
+ }
+
// TTY status
mService.setIcon(SLOT_TTY, R.drawable.stat_sys_tty_mode, 0, null);
mService.setIconVisibility(SLOT_TTY, false);
@@ -147,6 +161,10 @@ public class PhoneStatusBarPolicy {
mService.setIcon(SLOT_HOTSPOT, R.drawable.stat_sys_hotspot, 0, null);
mService.setIconVisibility(SLOT_HOTSPOT, mHotspot.isHotspotEnabled());
mHotspot.addCallback(mHotspotCallback);
+
+ // managed profile
+ mService.setIcon(SLOT_MANAGED_PROFILE, R.drawable.stat_sys_managed_profile_status, 0, null);
+ mService.setIconVisibility(SLOT_MANAGED_PROFILE, false);
}
public void setZenMode(int zen) {
@@ -298,6 +316,53 @@ public class PhoneStatusBarPolicy {
mService.setIconVisibility(SLOT_CAST, isCasting);
}
+ private void profileChanged(int userId) {
+ UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ UserInfo user = null;
+ if (userId == UserHandle.USER_CURRENT) {
+ try {
+ user = ActivityManagerNative.getDefault().getCurrentUser();
+ } catch (RemoteException e) {
+ // Ignore
+ }
+ } else {
+ user = userManager.getUserInfo(userId);
+ }
+
+ mManagedProfileFocused = user != null && user.isManagedProfile();
+ if (DEBUG) Log.v(TAG, "profileChanged: mManagedProfileFocused: " + mManagedProfileFocused);
+ // Actually update the icon later when transition starts.
+ }
+
+ private void updateManagedProfile() {
+ if (DEBUG) Log.v(TAG, "updateManagedProfile: mManagedProfileFocused: "
+ + mManagedProfileFocused
+ + " mKeyguardVisible: " + mKeyguardVisible);
+ boolean showIcon = mManagedProfileFocused && !mKeyguardVisible;
+ if (mManagedProfileIconVisible != showIcon) {
+ mService.setIconVisibility(SLOT_MANAGED_PROFILE, showIcon);
+ mManagedProfileIconVisible = showIcon;
+ }
+ }
+
+ private final IUserSwitchObserver.Stub mUserSwitchListener =
+ new IUserSwitchObserver.Stub() {
+ @Override
+ public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+ }
+
+ @Override
+ public void onUserSwitchComplete(int newUserId) throws RemoteException {
+ updateAlarm();
+ profileChanged(newUserId);
+ }
+
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ profileChanged(newProfileId);
+ }
+ };
+
private final HotspotController.Callback mHotspotCallback = new HotspotController.Callback() {
@Override
public void onHotspotChanged(boolean enabled) {
@@ -311,4 +376,13 @@ public class PhoneStatusBarPolicy {
updateCast();
}
};
+
+ public void appTransitionStarting(long startTime, long duration) {
+ updateManagedProfile();
+ }
+
+ public void setKeyguardShowing(boolean visible) {
+ mKeyguardVisible = visible;
+ updateManagedProfile();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
index 9928f7f..23a65e8 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbResolverActivity.java
@@ -93,7 +93,8 @@ public class UsbResolverActivity extends ResolverActivity {
}
@Override
- protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
+ protected void onTargetSelected(TargetInfo target, boolean alwaysCheck) {
+ final ResolveInfo ri = target.getResolveInfo();
try {
IBinder b = ServiceManager.getService(USB_SERVICE);
IUsbManager service = IUsbManager.Stub.asInterface(b);
@@ -121,7 +122,7 @@ public class UsbResolverActivity extends ResolverActivity {
}
try {
- startActivityAsUser(intent, new UserHandle(userId));
+ target.startAsUser(this, null, new UserHandle(userId));
} catch (ActivityNotFoundException e) {
Log.e(TAG, "startActivity failed", e);
}
diff --git a/preloaded-classes b/preloaded-classes
index 151766f..86bd5c9 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1791,7 +1791,6 @@ com.android.internal.telephony.ITelephonyRegistry
com.android.internal.telephony.ITelephonyRegistry$Stub
com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
com.android.internal.telephony.PhoneConstants$State
-com.android.internal.transition.ActionBarTransition
com.android.internal.util.ArrayUtils
com.android.internal.util.FastPrintWriter
com.android.internal.util.FastPrintWriter$1
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index a40233a..783df68 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -1074,9 +1074,8 @@ static jlong
nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
jobject jbitmap, jint usage)
{
- SkBitmap const * nativeBitmap =
- GraphicsJNI::getSkBitmap(_env, jbitmap);
- const SkBitmap& bitmap(*nativeBitmap);
+ SkBitmap bitmap;
+ GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
bitmap.lockPixels();
const void* ptr = bitmap.getPixels();
@@ -1091,9 +1090,8 @@ static jlong
nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type,
jint mip, jobject jbitmap, jint usage)
{
- SkBitmap const * nativeBitmap =
- GraphicsJNI::getSkBitmap(_env, jbitmap);
- const SkBitmap& bitmap(*nativeBitmap);
+ SkBitmap bitmap;
+ GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
bitmap.lockPixels();
const void* ptr = bitmap.getPixels();
@@ -1108,9 +1106,8 @@ static jlong
nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
jobject jbitmap, jint usage)
{
- SkBitmap const * nativeBitmap =
- GraphicsJNI::getSkBitmap(_env, jbitmap);
- const SkBitmap& bitmap(*nativeBitmap);
+ SkBitmap bitmap;
+ GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
bitmap.lockPixels();
const void* ptr = bitmap.getPixels();
@@ -1124,9 +1121,8 @@ nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong ty
static void
nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
{
- SkBitmap const * nativeBitmap =
- GraphicsJNI::getSkBitmap(_env, jbitmap);
- const SkBitmap& bitmap(*nativeBitmap);
+ SkBitmap bitmap;
+ GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
int w = bitmap.width();
int h = bitmap.height();
@@ -1141,9 +1137,8 @@ nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, j
static void
nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
{
- SkBitmap const * nativeBitmap =
- GraphicsJNI::getSkBitmap(_env, jbitmap);
- const SkBitmap& bitmap(*nativeBitmap);
+ SkBitmap bitmap;
+ GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
bitmap.lockPixels();
void* ptr = bitmap.getPixels();
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index d92a89f..0f9090d 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -797,6 +797,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void onUserSwitchComplete(int newUserId) throws RemoteException {
}
+
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ // Ignore.
+ }
});
userId = ActivityManagerNative.getDefault().getCurrentUser().id;
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 53c87a2..2e6d1c1 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -482,6 +482,7 @@ public class LockSettingsService extends ILockSettings.Stub {
private static final String[] READ_PASSWORD_PROTECTED_SETTINGS = new String[] {
LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
LockPatternUtils.PASSWORD_HISTORY_KEY,
+ LockPatternUtils.PASSWORD_TYPE_KEY,
};
private static final String[] SETTINGS_TO_BACKUP = new String[] {
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 5add88e..9a6f696 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -116,6 +116,11 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
@Override
public void onUserSwitchComplete(int newUserId) throws RemoteException {
}
+
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ // Ignore.
+ }
});
userId = ActivityManagerNative.getDefault().getCurrentUser().id;
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c2af765..6341807 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1284,6 +1284,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
static final int DELETE_DUMPHEAP_MSG = 52;
+ static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1922,6 +1923,9 @@ public final class ActivityManagerService extends ActivityManagerNative
mMemWatchDumpUid = -1;
}
} break;
+ case FOREGROUND_PROFILE_CHANGED_MSG: {
+ dispatchForegroundProfileChanged(msg.arg1);
+ } break;
}
}
};
@@ -2523,6 +2527,11 @@ public final class ActivityManagerService extends ActivityManagerNative
mWindowManager.setFocusedApp(r.appToken, true);
}
applyUpdateLockStateLocked(r);
+ if (last != null && last.userId != mFocusedActivity.userId) {
+ mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
+ mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
+ mFocusedActivity.userId, 0));
+ }
}
EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
@@ -19072,6 +19081,18 @@ public final class ActivityManagerService extends ActivityManagerNative
return true;
}
+ void dispatchForegroundProfileChanged(int userId) {
+ final int N = mUserSwitchObservers.beginBroadcast();
+ for (int i = 0; i < N; i++) {
+ try {
+ mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
+ } catch (RemoteException e) {
+ // Ignore
+ }
+ }
+ mUserSwitchObservers.finishBroadcast();
+ }
+
void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
long ident = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/content/AppIdleMonitor.java b/services/core/java/com/android/server/content/AppIdleMonitor.java
new file mode 100644
index 0000000..9598de8
--- /dev/null
+++ b/services/core/java/com/android/server/content/AppIdleMonitor.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 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.content;
+
+import android.app.usage.UsageStatsManagerInternal;
+import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.os.UserHandle;
+
+import com.android.server.LocalServices;
+
+/**
+ * Helper to listen for app idle and charging status changes and restart backed off
+ * sync operations.
+ */
+class AppIdleMonitor implements AppIdleStateChangeListener {
+
+ private final SyncManager mSyncManager;
+ private final UsageStatsManagerInternal mUsageStats;
+ final BatteryManager mBatteryManager;
+ /** Is the device currently plugged into power. */
+ private boolean mPluggedIn;
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ onPluggedIn(mBatteryManager.isCharging());
+ }
+ };
+
+ AppIdleMonitor(SyncManager syncManager, Context context) {
+ mSyncManager = syncManager;
+ mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
+ mUsageStats.addAppIdleStateChangeListener(this);
+ mBatteryManager = context.getSystemService(BatteryManager.class);
+ mPluggedIn = isPowered();
+ registerReceivers(context);
+ }
+
+ private void registerReceivers(Context context) {
+ // Monitor battery charging state
+ IntentFilter filter = new IntentFilter(BatteryManager.ACTION_CHARGING);
+ filter.addAction(BatteryManager.ACTION_DISCHARGING);
+ context.registerReceiver(mReceiver, filter);
+ }
+
+ private boolean isPowered() {
+ return mBatteryManager.isCharging();
+ }
+
+ void onPluggedIn(boolean pluggedIn) {
+ if (mPluggedIn == pluggedIn) {
+ return;
+ }
+ mPluggedIn = pluggedIn;
+ if (mPluggedIn) {
+ mSyncManager.onAppNotIdle(null, UserHandle.USER_ALL);
+ }
+ }
+
+ boolean isAppIdle(String packageName, int userId) {
+ return !mPluggedIn && mUsageStats.isAppIdle(packageName, userId);
+ }
+
+ @Override
+ public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
+ // Don't care if the app is becoming idle
+ if (idle) return;
+ mSyncManager.onAppNotIdle(packageName, userId);
+ }
+}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 7866ddc..4173b78 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -83,6 +83,7 @@ import com.android.internal.os.BackgroundThread;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.accounts.AccountManagerService;
import com.android.server.content.SyncStorageEngine.AuthorityInfo;
+import com.android.server.content.SyncStorageEngine.EndPoint;
import com.android.server.content.SyncStorageEngine.OnSyncRequestListener;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
@@ -107,7 +108,7 @@ import java.util.Set;
* @hide
*/
public class SyncManager {
- private static final String TAG = "SyncManager";
+ static final String TAG = "SyncManager";
/** Delay a sync due to local changes this long. In milliseconds */
private static final long LOCAL_SYNC_DELAY;
@@ -199,6 +200,8 @@ public class SyncManager {
protected SyncAdaptersCache mSyncAdapters;
+ private final AppIdleMonitor mAppIdleMonitor;
+
private BroadcastReceiver mStorageIntentReceiver =
new BroadcastReceiver() {
@Override
@@ -427,6 +430,8 @@ public class SyncManager {
mSyncAlarmIntent = PendingIntent.getBroadcast(
mContext, 0 /* ignored */, new Intent(ACTION_SYNC_ALARM), 0);
+ mAppIdleMonitor = new AppIdleMonitor(this, mContext);
+
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(mConnectivityIntentReceiver, intentFilter);
@@ -1169,6 +1174,36 @@ public class SyncManager {
}
/**
+ * Clear backoff on operations in the sync queue that match the packageName and userId.
+ * @param packageName The package that just became active. Can be null to indicate that all
+ * packages are now considered active due to being plugged in.
+ * @param userId The user for which the package has become active. Can be USER_ALL if
+ * the device just plugged in.
+ */
+ void onAppNotIdle(String packageName, int userId) {
+ synchronized (mSyncQueue) {
+ // For all sync operations in sync queue, if marked as idle, compare with package name
+ // and unmark. And clear backoff for the operation.
+ final Iterator<SyncOperation> operationIterator =
+ mSyncQueue.getOperations().iterator();
+ boolean changed = false;
+ while (operationIterator.hasNext()) {
+ final SyncOperation op = operationIterator.next();
+ if (op.appIdle
+ && getPackageName(op.target).equals(packageName)
+ && (userId == UserHandle.USER_ALL || op.target.userId == userId)) {
+ op.appIdle = false;
+ clearBackoffSetting(op);
+ changed = true;
+ }
+ }
+ if (changed) {
+ sendCheckAlarmsMessage();
+ }
+ }
+ }
+
+ /**
* @hide
*/
class ActiveSyncContext extends ISyncContext.Stub
@@ -2447,6 +2482,19 @@ public class SyncManager {
}
continue;
}
+ String packageName = getPackageName(op.target);
+ // If app is considered idle, then skip for now and backoff
+ if (packageName != null
+ && mAppIdleMonitor.isAppIdle(packageName, op.target.userId)) {
+ increaseBackoffSetting(op);
+ op.appIdle = true;
+ if (isLoggable) {
+ Log.v(TAG, "Sync backing off idle app " + packageName);
+ }
+ continue;
+ } else {
+ op.appIdle = false;
+ }
// Add this sync to be run.
operations.add(op);
}
@@ -3194,6 +3242,21 @@ public class SyncManager {
}
}
+ String getPackageName(EndPoint endpoint) {
+ if (endpoint.target_service) {
+ return endpoint.service.getPackageName();
+ } else {
+ SyncAdapterType syncAdapterType =
+ SyncAdapterType.newKey(endpoint.provider, endpoint.account.type);
+ final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
+ syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, endpoint.userId);
+ if (syncAdapterInfo == null) {
+ return null;
+ }
+ return syncAdapterInfo.componentName.getPackageName();
+ }
+ }
+
private boolean isSyncStillActive(ActiveSyncContext activeSyncContext) {
for (ActiveSyncContext sync : mActiveSyncContexts) {
if (sync == activeSyncContext) {
diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java
index 35827cc..10efe81 100644
--- a/services/core/java/com/android/server/content/SyncOperation.java
+++ b/services/core/java/com/android/server/content/SyncOperation.java
@@ -90,6 +90,9 @@ public class SyncOperation implements Comparable {
/** Descriptive string key for this operation */
public String wakeLockName;
+ /** Whether this sync op was recently skipped due to the app being idle */
+ public boolean appIdle;
+
public SyncOperation(Account account, int userId, int reason, int source, String provider,
Bundle extras, long runTimeFromNow, long flexTime, long backoff,
long delayUntil, boolean allowParallelSyncs) {
diff --git a/services/core/java/com/android/server/display/DisplayBlanker.java b/services/core/java/com/android/server/display/DisplayBlanker.java
index eb0ae6a..816dc13 100644
--- a/services/core/java/com/android/server/display/DisplayBlanker.java
+++ b/services/core/java/com/android/server/display/DisplayBlanker.java
@@ -20,5 +20,5 @@ package com.android.server.display;
* Interface used to update the actual display state.
*/
public interface DisplayBlanker {
- void requestDisplayState(int state);
+ void requestDisplayState(int state, int brightness);
}
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 61631d4..e16be71 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -118,10 +118,12 @@ abstract class DisplayDevice {
/**
* Sets the display state, if supported.
*
+ * @param state The new display state.
+ * @param brightness The new display brightness.
* @return A runnable containing work to be deferred until after we have
* exited the critical section, or null if none.
*/
- public Runnable requestDisplayStateLocked(int state) {
+ public Runnable requestDisplayStateLocked(int state, int brightness) {
return null;
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 5f0ad9f..9ea0444 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -40,11 +40,13 @@ import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.Trace;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
@@ -179,7 +181,11 @@ public final class DisplayManagerService extends SystemService {
// The overall display state, independent of changes that might influence one
// display or another in particular.
- private int mGlobalDisplayState = Display.STATE_UNKNOWN;
+ private int mGlobalDisplayState = Display.STATE_ON;
+
+ // The overall display brightness.
+ // For now, this only applies to the built-in display but we may split it up eventually.
+ private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT;
// Set to true when there are pending display changes that have yet to be applied
// to the surface flinger state.
@@ -226,6 +232,9 @@ public final class DisplayManagerService extends SystemService {
mUiHandler = UiThread.getHandler();
mDisplayAdapterListener = new DisplayAdapterListener();
mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
+
+ PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
}
@Override
@@ -322,16 +331,34 @@ public final class DisplayManagerService extends SystemService {
}
}
- private void requestGlobalDisplayStateInternal(int state) {
+ private void requestGlobalDisplayStateInternal(int state, int brightness) {
+ if (state == Display.STATE_UNKNOWN) {
+ state = Display.STATE_ON;
+ }
+ if (state == Display.STATE_OFF) {
+ brightness = PowerManager.BRIGHTNESS_OFF;
+ } else if (brightness < 0) {
+ brightness = PowerManager.BRIGHTNESS_DEFAULT;
+ } else if (brightness > PowerManager.BRIGHTNESS_ON) {
+ brightness = PowerManager.BRIGHTNESS_ON;
+ }
+
synchronized (mTempDisplayStateWorkQueue) {
try {
// Update the display state within the lock.
synchronized (mSyncRoot) {
- if (mGlobalDisplayState != state) {
- mGlobalDisplayState = state;
- updateGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
- scheduleTraversalLocked(false);
+ if (mGlobalDisplayState == state
+ && mGlobalDisplayBrightness == brightness) {
+ return; // no change
}
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
+ + Display.stateToString(state)
+ + ", brightness=" + brightness + ")");
+ mGlobalDisplayState = state;
+ mGlobalDisplayBrightness = brightness;
+ updateGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
+ scheduleTraversalLocked(false);
}
// Setting the display power state can take hundreds of milliseconds
@@ -341,6 +368,7 @@ public final class DisplayManagerService extends SystemService {
for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
mTempDisplayStateWorkQueue.get(i).run();
}
+ Trace.traceEnd(Trace.TRACE_TAG_POWER);
} finally {
mTempDisplayStateWorkQueue.clear();
}
@@ -708,7 +736,7 @@ public final class DisplayManagerService extends SystemService {
// by the display power controller (if known).
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
- return device.requestDisplayStateLocked(mGlobalDisplayState);
+ return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
}
return null;
}
@@ -1462,16 +1490,16 @@ public final class DisplayManagerService extends SystemService {
synchronized (mSyncRoot) {
DisplayBlanker blanker = new DisplayBlanker() {
@Override
- public void requestDisplayState(int state) {
+ public void requestDisplayState(int state, int brightness) {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
- requestGlobalDisplayStateInternal(state);
+ requestGlobalDisplayStateInternal(state, brightness);
}
callbacks.onDisplayStateChange(state);
if (state != Display.STATE_OFF) {
- requestGlobalDisplayStateInternal(state);
+ requestGlobalDisplayStateInternal(state, brightness);
}
}
};
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index cf1f4b0..f74601e 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -19,7 +19,6 @@ package com.android.server.display;
import com.android.internal.app.IBatteryStats;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
-import com.android.server.lights.LightsManager;
import android.animation.Animator;
import android.animation.ObjectAnimator;
@@ -122,9 +121,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Battery stats.
private final IBatteryStats mBatteryStats;
- // The lights service.
- private final LightsManager mLights;
-
// The sensor manager.
private final SensorManager mSensorManager;
@@ -260,7 +256,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mCallbacks = callbacks;
mBatteryStats = BatteryStatsService.getService();
- mLights = LocalServices.getService(LightsManager.class);
mSensorManager = sensorManager;
mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
mBlanker = blanker;
@@ -443,7 +438,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Initialize the power state object for the default display.
// In the future, we might manage multiple displays independently.
mPowerState = new DisplayPowerState(mBlanker,
- mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT),
new ColorFade(Display.DEFAULT_DISPLAY));
mColorFadeOnAnimator = ObjectAnimator.ofFloat(
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index a3c9738..f53ccc9 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -16,13 +16,10 @@
package com.android.server.display;
-import com.android.server.lights.Light;
-
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
-import android.os.Trace;
import android.util.FloatProperty;
import android.util.IntProperty;
import android.util.Slog;
@@ -56,7 +53,6 @@ final class DisplayPowerState {
private final Handler mHandler;
private final Choreographer mChoreographer;
private final DisplayBlanker mBlanker;
- private final Light mBacklight;
private final ColorFade mColorFade;
private final PhotonicModulator mPhotonicModulator;
@@ -72,12 +68,11 @@ final class DisplayPowerState {
private Runnable mCleanListener;
- public DisplayPowerState(DisplayBlanker blanker, Light backlight, ColorFade electronBeam) {
+ public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade) {
mHandler = new Handler(true /*async*/);
mChoreographer = Choreographer.getInstance();
mBlanker = blanker;
- mBacklight = backlight;
- mColorFade = electronBeam;
+ mColorFade = colorFade;
mPhotonicModulator = new PhotonicModulator();
mPhotonicModulator.start();
@@ -415,35 +410,7 @@ final class DisplayPowerState {
Slog.d(TAG, "Updating screen state: state="
+ Display.stateToString(state) + ", backlight=" + backlight);
}
- boolean suspending = Display.isSuspendedState(state);
- if (stateChanged && !suspending) {
- requestDisplayState(state);
- }
- if (backlightChanged) {
- setBrightness(backlight);
- }
- if (stateChanged && suspending) {
- requestDisplayState(state);
- }
- }
- }
-
- private void requestDisplayState(int state) {
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
- + Display.stateToString(state) + ")");
- try {
- mBlanker.requestDisplayState(state);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- }
-
- private void setBrightness(int backlight) {
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "setBrightness(" + backlight + ")");
- try {
- mBacklight.setBrightness(backlight);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ mBlanker.requestDisplayState(state, backlight);
}
}
}
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 5ebe64d..e87f265 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -16,10 +16,15 @@
package com.android.server.display;
+import com.android.server.LocalServices;
+import com.android.server.lights.Light;
+import com.android.server.lights.LightsManager;
+
import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.PowerManager;
import android.os.SystemProperties;
import android.os.Trace;
import android.util.Slog;
@@ -40,6 +45,7 @@ import java.util.Arrays;
*/
final class LocalDisplayAdapter extends DisplayAdapter {
private static final String TAG = "LocalDisplayAdapter";
+ private static final boolean DEBUG = false;
private static final String UNIQUE_ID_PREFIX = "local:";
@@ -132,14 +138,17 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private final int mBuiltInDisplayId;
private final SurfaceControl.PhysicalDisplayInfo mPhys;
private final int mDefaultPhysicalDisplayInfo;
+ private final Light mBacklight;
private DisplayDeviceInfo mInfo;
private boolean mHavePendingChanges;
private int mState = Display.STATE_UNKNOWN;
+ private int mBrightness = PowerManager.BRIGHTNESS_DEFAULT;
private float[] mSupportedRefreshRates;
private int[] mRefreshRateConfigIndices;
private float mLastRequestedRefreshRate;
+
public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);
@@ -148,6 +157,13 @@ final class LocalDisplayAdapter extends DisplayAdapter {
physicalDisplayInfos[activeDisplayInfo]);
mDefaultPhysicalDisplayInfo = activeDisplayInfo;
updateSupportedRefreshRatesLocked(physicalDisplayInfos, mPhys);
+
+ if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
+ LightsManager lights = LocalServices.getService(LightsManager.class);
+ mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
+ } else {
+ mBacklight = null;
+ }
}
public boolean updatePhysicalDisplayInfoLocked(
@@ -225,28 +241,91 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
@Override
- public Runnable requestDisplayStateLocked(final int state) {
- if (mState != state) {
+ public Runnable requestDisplayStateLocked(final int state, final int brightness) {
+ // Assume that the brightness is off if the display is being turned off.
+ assert state != Display.STATE_OFF || brightness == PowerManager.BRIGHTNESS_OFF;
+
+ final boolean stateChanged = (mState != state);
+ final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null;
+ if (stateChanged || brightnessChanged) {
final int displayId = mBuiltInDisplayId;
final IBinder token = getDisplayTokenLocked();
- final int mode = getPowerModeForState(state);
- mState = state;
- updateDeviceInfoLocked();
+ final int oldState = mState;
+
+ if (stateChanged) {
+ mState = state;
+ updateDeviceInfoLocked();
+ }
- // Defer actually setting the display power mode until we have exited
+ if (brightnessChanged) {
+ mBrightness = brightness;
+ }
+
+ // Defer actually setting the display state until after we have exited
// the critical section since it can take hundreds of milliseconds
// to complete.
return new Runnable() {
@Override
public void run() {
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
- + Display.stateToString(state) + ", id=" + displayId + ")");
+ // Exit a suspended state before making any changes.
+ int currentState = oldState;
+ if (Display.isSuspendedState(oldState)
+ || oldState == Display.STATE_UNKNOWN) {
+ if (!Display.isSuspendedState(state)) {
+ setDisplayState(state);
+ currentState = state;
+ } else if (state == Display.STATE_DOZE_SUSPEND
+ || oldState == Display.STATE_DOZE_SUSPEND) {
+ setDisplayState(Display.STATE_DOZE);
+ currentState = Display.STATE_DOZE;
+ } else {
+ return; // old state and new state is off
+ }
+ }
+
+ // Apply brightness changes given that we are in a non-suspended state.
+ if (brightnessChanged) {
+ setDisplayBrightness(brightness);
+ }
+
+ // Enter the final desired state, possibly suspended.
+ if (state != currentState) {
+ setDisplayState(state);
+ }
+ }
+
+ private void setDisplayState(int state) {
+ if (DEBUG) {
+ Slog.d(TAG, "setDisplayState("
+ + "id=" + displayId
+ + ", state=" + Display.stateToString(state) + ")");
+ }
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
+ + "id=" + displayId
+ + ", state=" + Display.stateToString(state) + ")");
try {
+ final int mode = getPowerModeForState(state);
SurfaceControl.setDisplayPowerMode(token, mode);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
+
+ private void setDisplayBrightness(int brightness) {
+ if (DEBUG) {
+ Slog.d(TAG, "setDisplayBrightness("
+ + "id=" + displayId + ", brightness=" + brightness + ")");
+ }
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
+ + "id=" + displayId + ", brightness=" + brightness + ")");
+ try {
+ mBacklight.setBrightness(brightness);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ }
+ }
};
}
return null;
@@ -278,6 +357,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
pw.println("mPhys=" + mPhys);
pw.println("mState=" + Display.stateToString(mState));
+ pw.println("mBrightness=" + mBrightness);
+ pw.println("mBacklight=" + mBacklight);
}
private void updateDeviceInfoLocked() {
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index f181cd5..6f59b54 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -221,7 +221,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
}
@Override
- public Runnable requestDisplayStateLocked(int state) {
+ public Runnable requestDisplayStateLocked(int state, int brightness) {
if (state != mDisplayState) {
mDisplayState = state;
if (state == Display.STATE_OFF) {
diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java
index 2da9d8e..ed884ef 100644
--- a/services/core/java/com/android/server/lights/LightsService.java
+++ b/services/core/java/com/android/server/lights/LightsService.java
@@ -19,16 +19,11 @@ package com.android.server.lights;
import com.android.server.SystemService;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.Handler;
-import android.os.IHardwareService;
import android.os.Message;
import android.os.Trace;
import android.util.Slog;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-
public class LightsService extends SystemService {
static final String TAG = "LightsService";
static final boolean DEBUG = false;
@@ -124,46 +119,6 @@ public class LightsService extends SystemService {
private boolean mFlashing;
}
- /* This class implements an obsolete API that was removed after eclair and re-added during the
- * final moments of the froyo release to support flashlight apps that had been using the private
- * IHardwareService API. This is expected to go away in the next release.
- */
- private final IHardwareService.Stub mLegacyFlashlightHack = new IHardwareService.Stub() {
-
- private static final String FLASHLIGHT_FILE = "/sys/class/leds/spotlight/brightness";
-
- public boolean getFlashlightEnabled() {
- try {
- FileInputStream fis = new FileInputStream(FLASHLIGHT_FILE);
- int result = fis.read();
- fis.close();
- return (result != '0');
- } catch (Exception e) {
- return false;
- }
- }
-
- public void setFlashlightEnabled(boolean on) {
- final Context context = getContext();
- if (context.checkCallingOrSelfPermission(android.Manifest.permission.FLASHLIGHT)
- != PackageManager.PERMISSION_GRANTED &&
- context.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires FLASHLIGHT or HARDWARE_TEST permission");
- }
- try {
- FileOutputStream fos = new FileOutputStream(FLASHLIGHT_FILE);
- byte[] bytes = new byte[2];
- bytes[0] = (byte)(on ? '1' : '0');
- bytes[1] = '\n';
- fos.write(bytes);
- fos.close();
- } catch (Exception e) {
- // fail silently
- }
- }
- };
-
public LightsService(Context context) {
super(context);
@@ -176,13 +131,12 @@ public class LightsService extends SystemService {
@Override
public void onStart() {
- publishBinderService("hardware", mLegacyFlashlightHack);
publishLocalService(LightsManager.class, mService);
}
private final LightsManager mService = new LightsManager() {
@Override
- public com.android.server.lights.Light getLight(int id) {
+ public Light getLight(int id) {
if (id < LIGHT_ID_COUNT) {
return mLights[id];
} else {
diff --git a/services/core/java/com/android/server/location/FlpHardwareProvider.java b/services/core/java/com/android/server/location/FlpHardwareProvider.java
index 530ad4b..834dff2 100644
--- a/services/core/java/com/android/server/location/FlpHardwareProvider.java
+++ b/services/core/java/com/android/server/location/FlpHardwareProvider.java
@@ -44,6 +44,9 @@ import android.util.Log;
public class FlpHardwareProvider {
private GeofenceHardwareImpl mGeofenceHardwareSink = null;
private IFusedLocationHardwareSink mLocationSink = null;
+ // Capabilities provided by FlpCallbacks
+ private boolean mHaveBatchingCapabilities;
+ private int mBatchingCapabilities;
private static FlpHardwareProvider sSingletonInstance = null;
@@ -124,6 +127,47 @@ public class FlpHardwareProvider {
}
}
+ private void onBatchingCapabilities(int capabilities) {
+ synchronized (mLocationSinkLock) {
+ mHaveBatchingCapabilities = true;
+ mBatchingCapabilities = capabilities;
+ }
+
+ maybeSendCapabilities();
+ }
+
+ private void onBatchingStatus(int status) {
+ IFusedLocationHardwareSink sink;
+ synchronized (mLocationSinkLock) {
+ sink = mLocationSink;
+ }
+ try {
+ if (sink != null) {
+ sink.onStatusChanged(status);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException calling onBatchingStatus");
+ }
+ }
+
+ private void maybeSendCapabilities() {
+ IFusedLocationHardwareSink sink;
+ boolean haveBatchingCapabilities;
+ int batchingCapabilities;
+ synchronized (mLocationSinkLock) {
+ sink = mLocationSink;
+ haveBatchingCapabilities = mHaveBatchingCapabilities;
+ batchingCapabilities = mBatchingCapabilities;
+ }
+ try {
+ if (sink != null && haveBatchingCapabilities) {
+ sink.onCapabilities(batchingCapabilities);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException calling onLocationAvailable");
+ }
+ }
+
// FlpDiagnosticCallbacks members
private void onDataReport(String data) {
IFusedLocationHardwareSink sink;
@@ -209,6 +253,10 @@ public class FlpHardwareProvider {
translateToGeofenceHardwareStatus(result));
}
+ private void onGeofencingCapabilities(int capabilities) {
+ getGeofenceHardwareSink().onCapabilities(capabilities);
+ }
+
/**
* Private native methods accessing FLP HAL.
*/
@@ -225,6 +273,7 @@ public class FlpHardwareProvider {
private native void nativeUpdateBatchingOptions(int requestId, FusedBatchOptions optionsObject);
private native void nativeStopBatching(int id);
private native void nativeRequestBatchedLocation(int lastNLocations);
+ private native void nativeFlushBatchedLocations();
private native void nativeInjectLocation(Location location);
// TODO [Fix] sort out the lifetime of the instance
private native void nativeCleanup();
@@ -277,6 +326,7 @@ public class FlpHardwareProvider {
mLocationSink = eventSink;
}
+ maybeSendCapabilities();
}
@Override
@@ -315,6 +365,11 @@ public class FlpHardwareProvider {
}
@Override
+ public void flushBatchedLocations() {
+ nativeFlushBatchedLocations();
+ }
+
+ @Override
public boolean supportsDiagnosticDataInjection() {
return nativeIsDiagnosticSupported();
}
diff --git a/services/core/java/com/android/server/location/FusedLocationHardwareSecure.java b/services/core/java/com/android/server/location/FusedLocationHardwareSecure.java
index 389bd24..e49c411 100644
--- a/services/core/java/com/android/server/location/FusedLocationHardwareSecure.java
+++ b/services/core/java/com/android/server/location/FusedLocationHardwareSecure.java
@@ -116,4 +116,10 @@ public class FusedLocationHardwareSecure extends IFusedLocationHardware.Stub {
checkPermissions();
mLocationHardware.injectDeviceContext(deviceEnabledContext);
}
+
+ @Override
+ public void flushBatchedLocations() throws RemoteException {
+ checkPermissions();
+ mLocationHardware.flushBatchedLocations();
+ }
}
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index fc2eced..b36fcd2 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -142,6 +142,9 @@ public class ConditionProviders extends ManagedServices {
} catch (RemoteException e) {
// we tried
}
+ if (mCallback != null) {
+ mCallback.onServiceAdded(info.component);
+ }
}
@Override
@@ -246,6 +249,16 @@ public class ConditionProviders extends ManagedServices {
}
}
+ public IConditionProvider findConditionProvider(ComponentName component) {
+ if (component == null) return null;
+ for (ManagedServiceInfo service : mServices) {
+ if (component.equals(service.component)) {
+ return provider(service);
+ }
+ }
+ return null;
+ }
+
public void ensureRecordExists(ComponentName component, Uri conditionId,
IConditionProvider provider) {
// constructed by convention, make sure the record exists...
@@ -378,6 +391,7 @@ public class ConditionProviders extends ManagedServices {
public interface Callback {
void onBootComplete();
+ void onServiceAdded(ComponentName component);
void onConditionChanged(Uri id, Condition condition);
void onUserSwitched();
}
diff --git a/services/core/java/com/android/server/notification/CountdownConditionProvider.java b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
index d223353..6a04688 100644
--- a/services/core/java/com/android/server/notification/CountdownConditionProvider.java
+++ b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
@@ -38,7 +38,7 @@ import java.util.Date;
/** Built-in zen condition provider for simple time-based conditions */
public class CountdownConditionProvider extends SystemConditionProviderService {
- private static final String TAG = "CountdownConditions";
+ private static final String TAG = "ConditionProviders";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
public static final ComponentName COMPONENT =
diff --git a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
index c997e45..383d56c 100644
--- a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
+++ b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
@@ -43,7 +43,7 @@ import java.util.TimeZone;
* Built-in zen condition provider for daily scheduled time-based conditions.
*/
public class ScheduleConditionProvider extends SystemConditionProviderService {
- private static final String TAG = "ScheduleConditions";
+ private static final String TAG = "ConditionProviders";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
public static final ComponentName COMPONENT =
diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java
index 67a2a54..766d6c5 100644
--- a/services/core/java/com/android/server/notification/ZenModeConditions.java
+++ b/services/core/java/com/android/server/notification/ZenModeConditions.java
@@ -20,6 +20,7 @@ import android.content.ComponentName;
import android.net.Uri;
import android.service.notification.Condition;
import android.service.notification.IConditionListener;
+import android.service.notification.IConditionProvider;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ZenRule;
import android.util.ArrayMap;
@@ -39,6 +40,7 @@ public class ZenModeConditions implements ConditionProviders.Callback {
private CountdownConditionProvider mCountdown;
private ScheduleConditionProvider mSchedule;
+ private boolean mFirstEvaluation = true;
public ZenModeConditions(ZenModeHelper helper, ConditionProviders conditionProviders) {
mHelper = helper;
@@ -64,7 +66,8 @@ public class ZenModeConditions implements ConditionProviders.Callback {
public void evaluateConfig(ZenModeConfig config) {
if (config == null) return;
- if (config.manualRule != null && !config.manualRule.isTrueOrUnknown()) {
+ if (config.manualRule != null && config.manualRule.condition != null
+ && !config.manualRule.isTrueOrUnknown()) {
if (DEBUG) Log.d(TAG, "evaluateConfig: clearing manual rule");
config.manualRule = null;
}
@@ -72,6 +75,7 @@ public class ZenModeConditions implements ConditionProviders.Callback {
evaluateRule(config.manualRule, current);
for (ZenRule automaticRule : config.automaticRules.values()) {
evaluateRule(automaticRule, current);
+ updateSnoozing(automaticRule);
}
final int N = mSubscriptions.size();
for (int i = N - 1; i >= 0; i--) {
@@ -82,21 +86,7 @@ public class ZenModeConditions implements ConditionProviders.Callback {
mSubscriptions.removeAt(i);
}
}
- }
-
- private void evaluateRule(ZenRule rule, ArraySet<Uri> current) {
- if (rule == null || rule.conditionId == null) return;
- final Uri id = rule.conditionId;
- for (SystemConditionProviderService sp : mConditionProviders.getSystemProviders()) {
- if (sp.isValidConditionid(id)) {
- mConditionProviders.ensureRecordExists(sp.getComponent(), id, sp.asInterface());
- rule.component = sp.getComponent();
- }
- }
- current.add(id);
- if (mConditionProviders.subscribeIfNecessary(rule.component, rule.conditionId)) {
- mSubscriptions.put(rule.conditionId, rule.component);
- }
+ mFirstEvaluation = false;
}
@Override
@@ -110,6 +100,14 @@ public class ZenModeConditions implements ConditionProviders.Callback {
}
@Override
+ public void onServiceAdded(ComponentName component) {
+ if (DEBUG) Log.d(TAG, "onServiceAdded " + component);
+ if (isAutomaticActive(component)) {
+ mHelper.setConfig(mHelper.getConfig(), "zmc.onServiceAdded");
+ }
+ }
+
+ @Override
public void onConditionChanged(Uri id, Condition condition) {
if (DEBUG) Log.d(TAG, "onConditionChanged " + id + " " + condition);
ZenModeConfig config = mHelper.getConfig();
@@ -125,8 +123,53 @@ public class ZenModeConditions implements ConditionProviders.Callback {
}
}
+ private void evaluateRule(ZenRule rule, ArraySet<Uri> current) {
+ if (rule == null || rule.conditionId == null) return;
+ final Uri id = rule.conditionId;
+ boolean isSystemCondition = false;
+ for (SystemConditionProviderService sp : mConditionProviders.getSystemProviders()) {
+ if (sp.isValidConditionid(id)) {
+ mConditionProviders.ensureRecordExists(sp.getComponent(), id, sp.asInterface());
+ rule.component = sp.getComponent();
+ isSystemCondition = true;
+ }
+ }
+ if (!isSystemCondition) {
+ final IConditionProvider cp = mConditionProviders.findConditionProvider(rule.component);
+ if (DEBUG) Log.d(TAG, "Ensure external rule exists: " + (cp != null) + " for " + id);
+ if (cp != null) {
+ mConditionProviders.ensureRecordExists(rule.component, id, cp);
+ }
+ }
+ if (rule.component == null) {
+ Log.w(TAG, "No component found for automatic rule: " + rule.conditionId);
+ rule.enabled = false;
+ return;
+ }
+ if (current != null) {
+ current.add(id);
+ }
+ if (mConditionProviders.subscribeIfNecessary(rule.component, rule.conditionId)) {
+ mSubscriptions.put(rule.conditionId, rule.component);
+ } else {
+ if (DEBUG) Log.d(TAG, "zmc failed to subscribe");
+ }
+ }
+
+ private boolean isAutomaticActive(ComponentName component) {
+ if (component == null) return false;
+ final ZenModeConfig config = mHelper.getConfig();
+ if (config == null) return false;
+ for (ZenRule rule : config.automaticRules.values()) {
+ if (component.equals(rule.component) && rule.isAutomaticActive()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private boolean updateSnoozing(ZenRule rule) {
- if (rule != null && rule.snoozing && !rule.isTrueOrUnknown()) {
+ if (rule != null && rule.snoozing && (mFirstEvaluation || !rule.isTrueOrUnknown())) {
rule.snoozing = false;
if (DEBUG) Log.d(TAG, "Snoozing reset for " + rule.conditionId);
return true;
@@ -141,4 +184,5 @@ public class ZenModeConditions implements ConditionProviders.Callback {
rule.condition = condition;
return true;
}
+
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index e5925fe..683d1fd 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -175,7 +175,7 @@ public class ZenModeHelper {
if (zenMode == Global.ZEN_MODE_OFF) {
newConfig.manualRule = null;
for (ZenRule automaticRule : newConfig.automaticRules.values()) {
- if (automaticRule.isTrueOrUnknown()) {
+ if (automaticRule.isAutomaticActive()) {
automaticRule.snoozing = true;
}
}
@@ -286,8 +286,7 @@ public class ZenModeHelper {
if (mConfig.manualRule != null) return mConfig.manualRule.zenMode;
int zen = Global.ZEN_MODE_OFF;
for (ZenRule automaticRule : mConfig.automaticRules.values()) {
- if (automaticRule.enabled && !automaticRule.snoozing
- && automaticRule.isTrueOrUnknown()) {
+ if (automaticRule.isAutomaticActive()) {
if (zenSeverity(automaticRule.zenMode) > zenSeverity(zen)) {
zen = automaticRule.zenMode;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 04059fc..a260b0e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -6645,86 +6645,94 @@ public class PackageManagerService extends IPackageManager.Stub {
r = null;
for (i=0; i<N; i++) {
PackageParser.Permission p = pkg.permissions.get(i);
+
+ // Now that permission groups have a special meaning, we ignore permission
+ // groups for legacy apps to prevent unexpected behavior. In particular,
+ // permissions for one app being granted to someone just becuase they happen
+ // to be in a group defined by another app (before this had no implications).
+ if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
+ p.group = mPermissionGroups.get(p.info.group);
+ // Warn for a permission in an unknown group.
+ if (p.info.group != null && p.group == null) {
+ Slog.w(TAG, "Permission " + p.info.name + " from package "
+ + p.info.packageName + " in an unknown group " + p.info.group);
+ }
+ }
+
ArrayMap<String, BasePermission> permissionMap =
p.tree ? mSettings.mPermissionTrees
- : mSettings.mPermissions;
- p.group = mPermissionGroups.get(p.info.group);
- if (p.info.group == null || p.group != null) {
- BasePermission bp = permissionMap.get(p.info.name);
-
- // Allow system apps to redefine non-system permissions
- if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
- final boolean currentOwnerIsSystem = (bp.perm != null
- && isSystemApp(bp.perm.owner));
- if (isSystemApp(p.owner)) {
- if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
- // It's a built-in permission and no owner, take ownership now
- bp.packageSetting = pkgSetting;
- bp.perm = p;
- bp.uid = pkg.applicationInfo.uid;
- bp.sourcePackage = p.info.packageName;
- } else if (!currentOwnerIsSystem) {
- String msg = "New decl " + p.owner + " of permission "
- + p.info.name + " is system; overriding " + bp.sourcePackage;
- reportSettingsProblem(Log.WARN, msg);
- bp = null;
- }
+ : mSettings.mPermissions;
+ BasePermission bp = permissionMap.get(p.info.name);
+
+ // Allow system apps to redefine non-system permissions
+ if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
+ final boolean currentOwnerIsSystem = (bp.perm != null
+ && isSystemApp(bp.perm.owner));
+ if (isSystemApp(p.owner)) {
+ if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
+ // It's a built-in permission and no owner, take ownership now
+ bp.packageSetting = pkgSetting;
+ bp.perm = p;
+ bp.uid = pkg.applicationInfo.uid;
+ bp.sourcePackage = p.info.packageName;
+ } else if (!currentOwnerIsSystem) {
+ String msg = "New decl " + p.owner + " of permission "
+ + p.info.name + " is system; overriding " + bp.sourcePackage;
+ reportSettingsProblem(Log.WARN, msg);
+ bp = null;
}
}
+ }
- if (bp == null) {
- bp = new BasePermission(p.info.name, p.info.packageName,
- BasePermission.TYPE_NORMAL);
- permissionMap.put(p.info.name, bp);
- }
-
- if (bp.perm == null) {
- if (bp.sourcePackage == null
- || bp.sourcePackage.equals(p.info.packageName)) {
- BasePermission tree = findPermissionTreeLP(p.info.name);
- if (tree == null
- || tree.sourcePackage.equals(p.info.packageName)) {
- bp.packageSetting = pkgSetting;
- bp.perm = p;
- bp.uid = pkg.applicationInfo.uid;
- bp.sourcePackage = p.info.packageName;
- if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(p.info.name);
+ if (bp == null) {
+ bp = new BasePermission(p.info.name, p.info.packageName,
+ BasePermission.TYPE_NORMAL);
+ permissionMap.put(p.info.name, bp);
+ }
+
+ if (bp.perm == null) {
+ if (bp.sourcePackage == null
+ || bp.sourcePackage.equals(p.info.packageName)) {
+ BasePermission tree = findPermissionTreeLP(p.info.name);
+ if (tree == null
+ || tree.sourcePackage.equals(p.info.packageName)) {
+ bp.packageSetting = pkgSetting;
+ bp.perm = p;
+ bp.uid = pkg.applicationInfo.uid;
+ bp.sourcePackage = p.info.packageName;
+ if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
}
- } else {
- Slog.w(TAG, "Permission " + p.info.name + " from package "
- + p.info.packageName + " ignored: base tree "
- + tree.name + " is from package "
- + tree.sourcePackage);
+ r.append(p.info.name);
}
} else {
Slog.w(TAG, "Permission " + p.info.name + " from package "
- + p.info.packageName + " ignored: original from "
- + bp.sourcePackage);
+ + p.info.packageName + " ignored: base tree "
+ + tree.name + " is from package "
+ + tree.sourcePackage);
}
- } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append("DUP:");
- r.append(p.info.name);
+ } else {
+ Slog.w(TAG, "Permission " + p.info.name + " from package "
+ + p.info.packageName + " ignored: original from "
+ + bp.sourcePackage);
}
- if (bp.perm == p) {
- bp.protectionLevel = p.info.protectionLevel;
+ } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
}
- } else {
- Slog.w(TAG, "Permission " + p.info.name + " from package "
- + p.info.packageName + " ignored: no group "
- + p.group);
+ r.append("DUP:");
+ r.append(p.info.name);
+ }
+ if (bp.perm == p) {
+ bp.protectionLevel = p.info.protectionLevel;
}
}
+
if (r != null) {
if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r);
}
@@ -11928,7 +11936,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
removeUser = user.getIdentifier();
appId = ps.appId;
- mSettings.writePackageRestrictionsLPr(removeUser);
+ scheduleWritePackageRestrictionsLocked(removeUser);
} else {
// We need to set it back to 'installed' so the uninstall
// broadcasts will be sent correctly.
@@ -11943,7 +11951,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
removeUser = user.getIdentifier();
appId = ps.appId;
- mSettings.writePackageRestrictionsLPr(removeUser);
+ scheduleWritePackageRestrictionsLocked(removeUser);
}
}
}
@@ -11960,6 +11968,11 @@ public class PackageManagerService extends IPackageManager.Stub {
mInstaller.clearUserData(packageName, removeUser);
removeKeystoreDataIfNeeded(removeUser, appId);
schedulePackageCleaning(packageName, removeUser, false);
+ synchronized (mPackages) {
+ if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
+ scheduleWritePackageRestrictionsLocked(removeUser);
+ }
+ }
return true;
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index cd1c9a5..b38d33d 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -691,6 +691,20 @@ public class TrustManagerService extends SystemService {
return isDeviceLockedInner(userId);
}
+ @Override
+ public boolean isDeviceSecure(int userId) throws RemoteException {
+ userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
+ false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
+ userId = resolveProfileParent(userId);
+
+ long token = Binder.clearCallingIdentity();
+ try {
+ return new LockPatternUtils(mContext).isSecure(userId);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
private void enforceReportPermission() {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 99cf8df..54be380 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -538,6 +538,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
@Override
public void onUserSwitchComplete(int newUserId) throws RemoteException {
}
+
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ // Ignore.
+ }
});
} catch (RemoteException e) {
// TODO Auto-generated catch block
diff --git a/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp b/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp
index d5508bc..852b5e9 100644
--- a/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp
+++ b/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp
@@ -33,12 +33,15 @@ static hw_device_t* sHardwareDevice = NULL;
static jmethodID sOnLocationReport = NULL;
static jmethodID sOnDataReport = NULL;
+static jmethodID sOnBatchingCapabilities = NULL;
+static jmethodID sOnBatchingStatus = NULL;
static jmethodID sOnGeofenceTransition = NULL;
static jmethodID sOnGeofenceMonitorStatus = NULL;
static jmethodID sOnGeofenceAdd = NULL;
static jmethodID sOnGeofenceRemove = NULL;
static jmethodID sOnGeofencePause = NULL;
static jmethodID sOnGeofenceResume = NULL;
+static jmethodID sOnGeofencingCapabilities = NULL;
static const FlpLocationInterface* sFlpInterface = NULL;
static const FlpDiagnosticInterface* sFlpDiagnosticInterface = NULL;
@@ -85,6 +88,32 @@ static bool IsValidCallbackThread() {
return true;
}
+static void BatchingCapabilitiesCallback(int32_t capabilities) {
+ if(!IsValidCallbackThread()) {
+ return;
+ }
+
+ sCallbackEnv->CallVoidMethod(
+ sCallbacksObj,
+ sOnBatchingCapabilities,
+ capabilities
+ );
+ CheckExceptions(sCallbackEnv, __FUNCTION__);
+}
+
+static void BatchingStatusCallback(int32_t status) {
+ if(!IsValidCallbackThread()) {
+ return;
+ }
+
+ sCallbackEnv->CallVoidMethod(
+ sCallbacksObj,
+ sOnBatchingStatus,
+ status
+ );
+ CheckExceptions(sCallbackEnv, __FUNCTION__);
+}
+
static int SetThreadEvent(ThreadEvent event) {
JavaVM* javaVm = AndroidRuntime::getJavaVM();
@@ -156,6 +185,18 @@ static void ClassInit(JNIEnv* env, jclass clazz) {
"onDataReport",
"(Ljava/lang/String;)V"
);
+ sOnBatchingCapabilities = env->GetMethodID(
+ clazz,
+ "onBatchingCapabilities",
+ "(I)V");
+ sOnBatchingStatus = env->GetMethodID(
+ clazz,
+ "onBatchingStatus",
+ "(I)V");
+ sOnGeofencingCapabilities = env->GetMethodID(
+ clazz,
+ "onGeofencingCapabilities",
+ "(I)V");
sOnGeofenceTransition = env->GetMethodID(
clazz,
"onGeofenceTransition",
@@ -534,7 +575,9 @@ FlpCallbacks sFlpCallbacks = {
LocationCallback,
AcquireWakelock,
ReleaseWakelock,
- SetThreadEvent
+ SetThreadEvent,
+ BatchingCapabilitiesCallback,
+ BatchingStatusCallback
};
static void ReportData(char* data, int length) {
@@ -670,6 +713,19 @@ static void GeofenceResumeCallback(int32_t geofenceId, int32_t result) {
CheckExceptions(sCallbackEnv, __FUNCTION__);
}
+static void GeofencingCapabilitiesCallback(int32_t capabilities) {
+ if(!IsValidCallbackThread()) {
+ return;
+ }
+
+ sCallbackEnv->CallVoidMethod(
+ sCallbacksObj,
+ sOnGeofencingCapabilities,
+ capabilities
+ );
+ CheckExceptions(sCallbackEnv, __FUNCTION__);
+}
+
FlpGeofenceCallbacks sFlpGeofenceCallbacks = {
sizeof(FlpGeofenceCallbacks),
GeofenceTransitionCallback,
@@ -678,7 +734,8 @@ FlpGeofenceCallbacks sFlpGeofenceCallbacks = {
GeofenceRemoveCallback,
GeofencePauseCallback,
GeofenceResumeCallback,
- SetThreadEvent
+ SetThreadEvent,
+ GeofencingCapabilitiesCallback
};
/*
@@ -790,6 +847,14 @@ static void GetBatchedLocation(JNIEnv* env, jobject /* object */, jint lastNLoca
sFlpInterface->get_batched_location(lastNLocations);
}
+static void FlushBatchedLocations(JNIEnv* env, jobject /* object */) {
+ if(sFlpInterface == NULL) {
+ ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+ }
+
+ sFlpInterface->flush_batched_locations();
+}
+
static void InjectLocation(JNIEnv* env, jobject /* object */, jobject locationObject) {
if(locationObject == NULL) {
ALOGE("Invalid location for injection: %p", locationObject);
@@ -972,6 +1037,9 @@ static JNINativeMethod sMethods[] = {
{"nativeRequestBatchedLocation",
"(I)V",
reinterpret_cast<void*>(GetBatchedLocation)},
+ {"nativeFlushBatchedLocations",
+ "()V",
+ reinterpret_cast<void*>(FlushBatchedLocations)},
{"nativeInjectLocation",
"(Landroid/location/Location;)V",
reinterpret_cast<void*>(InjectLocation)},
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
index c766183..2661643 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
@@ -22,6 +22,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Environment;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.util.AtomicFile;
import android.util.Slog;
@@ -59,6 +60,7 @@ class DeviceOwner {
private static final String ATTR_PACKAGE = "package";
private static final String ATTR_COMPONENT_NAME = "component";
private static final String ATTR_USERID = "userId";
+ private static final String TAG_OTA_POLICY = "ota-policy";
private AtomicFile fileForWriting;
@@ -75,6 +77,9 @@ class DeviceOwner {
// Internal state for the profile owner packages.
private final HashMap<Integer, OwnerInfo> mProfileOwners = new HashMap<Integer, OwnerInfo>();
+ // Local OTA policy controllable by device owner.
+ private PersistableBundle mOtaPolicy;
+
// Private default constructor.
private DeviceOwner() {
}
@@ -187,6 +192,18 @@ class DeviceOwner {
return mProfileOwners.keySet();
}
+ PersistableBundle getOtaPolicy() {
+ return mOtaPolicy;
+ }
+
+ void setOtaPolicy(PersistableBundle otaPolicy) {
+ mOtaPolicy = otaPolicy;
+ }
+
+ void clearOtaPolicy() {
+ mOtaPolicy = null;
+ }
+
boolean hasDeviceOwner() {
return mDeviceOwner != null;
}
@@ -273,6 +290,8 @@ class DeviceOwner {
profileOwnerInfo = new OwnerInfo(profileOwnerName, profileOwnerPackageName);
}
mProfileOwners.put(userId, profileOwnerInfo);
+ } else if (TAG_OTA_POLICY.equals(tag)) {
+ mOtaPolicy = PersistableBundle.restoreFromXml(parser);
} else {
throw new XmlPullParserException(
"Unexpected tag in device owner file: " + tag);
@@ -338,6 +357,17 @@ class DeviceOwner {
out.endTag(null, TAG_PROFILE_OWNER);
}
}
+
+ // Write OTA policy tag
+ if (mOtaPolicy != null) {
+ out.startTag(null, TAG_OTA_POLICY);
+ try {
+ mOtaPolicy.saveToXml(out);
+ } catch (XmlPullParserException e) {
+ Slog.e(TAG, "Failed to save OTA policy", e);
+ }
+ out.endTag(null, TAG_OTA_POLICY);
+ }
out.endDocument();
out.flush();
finishWrite(outputStream);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index bb3085e..c7d2b86 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -347,6 +347,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private static final String TAG_DISABLE_KEYGUARD_FEATURES = "disable-keyguard-features";
private static final String TAG_DISABLE_CAMERA = "disable-camera";
private static final String TAG_DISABLE_CALLER_ID = "disable-caller-id";
+ private static final String TAG_DISABLE_BLUETOOTH_CONTACT_SHARING
+ = "disable-bt-contacts-sharing";
private static final String TAG_DISABLE_SCREEN_CAPTURE = "disable-screen-capture";
private static final String TAG_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management";
private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time";
@@ -428,6 +430,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
boolean encryptionRequested = false;
boolean disableCamera = false;
boolean disableCallerId = false;
+ boolean disableBluetoothContactSharing = true;
boolean disableScreenCapture = false; // Can only be set by a device/profile owner.
boolean requireAutoTime = false; // Can only be set by a device owner.
@@ -569,6 +572,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
out.attribute(null, ATTR_VALUE, Boolean.toString(disableCallerId));
out.endTag(null, TAG_DISABLE_CALLER_ID);
}
+ if (disableBluetoothContactSharing) {
+ out.startTag(null, TAG_DISABLE_BLUETOOTH_CONTACT_SHARING);
+ out.attribute(null, ATTR_VALUE,
+ Boolean.toString(disableBluetoothContactSharing));
+ out.endTag(null, TAG_DISABLE_BLUETOOTH_CONTACT_SHARING);
+ }
if (disableScreenCapture) {
out.startTag(null, TAG_DISABLE_SCREEN_CAPTURE);
out.attribute(null, ATTR_VALUE, Boolean.toString(disableScreenCapture));
@@ -714,6 +723,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} else if (TAG_DISABLE_CALLER_ID.equals(tag)) {
disableCallerId = Boolean.parseBoolean(
parser.getAttributeValue(null, ATTR_VALUE));
+ } else if (TAG_DISABLE_BLUETOOTH_CONTACT_SHARING.equals(tag)) {
+ disableBluetoothContactSharing = Boolean.parseBoolean(parser
+ .getAttributeValue(null, ATTR_VALUE));
} else if (TAG_DISABLE_SCREEN_CAPTURE.equals(tag)) {
disableScreenCapture = Boolean.parseBoolean(
parser.getAttributeValue(null, ATTR_VALUE));
@@ -904,6 +916,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
pw.println(disableCamera);
pw.print(prefix); pw.print("disableCallerId=");
pw.println(disableCallerId);
+ pw.print(prefix); pw.print("disableBluetoothContactSharing=");
+ pw.println(disableBluetoothContactSharing);
pw.print(prefix); pw.print("disableScreenCapture=");
pw.println(disableScreenCapture);
pw.print(prefix); pw.print("requireAutoTime=");
@@ -3027,9 +3041,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, String alias) {
- Preconditions.checkNotNull(who, "ComponentName is null");
- synchronized (this) {
- getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ if (who == null) {
+ if (!isCallerDelegatedCertInstaller()) {
+ throw new SecurityException("who == null, but caller is not cert installer");
+ }
+ } else {
+ synchronized (this) {
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ }
}
final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
final long id = Binder.clearCallingIdentity();
@@ -5517,6 +5536,46 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return -1;
}
+ @Override
+ public void setBluetoothContactSharingDisabled(ComponentName who, boolean disabled) {
+ if (!mHasFeature) {
+ return;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ synchronized (this) {
+ ActiveAdmin admin = getActiveAdminForCallerLocked(who,
+ DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ if (admin.disableBluetoothContactSharing != disabled) {
+ admin.disableBluetoothContactSharing = disabled;
+ saveSettingsLocked(UserHandle.getCallingUserId());
+ }
+ }
+ }
+
+ @Override
+ public boolean getBluetoothContactSharingDisabled(ComponentName who) {
+ if (!mHasFeature) {
+ return false;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ synchronized (this) {
+ ActiveAdmin admin = getActiveAdminForCallerLocked(who,
+ DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ return admin.disableBluetoothContactSharing;
+ }
+ }
+
+ @Override
+ public boolean getBluetoothContactSharingDisabledForUser(int userId) {
+ // TODO: Should there be a check to make sure this relationship is
+ // within a profile group?
+ // enforceSystemProcess("getCrossProfileCallerIdDisabled can only be called by system");
+ synchronized (this) {
+ ActiveAdmin admin = getProfileOwnerAdmin(userId);
+ return (admin != null) ? admin.disableBluetoothContactSharing : false;
+ }
+ }
+
/**
* Sets which packages may enter lock task mode.
*
@@ -5715,6 +5774,62 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ @Override
+ public void sendDeviceInitializerStatus(int statusCode, String description) {
+ synchronized (this) {
+ String packageName = getDeviceInitializer();
+ if (packageName == null) {
+ throw new SecurityException("No device initializers");
+ }
+ UserHandle callingUser = Binder.getCallingUserHandle();
+ int deviceInitializerUid = -1;
+ try {
+ deviceInitializerUid = mContext.getPackageManager().getPackageUid(
+ packageName, callingUser.getIdentifier());
+ } catch (NameNotFoundException e) {
+ throw new SecurityException(e);
+ }
+ if (Binder.getCallingUid() != deviceInitializerUid) {
+ throw new SecurityException("Caller must be a device initializer");
+ }
+ long id = Binder.clearCallingIdentity();
+ try {
+ Intent intent = new Intent(
+ DevicePolicyManager.ACTION_SEND_DEVICE_INITIALIZER_STATUS);
+ intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_INITIALIZER_STATUS_CODE,
+ statusCode);
+ intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_INITIALIZER_STATUS_DESCRIPTION,
+ description);
+ mContext.sendBroadcastAsUser(intent, callingUser,
+ android.Manifest.permission.RECEIVE_DEVICE_INITIALIZER_STATUS);
+ } finally {
+ restoreCallingIdentity(id);
+ }
+ }
+ }
+
+ @Override
+ public boolean setKeyguardEnabledState(ComponentName who, boolean enabled) {
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ synchronized (this) {
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ }
+ final int userId = UserHandle.getCallingUserId();
+ LockPatternUtils utils = new LockPatternUtils(mContext);
+
+ // disallow disabling the keyguard if a password is currently set
+ if (!enabled && utils.isSecure(userId)) {
+ return false;
+ }
+ long ident = Binder.clearCallingIdentity();
+ try {
+ utils.setLockScreenDisabled(!enabled, userId);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ return true;
+ }
+
/**
* We need to update the internal state of whether a user has completed setup once. After
* that, we ignore any changes that reset the Settings.Secure.USER_SETUP_COMPLETE changes
@@ -5833,4 +5948,26 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
return admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
}
+
+ @Override
+ public void setOtaPolicy(ComponentName who, PersistableBundle policy) {
+ synchronized (this) {
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ if (policy == null) {
+ mDeviceOwner.clearOtaPolicy();
+ } else {
+ mDeviceOwner.setOtaPolicy(policy);
+ }
+ mDeviceOwner.writeOwnerFile();
+ }
+ mContext.sendBroadcastAsUser(new Intent(DevicePolicyManager.ACTION_OTA_POLICY_CHANGED),
+ UserHandle.OWNER);
+ }
+
+ @Override
+ public PersistableBundle getOtaPolicy() {
+ synchronized (this) {
+ return mDeviceOwner.getOtaPolicy();
+ }
+ }
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 53da75b..593853c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -325,6 +325,9 @@ public final class SystemServer {
// initialize power management features.
mActivityManagerService.initPowerManagement();
+ // Manages LEDs and display backlight so we need it to bring up the display.
+ mSystemServiceManager.startService(LightsService.class);
+
// Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
@@ -363,9 +366,6 @@ public final class SystemServer {
* Starts some essential services that are not tangled up in the bootstrap process.
*/
private void startCoreServices() {
- // Manages LEDs and display backlight.
- mSystemServiceManager.startService(LightsService.class);
-
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class);
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index bfa308e..2d47c24 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -138,14 +138,16 @@ public class UserManagerTest extends AndroidTestCase {
assertNotNull(profile);
assertTrue("creationTime must be set when the profile is created",
profile.creationTime > 0);
- assertEquals(profile.creationTime, mUserManager.getUserCreationTime(profile.id));
+ assertEquals(profile.creationTime, mUserManager.getUserCreationTime(
+ new UserHandle(profile.id)));
long ownerCreationTime = mUserManager.getUserInfo(UserHandle.USER_OWNER).creationTime;
- assertEquals(ownerCreationTime, mUserManager.getUserCreationTime(UserHandle.USER_OWNER));
+ assertEquals(ownerCreationTime, mUserManager.getUserCreationTime(
+ new UserHandle(UserHandle.USER_OWNER)));
try {
int noSuchUserId = 100500;
- mUserManager.getUserCreationTime(noSuchUserId);
+ mUserManager.getUserCreationTime(new UserHandle(noSuchUserId));
fail("SecurityException should be thrown for nonexistent user");
} catch (Exception e) {
assertTrue("SecurityException should be thrown for nonexistent user, but was: " + e,
@@ -154,7 +156,7 @@ public class UserManagerTest extends AndroidTestCase {
UserInfo user = createUser("User 1", 0);
try {
- mUserManager.getUserCreationTime(user.id);
+ mUserManager.getUserCreationTime(new UserHandle(user.id));
fail("SecurityException should be thrown for other user");
} catch (Exception e) {
assertTrue("SecurityException should be thrown for other user, but was: " + e,
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index cc0ab81..3d54dfb 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -53,6 +53,7 @@ import android.util.SparseArray;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.SystemConfig;
import com.android.server.SystemService;
import java.io.File;
@@ -383,6 +384,9 @@ public class UsageStatsService extends SystemService implements
}
boolean isAppIdle(String packageName, int userId) {
+ if (SystemConfig.getInstance().getAllowInPowerSave().contains(packageName)) {
+ return false;
+ }
final long lastUsed = getLastPackageAccessTime(packageName, userId);
return hasPassedIdleDuration(lastUsed);
}
diff --git a/tools/layoutlib/bridge/src/android/view/WindowCallback.java b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
index 823b247..d691c8e 100644
--- a/tools/layoutlib/bridge/src/android/view/WindowCallback.java
+++ b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
@@ -110,6 +110,11 @@ public class WindowCallback implements Window.Callback {
}
@Override
+ public boolean onSearchRequested(SearchEvent searchEvent) {
+ return onSearchRequested();
+ }
+
+ @Override
public boolean onSearchRequested() {
return false;
}