summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/ActivityView.java7
-rw-r--r--core/java/android/app/SystemServiceRegistry.java8
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java144
-rw-r--r--core/java/android/app/admin/DevicePolicyManagerInternal.java9
-rw-r--r--core/java/android/app/usage/NetworkStatsManager.java233
-rw-r--r--core/java/android/app/usage/NetworkUsageStats.java479
-rw-r--r--core/java/android/bluetooth/le/ScanSettings.java9
-rw-r--r--core/java/android/content/Context.java20
-rw-r--r--core/java/android/content/Intent.java60
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java7
-rw-r--r--core/java/android/content/pm/PackageParser.java14
-rw-r--r--core/java/android/content/res/Resources.java51
-rw-r--r--core/java/android/hardware/SystemSensorManager.java27
-rw-r--r--core/java/android/net/ConnectivityManager.java2
-rw-r--r--core/java/android/net/INetworkStatsService.aidl8
-rw-r--r--core/java/android/net/INetworkStatsSession.aidl6
-rw-r--r--core/java/android/net/NetworkCapabilities.java4
-rw-r--r--core/java/android/net/NetworkStats.java41
-rw-r--r--core/java/android/os/BatteryStats.java898
-rw-r--r--core/java/android/os/IPowerManager.aidl1
-rw-r--r--core/java/android/os/PowerManager.java26
-rw-r--r--core/java/android/preference/Preference.java6
-rw-r--r--core/java/android/provider/ContactsContract.java8
-rw-r--r--core/java/android/security/IKeystoreService.aidl8
-rw-r--r--core/java/android/security/NetworkSecurityPolicy.java79
-rw-r--r--core/java/android/security/keymaster/KeymasterBlob.aidl20
-rw-r--r--core/java/android/security/keymaster/KeymasterBlob.java55
-rw-r--r--core/java/android/security/keymaster/KeymasterBlobArgument.java7
-rw-r--r--core/java/android/security/keymaster/KeymasterBooleanArgument.java6
-rw-r--r--core/java/android/security/keymaster/KeymasterDateArgument.java6
-rw-r--r--core/java/android/security/keymaster/KeymasterIntArgument.java9
-rw-r--r--core/java/android/security/keymaster/KeymasterLongArgument.java6
-rw-r--r--core/java/android/service/fingerprint/Fingerprint.aidl19
-rw-r--r--core/java/android/service/fingerprint/Fingerprint.java93
-rw-r--r--core/java/android/service/fingerprint/FingerprintManager.java566
-rw-r--r--core/java/android/service/fingerprint/FingerprintManagerReceiver.java76
-rw-r--r--core/java/android/service/fingerprint/FingerprintUtils.java2
-rw-r--r--core/java/android/service/fingerprint/IFingerprintService.aidl37
-rw-r--r--core/java/android/service/fingerprint/IFingerprintServiceReceiver.aidl10
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java17
-rw-r--r--core/java/android/text/Html.java16
-rw-r--r--core/java/android/text/Layout.java5
-rw-r--r--core/java/android/text/StaticLayout.java55
-rw-r--r--core/java/android/text/style/URLSpan.java8
-rw-r--r--core/java/android/util/IntArray.java26
-rw-r--r--core/java/android/view/TextureView.java6
-rw-r--r--core/java/android/view/View.java359
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java12
-rw-r--r--core/java/android/webkit/WebChromeClient.java8
-rw-r--r--core/java/android/widget/Editor.java35
-rw-r--r--core/java/android/widget/FrameLayout.java326
-rw-r--r--core/java/android/widget/Gallery.java20
-rw-r--r--core/java/com/android/internal/logging/EventLogTags.logtags7
-rw-r--r--core/java/com/android/internal/logging/MetricsConstants.java153
-rw-r--r--core/java/com/android/internal/logging/MetricsLogger.java47
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java1025
-rw-r--r--core/java/com/android/internal/os/KernelWakelockReader.java192
-rw-r--r--core/java/com/android/internal/os/KernelWakelockStats.java37
-rw-r--r--core/java/com/android/internal/util/Protocol.java1
-rw-r--r--core/java/com/android/internal/widget/FloatingToolbar.java596
-rw-r--r--core/jni/android/graphics/MinikinUtils.cpp35
-rw-r--r--core/jni/android/graphics/MinikinUtils.h20
-rw-r--r--core/jni/android/graphics/Paint.cpp10
-rw-r--r--core/jni/android/graphics/TypefaceImpl.h2
-rw-r--r--core/jni/android_hardware_SensorManager.cpp23
-rw-r--r--core/jni/android_server_FingerprintManager.cpp43
-rw-r--r--core/jni/android_text_StaticLayout.cpp619
-rw-r--r--core/res/AndroidManifest.xml5
-rw-r--r--core/res/res/anim/ic_checkbox_checked_box_inner_merged_animation.xml52
-rw-r--r--core/res/res/anim/ic_checkbox_checked_check_path_merged_animation.xml42
-rw-r--r--core/res/res/anim/ic_checkbox_checked_icon_null_animation.xml50
-rw-r--r--core/res/res/anim/ic_checkbox_unchecked_box_inner_merged_animation.xml42
-rw-r--r--core/res/res/anim/ic_checkbox_unchecked_box_outer_merged_animation.xml52
-rw-r--r--core/res/res/anim/ic_checkbox_unchecked_icon_null_animation.xml50
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_000.pngbin900 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_001.pngbin835 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_002.pngbin699 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_003.pngbin669 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_004.pngbin613 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_005.pngbin610 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_006.pngbin597 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_007.pngbin763 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_008.pngbin758 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_009.pngbin693 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_010.pngbin664 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_011.pngbin614 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_012.pngbin579 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_013.pngbin581 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_014.pngbin602 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_off_mtrl_015.pngbin602 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_000.pngbin602 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_001.pngbin673 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_002.pngbin696 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_003.pngbin588 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_004.pngbin544 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_005.pngbin548 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_006.pngbin648 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_007.pngbin647 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_008.pngbin763 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_009.pngbin827 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_010.pngbin810 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_011.pngbin906 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_012.pngbin872 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_013.pngbin882 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_014.pngbin903 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/btn_check_to_on_mtrl_015.pngbin900 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_000.pngbin724 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_001.pngbin695 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_002.pngbin611 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_003.pngbin572 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_004.pngbin571 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_005.pngbin530 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_006.pngbin568 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_007.pngbin598 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_008.pngbin619 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_009.pngbin572 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_010.pngbin604 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_011.pngbin539 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_012.pngbin573 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_013.pngbin566 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_014.pngbin606 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_off_mtrl_015.pngbin595 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_000.pngbin595 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_001.pngbin568 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_002.pngbin581 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_003.pngbin495 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_004.pngbin536 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_005.pngbin518 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_006.pngbin567 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_007.pngbin578 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_008.pngbin615 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_009.pngbin693 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_010.pngbin677 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_011.pngbin674 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_012.pngbin685 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_013.pngbin708 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_014.pngbin708 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/btn_check_to_on_mtrl_015.pngbin724 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_000.pngbin910 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_001.pngbin928 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_002.pngbin826 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_003.pngbin762 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_004.pngbin755 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_005.pngbin682 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_006.pngbin687 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_007.pngbin854 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_008.pngbin777 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_009.pngbin751 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_010.pngbin767 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_011.pngbin757 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_012.pngbin734 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_013.pngbin709 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_014.pngbin708 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_015.pngbin719 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_000.pngbin719 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_001.pngbin783 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_002.pngbin824 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_003.pngbin661 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_004.pngbin622 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_005.pngbin613 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_006.pngbin739 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_007.pngbin744 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_008.pngbin889 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_009.pngbin906 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_010.pngbin942 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_011.pngbin894 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_012.pngbin949 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_013.pngbin944 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_014.pngbin942 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_015.pngbin910 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_000.pngbin1210 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_001.pngbin1232 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_002.pngbin1064 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_003.pngbin960 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_004.pngbin935 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_005.pngbin874 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_006.pngbin876 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_007.pngbin1123 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_008.pngbin1033 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_009.pngbin921 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_010.pngbin826 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_011.pngbin888 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_012.pngbin866 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_013.pngbin854 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_014.pngbin851 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_015.pngbin822 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_000.pngbin822 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_001.pngbin943 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_002.pngbin1051 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_003.pngbin861 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_004.pngbin749 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_005.pngbin688 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_006.pngbin948 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_007.pngbin934 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_008.pngbin1204 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_009.pngbin1283 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_010.pngbin1363 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_011.pngbin1309 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_012.pngbin1240 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_013.pngbin1240 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_014.pngbin1220 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_015.pngbin1210 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_000.pngbin881 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_001.pngbin895 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_002.pngbin804 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_003.pngbin743 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_004.pngbin690 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_005.pngbin626 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_006.pngbin662 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_007.pngbin765 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_008.pngbin711 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_009.pngbin726 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_010.pngbin671 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_011.pngbin604 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_012.pngbin621 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_013.pngbin647 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_014.pngbin623 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_015.pngbin588 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_000.pngbin588 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_001.pngbin703 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_002.pngbin806 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_003.pngbin629 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_004.pngbin547 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_005.pngbin545 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_006.pngbin698 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_007.pngbin721 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_008.pngbin817 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_009.pngbin879 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_010.pngbin955 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_011.pngbin977 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_012.pngbin906 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_013.pngbin913 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_014.pngbin914 -> 0 bytes
-rw-r--r--core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_015.pngbin881 -> 0 bytes
-rw-r--r--core/res/res/drawable/btn_check_material_anim.xml164
-rw-r--r--core/res/res/drawable/ic_checkbox_checked.xml52
-rw-r--r--core/res/res/drawable/ic_checkbox_checked_animation.xml30
-rw-r--r--core/res/res/drawable/ic_checkbox_unchecked.xml52
-rw-r--r--core/res/res/drawable/ic_checkbox_unchecked_animation.xml30
-rw-r--r--core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_0.xml20
-rw-r--r--core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_1.xml20
-rw-r--r--core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_0.xml20
-rw-r--r--core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_1.xml20
-rw-r--r--core/res/res/layout/floating_popup_container.xml25
-rw-r--r--core/res/res/layout/floating_popup_menu_button.xml31
-rw-r--r--core/res/res/layout/floating_popup_open_overflow_button.xml25
-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.xml2
-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.xml2
-rw-r--r--core/res/res/values-da/strings.xml2
-rw-r--r--core/res/res/values-de/strings.xml4
-rw-r--r--core/res/res/values-el/strings.xml2
-rw-r--r--core/res/res/values-en-rAU/strings.xml2
-rw-r--r--core/res/res/values-en-rGB/strings.xml2
-rw-r--r--core/res/res/values-en-rIN/strings.xml2
-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.xml2
-rw-r--r--core/res/res/values-eu-rES/strings.xml2
-rw-r--r--core/res/res/values-fa/strings.xml2
-rw-r--r--core/res/res/values-fi/strings.xml2
-rw-r--r--core/res/res/values-fr-rCA/strings.xml2
-rw-r--r--core/res/res/values-fr/strings.xml2
-rw-r--r--core/res/res/values-gl-rES/strings.xml2
-rw-r--r--core/res/res/values-hi/strings.xml10
-rw-r--r--core/res/res/values-hr/strings.xml2
-rw-r--r--core/res/res/values-hu/strings.xml2
-rw-r--r--core/res/res/values-hy-rAM/strings.xml2
-rw-r--r--core/res/res/values-in/strings.xml2
-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.xml2
-rw-r--r--core/res/res/values-ja/strings.xml2
-rw-r--r--core/res/res/values-ka-rGE/strings.xml2
-rw-r--r--core/res/res/values-kk-rKZ/strings.xml2
-rw-r--r--core/res/res/values-km-rKH/strings.xml2
-rw-r--r--core/res/res/values-kn-rIN/strings.xml2
-rw-r--r--core/res/res/values-ko/strings.xml2
-rw-r--r--core/res/res/values-ky-rKG/strings.xml2
-rw-r--r--core/res/res/values-lo-rLA/strings.xml2
-rw-r--r--core/res/res/values-lt/strings.xml2
-rw-r--r--core/res/res/values-lv/strings.xml2
-rw-r--r--core/res/res/values-mcc310-mnc260/strings.xml2
-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.xml2
-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.xml2
-rw-r--r--core/res/res/values-nb/strings.xml2
-rw-r--r--core/res/res/values-ne-rNP/strings.xml2
-rw-r--r--core/res/res/values-nl/strings.xml2
-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.xml2
-rw-r--r--core/res/res/values-sk/strings.xml2
-rw-r--r--core/res/res/values-sl/strings.xml2
-rw-r--r--core/res/res/values-sr/strings.xml2
-rw-r--r--core/res/res/values-sv/strings.xml2
-rw-r--r--core/res/res/values-sw/strings.xml2
-rw-r--r--core/res/res/values-ta-rIN/strings.xml2
-rw-r--r--core/res/res/values-te-rIN/strings.xml2
-rw-r--r--core/res/res/values-th/strings.xml2
-rw-r--r--core/res/res/values-tl/strings.xml2
-rw-r--r--core/res/res/values-tr/strings.xml2
-rw-r--r--core/res/res/values-uk/strings.xml2
-rw-r--r--core/res/res/values-ur-rPK/strings.xml2
-rw-r--r--core/res/res/values-uz-rUZ/strings.xml2
-rw-r--r--core/res/res/values-vi/strings.xml2
-rw-r--r--core/res/res/values-zh-rCN/strings.xml2
-rw-r--r--core/res/res/values-zh-rHK/strings.xml2
-rw-r--r--core/res/res/values-zh-rTW/strings.xml2
-rw-r--r--core/res/res/values-zu/strings.xml2
-rw-r--r--core/res/res/values/attrs.xml127
-rw-r--r--core/res/res/values/attrs_manifest.xml27
-rwxr-xr-xcore/res/res/values/config.xml12
-rw-r--r--core/res/res/values/dimens.xml7
-rw-r--r--core/res/res/values/ids.xml1
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--core/res/res/values/strings.xml32
-rwxr-xr-xcore/res/res/values/symbols.xml31
-rw-r--r--core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java82
-rw-r--r--core/tests/coretests/src/android/net/NetworkStatsTest.java31
330 files changed, 5170 insertions, 2891 deletions
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 2cb27b0..eafcdb2 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -350,10 +350,15 @@ public class ActivityView extends ViewGroup {
if (activityView != null) {
final ActivityViewCallback callback = activityView.mActivityViewCallback;
if (callback != null) {
+ final WeakReference<ActivityViewCallback> callbackRef =
+ new WeakReference<>(callback);
activityView.post(new Runnable() {
@Override
public void run() {
- callback.onAllActivitiesComplete(activityView);
+ ActivityViewCallback callback = callbackRef.get();
+ if (callback != null) {
+ callback.onAllActivitiesComplete(activityView);
+ }
}
});
}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index fd7bae7..59fe490 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -27,6 +27,7 @@ import android.app.job.IJobScheduler;
import android.app.job.JobScheduler;
import android.app.trust.TrustManager;
import android.app.usage.IUsageStatsManager;
+import android.app.usage.NetworkStatsManager;
import android.app.usage.UsageStatsManager;
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothManager;
@@ -639,6 +640,13 @@ final class SystemServiceRegistry {
return new UsageStatsManager(ctx.getOuterContext(), service);
}});
+ registerService(Context.NETWORK_STATS_SERVICE, NetworkStatsManager.class,
+ new CachedServiceFetcher<NetworkStatsManager>() {
+ @Override
+ public NetworkStatsManager createService(ContextImpl ctx) {
+ return new NetworkStatsManager(ctx.getOuterContext());
+ }});
+
registerService(Context.JOB_SCHEDULER_SERVICE, JobScheduler.class,
new StaticServiceFetcher<JobScheduler>() {
@Override
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 6dde07b..cf6619f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -20,7 +20,6 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.app.Activity;
-import android.app.admin.IDevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -176,7 +175,8 @@ public class DevicePolicyManager {
*
* <p>This component is set as device owner and active admin when device owner provisioning is
* started by an NFC message containing an NFC record with MIME type
- * {@link #MIME_TYPE_PROVISIONING_NFC}.
+ * {@link #MIME_TYPE_PROVISIONING_NFC_V2}. For the NFC record, the component name should be
+ * flattened to a string, via {@link ComponentName#flattenToShortString()}.
*
* @see DeviceAdminReceiver
*/
@@ -346,7 +346,7 @@ public class DevicePolicyManager {
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION} if the version of the
* installed package is less than this version code.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE
@@ -363,10 +363,10 @@ public class DevicePolicyManager {
= "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
/**
- * A String extra holding the SHA-1 checksum of the file at download location specified in
- * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}. If this doesn't match
- * the file at the download location an error will be shown to the user and the user will be
- * asked to factory reset the device.
+ * A String extra holding the URL-safe base64 encoded SHA-1 checksum of the file at download
+ * location specified in {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}. If
+ * this doesn't match the file at the download location an error will be shown to the user and
+ * the user will be asked to factory reset the device.
*
* <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
* provisioning via an NFC bump.
@@ -392,21 +392,23 @@ public class DevicePolicyManager {
* A boolean extra indicating whether device encryption is required as part of Device Owner
* provisioning.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_SKIP_ENCRYPTION =
"android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
/**
- * On devices managed by a device owner app, a String representation of a Component name extra
- * indicating the component of the application that is temporarily granted device owner
- * privileges during device initialization and profile owner privileges during secondary user
- * initialization.
+ * On devices managed by a device owner app, a {@link ComponentName} extra indicating the
+ * component of the application that is temporarily granted device owner privileges during
+ * device initialization and profile owner privileges during secondary user initialization.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an NFC bump.
- * @see ComponentName#unflattenFromString()
+ * <p>
+ * It can also be used in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts
+ * device owner provisioning via an NFC bump. For the NFC record, it should be flattened to a
+ * string first.
+ *
+ * @see ComponentName#flattenToShortString()
*/
public static final String EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME";
@@ -416,7 +418,7 @@ public class DevicePolicyManager {
* initializer package. When not provided it is assumed that the device initializer package is
* already installed.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION
@@ -428,7 +430,7 @@ public class DevicePolicyManager {
* {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION} if the version of
* the installed package is less than this version code.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE
@@ -438,19 +440,20 @@ public class DevicePolicyManager {
* A String extra holding a http cookie header which should be used in the http request to the
* url specified in {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER
= "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER";
/**
- * A String extra holding the SHA-1 checksum of the file at download location specified in
+ * A String extra holding the URL-safe base64 encoded SHA-1 checksum of the file at download
+ * location specified in
* {@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}. If this doesn't
* match the file at the download location an error will be shown to the user and the user will
* be asked to factory reset the device.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM
@@ -460,7 +463,7 @@ public class DevicePolicyManager {
* A String extra holding the MAC address of the Bluetooth device to connect to with status
* updates during provisioning.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_BT_MAC_ADDRESS
@@ -472,7 +475,7 @@ public class DevicePolicyManager {
*
* <p>This value must be specified when {@code #EXTRA_PROVISIONING_BT_MAC_ADDRESS} is present.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_BT_UUID
@@ -484,7 +487,7 @@ public class DevicePolicyManager {
*
* <p>This value must be specified when {@code #EXTRA_PROVISIONING_BT_MAC_ADDRESS} is present.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_BT_DEVICE_ID
@@ -494,31 +497,26 @@ public class DevicePolicyManager {
* A Boolean extra that that will cause a provisioned device to temporarily proxy network
* traffic over Bluetooth. When a Wi-Fi network is available, the network proxy will stop.
*
- * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner
* provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_BT_USE_PROXY
= "android.app.extra.PROVISIONING_BT_USE_PROXY";
-
/**
- * This MIME type is used for starting the Device Owner provisioning.
- *
- * <p>During device owner provisioning a device admin app is set as the owner of the device.
- * A device owner has full control over the device. The device owner can not be modified by the
- * user and the only way of resetting the device is if the device owner app calls a factory
- * reset.
- *
- * <p> A typical use case would be a device that is owned by a company, but used by either an
- * employee or client.
+ * This MIME type is used for starting the Device Owner provisioning that does not require
+ * provisioning features introduced in Android API level
+ * {@link android.os.Build.VERSION_CODES#MNC} or later levels.
*
- * <p> The NFC message should be send to an unprovisioned device.
+ * <p>For more information about the provisioning process see
+ * {@link #MIME_TYPE_PROVISIONING_NFC_V2}.
*
* <p>The NFC record must contain a serialized {@link java.util.Properties} object which
* contains the following properties:
* <ul>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM}</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_LOCAL_TIME} (convert to String), optional</li>
* <li>{@link #EXTRA_PROVISIONING_TIME_ZONE}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_LOCALE}, optional</li>
@@ -529,17 +527,56 @@ public class DevicePolicyManager {
* <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_HOST}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_PORT} (convert to String), optional</li>
* <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_BYPASS}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li>
- * <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li></ul>
+ * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li></ul>
*
* <p>
- * In version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, it should also contain
- * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}.
- * As of {@link android.os.Build.VERSION_CODES#MNC}, it should contain
- * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead, (although
- * specifying only {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported).
- * This componentName must have been converted to a String via
- * {@link android.content.ComponentName#flattenToString()}
+ * As of {@link android.os.Build.VERSION_CODES#MNC}, the properties should contain
+ * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead of
+ * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}, (although specifying only
+ * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported).
+ *
+ * @see #MIME_TYPE_PROVISIONING_NFC_V2
+ *
+ */
+ public static final String MIME_TYPE_PROVISIONING_NFC
+ = "application/com.android.managedprovisioning";
+
+
+ /**
+ * This MIME type is used for starting the Device Owner provisioning that requires
+ * new provisioning features introduced in API version
+ * {@link android.os.Build.VERSION_CODES#MNC} in addition to those supported in earlier
+ * versions.
+ *
+ * <p>During device owner provisioning a device admin app is set as the owner of the device.
+ * A device owner has full control over the device. The device owner can not be modified by the
+ * user and the only way of resetting the device is if the device owner app calls a factory
+ * reset.
+ *
+ * <p> A typical use case would be a device that is owned by a company, but used by either an
+ * employee or client.
+ *
+ * <p> The NFC message should be sent to an unprovisioned device.
+ *
+ * <p>The NFC record must contain a serialized {@link java.util.Properties} object which
+ * contains the following properties in addition to properties listed at
+ * {@link #MIME_TYPE_PROVISIONING_NFC}:
+ * <ul>
+ * <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_COMPONENT_NAME}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_LOCATION}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_DOWNLOAD_COOKIE_HEADER}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_PACKAGE_CHECKSUM}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_INITIALIZER_MINIMUM_VERSION_CODE}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}.
+ * Replaces {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}. The value of the property
+ * should be converted to a String via
+ * {@link android.content.ComponentName#flattenToString()}</li>
+ * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_BT_MAC_ADDRESS}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_BT_UUID}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_BT_DEVICE_ID}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_BT_USE_PROXY}, optional</li></ul>
*
* <p> When device owner provisioning has completed, an intent of the type
* {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcasted to the
@@ -551,8 +588,8 @@ public class DevicePolicyManager {
* <p>Input: Nothing.</p>
* <p>Output: Nothing</p>
*/
- public static final String MIME_TYPE_PROVISIONING_NFC
- = "application/com.android.managedprovisioning";
+ public static final String MIME_TYPE_PROVISIONING_NFC_V2
+ = "application/com.android.managedprovisioning.v2";
/**
* Activity action: ask the user to add a new device administrator to the system.
@@ -577,11 +614,10 @@ public class DevicePolicyManager {
/**
* @hide
* Activity action: ask the user to add a new device administrator as the profile owner
- * for this user. Only system privileged apps that have MANAGE_USERS and MANAGE_DEVICE_ADMINS
- * permission can call this API.
+ * for this user. Only system apps can launch this intent.
*
- * <p>The ComponentName of the profile owner admin is pass in {@link #EXTRA_DEVICE_ADMIN} extra
- * field. This will invoke a UI to bring the user through adding the profile owner admin
+ * <p>The ComponentName of the profile owner admin is passed in the {@link #EXTRA_DEVICE_ADMIN}
+ * extra field. This will invoke a UI to bring the user through adding the profile owner admin
* to remotely control restrictions on the user.
*
* <p>The intent must be invoked via {@link Activity#startActivityForResult()} to receive the
@@ -593,8 +629,8 @@ public class DevicePolicyManager {
* field to provide the user with additional explanation (in addition
* to your component's description) about what is being added.
*
- * <p>If there is already a profile owner active or the caller doesn't have the required
- * permissions, the operation will return a failure result.
+ * <p>If there is already a profile owner active or the caller is not a system app, the
+ * operation will return a failure result.
*/
@SystemApi
public static final String ACTION_SET_PROFILE_OWNER
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index a1f1d92..0a0d77d 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -60,4 +60,13 @@ public abstract class DevicePolicyManagerInternal {
*/
public abstract void addOnCrossProfileWidgetProvidersChangeListener(
OnCrossProfileWidgetProvidersChangeListener listener);
+
+ /**
+ * Checks if an app with given uid is an active device admin of its user and has the policy
+ * specified.
+ * @param uid App uid.
+ * @param reqPolicy Required policy, for policies see {@link DevicePolicyManager}.
+ * @return true if the uid is an active admin with the given policy.
+ */
+ public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy);
}
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
new file mode 100644
index 0000000..af7c053
--- /dev/null
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -0,0 +1,233 @@
+/**
+ * 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.usage;
+
+import android.app.usage.NetworkUsageStats.Bucket;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkIdentity;
+import android.net.NetworkTemplate;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+
+/**
+ * Provides access to network usage history and statistics. Usage data is collected in
+ * discrete bins of time called 'Buckets'. See {@link NetworkUsageStats.Bucket} for details.
+ * <p />
+ * Queries can define a time interval in the form of start and end timestamps (Long.MIN_VALUE and
+ * Long.MAX_VALUE can be used to simulate open ended intervals). All queries (except
+ * {@link #querySummaryForDevice}) collect only network usage of apps belonging to the same user
+ * as the client. In addition tethering usage, usage by removed users and apps, and usage by system
+ * is also included in the results.
+ * <h3>
+ * Summary queries
+ * </h3>
+ * These queries aggregate network usage across the whole interval. Therefore there will be only one
+ * bucket for a particular key and state combination. In case of the user-wide and device-wide
+ * summaries a single bucket containing the totalised network usage is returned.
+ * <h3>
+ * History queries
+ * </h3>
+ * These queries do not aggregate over time but do aggregate over state. Therefore there can be
+ * multiple buckets for a particular key but all Bucket's state is going to be
+ * {@link NetworkUsageStats.Bucket#STATE_ALL}.
+ * <p />
+ * <b>NOTE:</b> This API requires the permission
+ * {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, which is a system-level permission and
+ * will not be granted to third-party apps. However, declaring the permission implies intention to
+ * use the API and the user of the device can grant permission through the Settings application.
+ * Profile owner apps are automatically granted permission to query data on the profile they manage
+ * (that is, for any query except {@link #querySummaryForDevice}). Device owner apps likewise get
+ * access to usage data of the primary user.
+ */
+public class NetworkStatsManager {
+ private final static String TAG = "NetworkStatsManager";
+
+ private final Context mContext;
+
+ /**
+ * {@hide}
+ */
+ public NetworkStatsManager(Context context) {
+ mContext = context;
+ }
+ /**
+ * Query network usage statistics summaries. Result is summarised data usage for the whole
+ * device. Result is a single Bucket aggregated over time, state and uid.
+ *
+ * @param networkType As defined in {@link ConnectivityManager}, e.g.
+ * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
+ * etc.
+ * @param subscriberId If applicable, the subscriber id of the network interface.
+ * @param startTime Start of period. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @param endTime End of period. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @return Bucket object or null if permissions are insufficient or error happened during
+ * statistics collection.
+ */
+ public Bucket querySummaryForDevice(int networkType, String subscriberId,
+ long startTime, long endTime) throws SecurityException, RemoteException {
+ NetworkTemplate template = createTemplate(networkType, subscriberId);
+ if (template == null) {
+ return null;
+ }
+
+ Bucket bucket = null;
+ NetworkUsageStats stats = new NetworkUsageStats(mContext, template, startTime, endTime);
+ bucket = stats.getDeviceSummaryForNetwork(startTime, endTime);
+
+ stats.close();
+ return bucket;
+ }
+
+ /**
+ * Query network usage statistics summaries. Result is summarised data usage for all uids
+ * belonging to calling user. Result is a single Bucket aggregated over time, state and uid.
+ *
+ * @param networkType As defined in {@link ConnectivityManager}, e.g.
+ * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
+ * etc.
+ * @param subscriberId If applicable, the subscriber id of the network interface.
+ * @param startTime Start of period. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @param endTime End of period. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @return Bucket object or null if permissions are insufficient or error happened during
+ * statistics collection.
+ */
+ public Bucket querySummaryForUser(int networkType, String subscriberId, long startTime,
+ long endTime) throws SecurityException, RemoteException {
+ NetworkTemplate template = createTemplate(networkType, subscriberId);
+ if (template == null) {
+ return null;
+ }
+
+ NetworkUsageStats stats;
+ stats = new NetworkUsageStats(mContext, template, startTime, endTime);
+ stats.startSummaryEnumeration(startTime, endTime);
+
+ stats.close();
+ return stats.getSummaryAggregate();
+ }
+
+ /**
+ * Query network usage statistics summaries. Result filtered to include only uids belonging to
+ * calling user. Result is aggregated over time, hence all buckets will have the same start and
+ * end timestamps. Not aggregated over state or uid.
+ *
+ * @param networkType As defined in {@link ConnectivityManager}, e.g.
+ * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
+ * etc.
+ * @param subscriberId If applicable, the subscriber id of the network interface.
+ * @param startTime Start of period. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @param endTime End of period. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @return Statistics object or null if permissions are insufficient or error happened during
+ * statistics collection.
+ */
+ public NetworkUsageStats querySummary(int networkType, String subscriberId, long startTime,
+ long endTime) throws SecurityException, RemoteException {
+ NetworkTemplate template = createTemplate(networkType, subscriberId);
+ if (template == null) {
+ return null;
+ }
+
+ NetworkUsageStats result;
+ result = new NetworkUsageStats(mContext, template, startTime, endTime);
+ result.startSummaryEnumeration(startTime, endTime);
+
+ return result;
+ }
+
+ /**
+ * Query network usage statistics details. Only usable for uids belonging to calling user.
+ * Result is aggregated over state but not aggregated over time.
+ *
+ * @param networkType As defined in {@link ConnectivityManager}, e.g.
+ * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
+ * etc.
+ * @param subscriberId If applicable, the subscriber id of the network interface.
+ * @param startTime Start of period. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @param endTime End of period. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @param uid UID of app
+ * @return Statistics object or null if permissions are insufficient or error happened during
+ * statistics collection.
+ */
+ public NetworkUsageStats queryDetailsForUid(int networkType, String subscriberId,
+ long startTime, long endTime, int uid) throws SecurityException, RemoteException {
+ NetworkTemplate template = createTemplate(networkType, subscriberId);
+ if (template == null) {
+ return null;
+ }
+
+ NetworkUsageStats result;
+ result = new NetworkUsageStats(mContext, template, startTime, endTime);
+ result.startHistoryEnumeration(uid);
+
+ return result;
+ }
+
+ /**
+ * Query network usage statistics details. Result filtered to include only uids belonging to
+ * calling user. Result is aggregated over state but not aggregated over time or uid.
+ *
+ * @param networkType As defined in {@link ConnectivityManager}, e.g.
+ * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
+ * etc.
+ * @param subscriberId If applicable, the subscriber id of the network interface.
+ * @param startTime Start of period. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @param endTime End of period. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @return Statistics object or null if permissions are insufficient or error happened during
+ * statistics collection.
+ */
+ public NetworkUsageStats queryDetails(int networkType, String subscriberId, long startTime,
+ long endTime) throws SecurityException, RemoteException {
+ NetworkTemplate template = createTemplate(networkType, subscriberId);
+ if (template == null) {
+ return null;
+ }
+ NetworkUsageStats result;
+ result = new NetworkUsageStats(mContext, template, startTime, endTime);
+ result.startUserUidEnumeration();
+ return result;
+ }
+
+ private static NetworkTemplate createTemplate(int networkType, String subscriberId) {
+ NetworkTemplate template = null;
+ switch (networkType) {
+ case ConnectivityManager.TYPE_MOBILE: {
+ template = NetworkTemplate.buildTemplateMobileAll(subscriberId);
+ } break;
+ case ConnectivityManager.TYPE_WIFI: {
+ template = NetworkTemplate.buildTemplateWifiWildcard();
+ } break;
+ default: {
+ Log.w(TAG, "Cannot create template for network type " + networkType
+ + ", subscriberId '" + NetworkIdentity.scrubSubscriberId(subscriberId) +
+ "'.");
+ }
+ }
+ return template;
+ }
+}
diff --git a/core/java/android/app/usage/NetworkUsageStats.java b/core/java/android/app/usage/NetworkUsageStats.java
new file mode 100644
index 0000000..990d231
--- /dev/null
+++ b/core/java/android/app/usage/NetworkUsageStats.java
@@ -0,0 +1,479 @@
+/**
+ * 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.usage;
+
+import android.content.Context;
+import android.net.INetworkStatsService;
+import android.net.INetworkStatsSession;
+import android.net.NetworkStats;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+import android.net.TrafficStats;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import dalvik.system.CloseGuard;
+
+/**
+ * Class providing enumeration over buckets of network usage statistics. NetworkUsageStats objects
+ * are returned as results to various queries in {@link NetworkStatsManager}.
+ */
+public final class NetworkUsageStats implements AutoCloseable {
+ private final static String TAG = "NetworkUsageStats";
+
+ private final CloseGuard mCloseGuard = CloseGuard.get();
+
+ /**
+ * Start timestamp of stats collected
+ */
+ private final long mStartTimeStamp;
+
+ /**
+ * End timestamp of stats collected
+ */
+ private final long mEndTimeStamp;
+
+
+ /**
+ * Non-null array indicates the query enumerates over uids.
+ */
+ private int[] mUids;
+
+ /**
+ * Index of the current uid in mUids when doing uid enumeration or a single uid value,
+ * depending on query type.
+ */
+ private int mUidOrUidIndex;
+
+ /**
+ * The session while the query requires it, null if all the stats have been collected or close()
+ * has been called.
+ */
+ private INetworkStatsSession mSession;
+ private NetworkTemplate mTemplate;
+
+ /**
+ * Results of a summary query.
+ */
+ private NetworkStats mSummary = null;
+
+ /**
+ * Results of detail queries.
+ */
+ private NetworkStatsHistory mHistory = null;
+
+ /**
+ * Where we are in enumerating over the current result.
+ */
+ private int mEnumerationIndex = 0;
+
+ /**
+ * Recycling entry objects to prevent heap fragmentation.
+ */
+ private NetworkStats.Entry mRecycledSummaryEntry = null;
+ private NetworkStatsHistory.Entry mRecycledHistoryEntry = null;
+
+ /** @hide */
+ NetworkUsageStats(Context context, NetworkTemplate template, long startTimestamp,
+ long endTimestamp) throws RemoteException, SecurityException {
+ final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
+ ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+ // Open network stats session
+ mSession = statsService.openSessionForUsageStats(context.getOpPackageName());
+ mCloseGuard.open("close");
+ mTemplate = template;
+ mStartTimeStamp = startTimestamp;
+ mEndTimeStamp = endTimestamp;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ if (mCloseGuard != null) {
+ mCloseGuard.warnIfOpen();
+ }
+ close();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ // -------------------------BEGINNING OF PUBLIC API-----------------------------------
+
+ /**
+ * Buckets are the smallest elements of a query result. As some dimensions of a result may be
+ * aggregated (e.g. time or state) some values may be equal across all buckets.
+ */
+ public static class Bucket {
+ /**
+ * Combined usage across all other states.
+ */
+ public static final int STATE_ALL = -1;
+
+ /**
+ * Usage not accounted in any other states.
+ */
+ public static final int STATE_DEFAULT = 0x1;
+
+ /**
+ * Foreground usage.
+ */
+ public static final int STATE_FOREGROUND = 0x2;
+
+ /**
+ * Special UID value for removed apps.
+ */
+ public static final int UID_REMOVED = -4;
+
+ /**
+ * Special UID value for data usage by tethering.
+ */
+ public static final int UID_TETHERING = -5;
+
+ private int mUid;
+ private int mState;
+ private long mBeginTimeStamp;
+ private long mEndTimeStamp;
+ private long mRxBytes;
+ private long mRxPackets;
+ private long mTxBytes;
+ private long mTxPackets;
+
+ private static int convertState(int networkStatsSet) {
+ switch (networkStatsSet) {
+ case NetworkStats.SET_ALL : return STATE_ALL;
+ case NetworkStats.SET_DEFAULT : return STATE_DEFAULT;
+ case NetworkStats.SET_FOREGROUND : return STATE_FOREGROUND;
+ }
+ return 0;
+ }
+
+ private static int convertUid(int uid) {
+ switch (uid) {
+ case TrafficStats.UID_REMOVED: return UID_REMOVED;
+ case TrafficStats.UID_TETHERING: return UID_TETHERING;
+ }
+ return uid;
+ }
+
+ public Bucket() {
+ }
+
+ /**
+ * Key of the bucket. Usually an app uid or one of the following special values:<p />
+ * <ul>
+ * <li>{@link #UID_REMOVED}</li>
+ * <li>{@link #UID_TETHERING}</li>
+ * <li>{@link android.os.Process#SYSTEM_UID}</li>
+ * </ul>
+ * @return Bucket key.
+ */
+ public int getUid() {
+ return mUid;
+ }
+
+ /**
+ * Usage state. One of the following values:<p/>
+ * <ul>
+ * <li>{@link #STATE_ALL}</li>
+ * <li>{@link #STATE_DEFAULT}</li>
+ * <li>{@link #STATE_FOREGROUND}</li>
+ * </ul>
+ * @return Usage state.
+ */
+ public int getState() {
+ return mState;
+ }
+
+ /**
+ * Start timestamp of the bucket's time interval. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @return Start of interval.
+ */
+ public long getStartTimeStamp() {
+ return mBeginTimeStamp;
+ }
+
+ /**
+ * End timestamp of the bucket's time interval. Defined in terms of "Unix time", see
+ * {@link java.lang.System#currentTimeMillis}.
+ * @return End of interval.
+ */
+ public long getEndTimeStamp() {
+ return mEndTimeStamp;
+ }
+
+ /**
+ * Number of bytes received during the bucket's time interval. Statistics are measured at
+ * the network layer, so they include both TCP and UDP usage.
+ * @return Number of bytes.
+ */
+ public long getRxBytes() {
+ return mRxBytes;
+ }
+
+ /**
+ * Number of bytes transmitted during the bucket's time interval. Statistics are measured at
+ * the network layer, so they include both TCP and UDP usage.
+ * @return Number of bytes.
+ */
+ public long getTxBytes() {
+ return mTxBytes;
+ }
+
+ /**
+ * Number of packets received during the bucket's time interval. Statistics are measured at
+ * the network layer, so they include both TCP and UDP usage.
+ * @return Number of packets.
+ */
+ public long getRxPackets() {
+ return mRxPackets;
+ }
+
+ /**
+ * Number of packets transmitted during the bucket's time interval. Statistics are measured
+ * at the network layer, so they include both TCP and UDP usage.
+ * @return Number of packets.
+ */
+ public long getTxPackets() {
+ return mTxPackets;
+ }
+ }
+
+ /**
+ * Fills the recycled bucket with data of the next bin in the enumeration.
+ * @param bucketOut Bucket to be filled with data.
+ * @return true if successfully filled the bucket, false otherwise.
+ */
+ public boolean getNextBucket(Bucket bucketOut) {
+ if (mSummary != null) {
+ return getNextSummaryBucket(bucketOut);
+ } else {
+ return getNextHistoryBucket(bucketOut);
+ }
+ }
+
+ /**
+ * Check if it is possible to ask for a next bucket in the enumeration.
+ * @return true if there is at least one more bucket.
+ */
+ public boolean hasNextBucket() {
+ if (mSummary != null) {
+ return mEnumerationIndex < mSummary.size();
+ } else if (mHistory != null) {
+ return mEnumerationIndex < mHistory.size()
+ || hasNextUid();
+ }
+ return false;
+ }
+
+ /**
+ * Closes the enumeration. Call this method before this object gets out of scope.
+ */
+ @Override
+ public void close() {
+ if (mSession != null) {
+ try {
+ mSession.close();
+ } catch (RemoteException e) {
+ Log.w(TAG, e);
+ // Otherwise, meh
+ }
+ }
+ mSession = null;
+ if (mCloseGuard != null) {
+ mCloseGuard.close();
+ }
+ }
+
+ // -------------------------END OF PUBLIC API-----------------------------------
+
+ /**
+ * Collects device summary results into a Bucket.
+ * @param startTime
+ * @param endTime
+ * @throws RemoteException
+ */
+ Bucket getDeviceSummaryForNetwork(long startTime, long endTime) throws RemoteException {
+ mSummary = mSession.getDeviceSummaryForNetwork(mTemplate, startTime, endTime);
+
+ // Setting enumeration index beyond end to avoid accidental enumeration over data that does
+ // not belong to the calling user.
+ mEnumerationIndex = mSummary.size();
+
+ return getSummaryAggregate();
+ }
+
+ /**
+ * Collects summary results and sets summary enumeration mode.
+ * @param startTime
+ * @param endTime
+ * @throws RemoteException
+ */
+ void startSummaryEnumeration(long startTime, long endTime) throws RemoteException {
+ mSummary = mSession.getSummaryForAllUid(mTemplate, startTime, endTime, false);
+
+ mEnumerationIndex = 0;
+ }
+
+ /**
+ * Collects history results for uid and resets history enumeration index.
+ */
+ void startHistoryEnumeration(int uid) {
+ mHistory = null;
+ try {
+ mHistory = mSession.getHistoryForUid(mTemplate, uid, NetworkStats.SET_ALL,
+ NetworkStats.TAG_NONE, NetworkStatsHistory.FIELD_ALL);
+ setSingleUid(uid);
+ } catch (RemoteException e) {
+ Log.w(TAG, e);
+ // Leaving mHistory null
+ }
+ mEnumerationIndex = 0;
+ }
+
+ /**
+ * Starts uid enumeration for current user.
+ * @throws RemoteException
+ */
+ void startUserUidEnumeration() throws RemoteException {
+ setUidEnumeration(mSession.getRelevantUids());
+ stepHistory();
+ }
+
+ /**
+ * Steps to next uid in enumeration and collects history for that.
+ */
+ private void stepHistory(){
+ if (hasNextUid()) {
+ stepUid();
+ mHistory = null;
+ try {
+ mHistory = mSession.getHistoryForUid(mTemplate, getUid(), NetworkStats.SET_ALL,
+ NetworkStats.TAG_NONE, NetworkStatsHistory.FIELD_ALL);
+ } catch (RemoteException e) {
+ Log.w(TAG, e);
+ // Leaving mHistory null
+ }
+ mEnumerationIndex = 0;
+ }
+ }
+
+ private void fillBucketFromSummaryEntry(Bucket bucketOut) {
+ bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid);
+ bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set);
+ bucketOut.mBeginTimeStamp = mStartTimeStamp;
+ bucketOut.mEndTimeStamp = mEndTimeStamp;
+ bucketOut.mRxBytes = mRecycledSummaryEntry.rxBytes;
+ bucketOut.mRxPackets = mRecycledSummaryEntry.rxPackets;
+ bucketOut.mTxBytes = mRecycledSummaryEntry.txBytes;
+ bucketOut.mTxPackets = mRecycledSummaryEntry.txPackets;
+ }
+
+ /**
+ * Getting the next item in summary enumeration.
+ * @param bucketOut Next item will be set here.
+ * @return true if a next item could be set.
+ */
+ private boolean getNextSummaryBucket(Bucket bucketOut) {
+ if (bucketOut != null && mEnumerationIndex < mSummary.size()) {
+ mRecycledSummaryEntry = mSummary.getValues(mEnumerationIndex++, mRecycledSummaryEntry);
+ fillBucketFromSummaryEntry(bucketOut);
+ return true;
+ }
+ return false;
+ }
+
+ Bucket getSummaryAggregate() {
+ if (mSummary == null) {
+ return null;
+ }
+ Bucket bucket = new Bucket();
+ if (mRecycledSummaryEntry == null) {
+ mRecycledSummaryEntry = new NetworkStats.Entry();
+ }
+ mSummary.getTotal(mRecycledSummaryEntry);
+ fillBucketFromSummaryEntry(bucket);
+ return bucket;
+ }
+ /**
+ * Getting the next item in a history enumeration.
+ * @param bucketOut Next item will be set here.
+ * @return true if a next item could be set.
+ */
+ private boolean getNextHistoryBucket(Bucket bucketOut) {
+ if (bucketOut != null && mHistory != null) {
+ if (mEnumerationIndex < mHistory.size()) {
+ mRecycledHistoryEntry = mHistory.getValues(mEnumerationIndex++,
+ mRecycledHistoryEntry);
+ bucketOut.mUid = Bucket.convertUid(getUid());
+ bucketOut.mState = Bucket.STATE_ALL;
+ bucketOut.mBeginTimeStamp = mRecycledHistoryEntry.bucketStart;
+ bucketOut.mEndTimeStamp = mRecycledHistoryEntry.bucketStart +
+ mRecycledHistoryEntry.bucketDuration;
+ bucketOut.mRxBytes = mRecycledHistoryEntry.rxBytes;
+ bucketOut.mRxPackets = mRecycledHistoryEntry.rxPackets;
+ bucketOut.mTxBytes = mRecycledHistoryEntry.txBytes;
+ bucketOut.mTxPackets = mRecycledHistoryEntry.txPackets;
+ return true;
+ } else if (hasNextUid()) {
+ stepHistory();
+ return getNextHistoryBucket(bucketOut);
+ }
+ }
+ return false;
+ }
+
+ // ------------------ UID LOGIC------------------------
+
+ private boolean isUidEnumeration() {
+ return mUids != null;
+ }
+
+ private boolean hasNextUid() {
+ return isUidEnumeration() && (mUidOrUidIndex + 1) < mUids.length;
+ }
+
+ private int getUid() {
+ // Check if uid enumeration.
+ if (isUidEnumeration()) {
+ if (mUidOrUidIndex < 0 || mUidOrUidIndex >= mUids.length) {
+ throw new IndexOutOfBoundsException(
+ "Index=" + mUidOrUidIndex + " mUids.length=" + mUids.length);
+ }
+ return mUids[mUidOrUidIndex];
+ }
+ // Single uid mode.
+ return mUidOrUidIndex;
+ }
+
+ private void setSingleUid(int uid) {
+ mUidOrUidIndex = uid;
+ }
+
+ private void setUidEnumeration(int[] uids) {
+ mUids = uids;
+ mUidOrUidIndex = -1;
+ }
+
+ private void stepUid() {
+ if (mUids != null) {
+ ++mUidOrUidIndex;
+ }
+ }
+}
diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java
index 7eae439..0106686 100644
--- a/core/java/android/bluetooth/le/ScanSettings.java
+++ b/core/java/android/bluetooth/le/ScanSettings.java
@@ -25,6 +25,13 @@ import android.os.Parcelable;
* parameters for the scan.
*/
public final class ScanSettings implements Parcelable {
+
+ /**
+ * A special Bluetooth LE scan mode. Applications using this scan mode will passively listen for
+ * other scan results without starting BLE scans themselves.
+ */
+ public static final int SCAN_MODE_OPPORTUNISTIC = -1;
+
/**
* Perform Bluetooth LE scan in low power mode. This is the default scan mode as it consumes the
* least power.
@@ -177,7 +184,7 @@ public final class ScanSettings implements Parcelable {
* @throws IllegalArgumentException If the {@code scanMode} is invalid.
*/
public Builder setScanMode(int scanMode) {
- if (scanMode < SCAN_MODE_LOW_POWER || scanMode > SCAN_MODE_LOW_LATENCY) {
+ if (scanMode < SCAN_MODE_OPPORTUNISTIC || scanMode > SCAN_MODE_LOW_LATENCY) {
throw new IllegalArgumentException("invalid scan mode " + scanMode);
}
mScanMode = scanMode;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 39a70be..e9d4e59 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2149,7 +2149,7 @@ public abstract class Context {
CONNECTIVITY_SERVICE,
//@hide: UPDATE_LOCK_SERVICE,
//@hide: NETWORKMANAGEMENT_SERVICE,
- //@hide: NETWORK_STATS_SERVICE,
+ NETWORK_STATS_SERVICE,
//@hide: NETWORK_POLICY_SERVICE,
WIFI_SERVICE,
WIFI_PASSPOINT_SERVICE,
@@ -2259,6 +2259,9 @@ public abstract class Context {
* <dd> A {@link android.os.BatteryManager} for managing battery state
* <dt> {@link #JOB_SCHEDULER_SERVICE} ("taskmanager")
* <dd> A {@link android.app.job.JobScheduler} for managing scheduled tasks
+ * <dt> {@link #NETWORK_STATS_SERVICE} ("netstats")
+ * <dd> A {@link android.app.usage.NetworkStatsManager NetworkStatsManager} for querying network
+ * usage statistics.
* </dl>
*
* <p>Note: System services obtained via this API may be closely associated with
@@ -2316,6 +2319,8 @@ public abstract class Context {
* @see android.os.BatteryManager
* @see #JOB_SCHEDULER_SERVICE
* @see android.app.job.JobScheduler
+ * @see #NETWORK_STATS_SERVICE
+ * @see android.app.usage.NetworkStatsManager
*/
public abstract Object getSystemService(@ServiceName @NonNull String name);
@@ -2334,7 +2339,8 @@ public abstract class Context {
* {@link android.telephony.TelephonyManager}, {@link android.telephony.SubscriptionManager},
* {@link android.view.inputmethod.InputMethodManager},
* {@link android.app.UiModeManager}, {@link android.app.DownloadManager},
- * {@link android.os.BatteryManager}, {@link android.app.job.JobScheduler}.
+ * {@link android.os.BatteryManager}, {@link android.app.job.JobScheduler},
+ * {@link android.app.usage.NetworkStatsManager}.
* </p><p>
* Note: System services obtained via this API may be closely associated with
* the Context in which they are obtained from. In general, do not share the
@@ -2563,7 +2569,13 @@ public abstract class Context {
*/
public static final String NETWORKMANAGEMENT_SERVICE = "network_management";
- /** {@hide} */
+ /**
+ * Use with {@link #getSystemService} to retrieve a {@link
+ * android.app.usage.NetworkStatsManager} for querying network usage stats.
+ *
+ * @see #getSystemService
+ * @see android.app.usage.NetworkStatsManager
+ */
public static final String NETWORK_STATS_SERVICE = "netstats";
/** {@hide} */
public static final String NETWORK_POLICY_SERVICE = "netpolicy";
@@ -2819,7 +2831,7 @@ public abstract class Context {
/**
* Use with {@link #getSystemService} to retrieve a
- * {@link android.bluetooth.BluetoothAdapter} for using Bluetooth.
+ * {@link android.bluetooth.BluetoothManager} for using Bluetooth.
*
* @see #getSystemService
*/
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 9be96a1..030b770 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1502,6 +1502,66 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final String METADATA_SETUP_VERSION = "android.SETUP_VERSION";
+ /**
+ * Activity action: Launch UI to manage the permissions of an app.
+ * <p>
+ * Input: {@link #EXTRA_PACKAGE_NAME} specifies the package whose permissions
+ * will be managed by the launched UI.
+ * </p>
+ * <p>
+ * Output: Nothing.
+ * </p>
+ *
+ * @see #EXTRA_PACKAGE_NAME
+ *
+ * @hide
+ */
+ @SystemApi
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MANAGE_APP_PERMISSIONS =
+ "android.intent.action.MANAGE_APP_PERMISSIONS";
+
+ /**
+ * Intent extra: An app package name.
+ * <p>
+ * Type: String
+ * </p>S
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_PACKAGE_NAME = "android.intent.extra.PACKAGE_NAME";
+
+ /**
+ * Activity action: Launch UI to manage which apps have a given permission.
+ * <p>
+ * Input: {@link #EXTRA_PERMISSION_NAME} specifies the permission access
+ * to which will be managed by the launched UI.
+ * </p>
+ * <p>
+ * Output: Nothing.
+ * </p>
+ *
+ * @see #EXTRA_PERMISSION_NAME
+ *
+ * @hide
+ */
+ @SystemApi
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MANAGE_PERMISSION_APPS =
+ "android.intent.action.MANAGE_PERMISSION_APPS";
+
+ /**
+ * Intent extra: The name of a permission.
+ * <p>
+ * Type: String
+ * </p>
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Standard intent broadcast actions (see action variable).
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 8f17845..2496e45 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -340,8 +340,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* cleartext network traffic, in which case platform components (e.g., HTTP stacks,
* {@code WebView}, {@code MediaPlayer}) will refuse app's requests to use cleartext traffic.
* Third-party libraries are encouraged to honor this flag as well.
- *
- * @hide
*/
public static final int FLAG_USES_CLEARTEXT_TRAFFIC = 1<<27;
@@ -379,7 +377,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* {@link #FLAG_LARGE_HEAP}, {@link #FLAG_STOPPED},
* {@link #FLAG_SUPPORTS_RTL}, {@link #FLAG_INSTALLED},
* {@link #FLAG_IS_DATA_ONLY}, {@link #FLAG_IS_GAME},
- * {@link #FLAG_FULL_BACKUP_ONLY}, {@link #FLAG_MULTIARCH}.
+ * {@link #FLAG_FULL_BACKUP_ONLY}, {@link #FLAG_USES_CLEARTEXT_TRAFFIC},
+ * {@link #FLAG_MULTIARCH}.
*/
public int flags = 0;
@@ -655,7 +654,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
}
pw.println(prefix + "dataDir=" + dataDir);
if (sharedLibraryFiles != null) {
- pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles);
+ pw.println(prefix + "sharedLibraryFiles=" + Arrays.toString(sharedLibraryFiles));
}
pw.println(prefix + "enabled=" + enabled + " targetSdkVersion=" + targetSdkVersion
+ " versionCode=" + versionCode);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e5859d0..212cf6d 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -376,16 +376,6 @@ public class PackageParser {
return path.endsWith(".apk");
}
- /*
- public static PackageInfo generatePackageInfo(PackageParser.Package p,
- int gids[], int flags, long firstInstallTime, long lastUpdateTime,
- HashSet<String> grantedPermissions) {
- PackageUserState state = new PackageUserState();
- return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime,
- grantedPermissions, state, UserHandle.getCallingUserId());
- }
- */
-
/**
* Generate and return the {@link PackageInfo} for a parsed package.
*
@@ -394,7 +384,7 @@ public class PackageParser {
*/
public static PackageInfo generatePackageInfo(PackageParser.Package p,
int gids[], int flags, long firstInstallTime, long lastUpdateTime,
- ArraySet<String> grantedPermissions, PackageUserState state) {
+ Set<String> grantedPermissions, PackageUserState state) {
return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime,
grantedPermissions, state, UserHandle.getCallingUserId());
@@ -574,7 +564,7 @@ public class PackageParser {
for (int i=0; i<N; i++) {
final String perm = p.requestedPermissions.get(i);
pi.requestedPermissions[i] = perm;
- // The notion of requried permissions is deprecated but for compatibility.
+ // The notion of required permissions is deprecated but for compatibility.
pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_REQUIRED;
if (grantedPermissions != null && grantedPermissions.contains(perm)) {
pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_GRANTED;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 95ad57e..44018ff 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -111,12 +111,12 @@ public class Resources {
// single-threaded, and after that these are immutable.
private static final LongSparseArray<ConstantState>[] sPreloadedDrawables;
private static final LongSparseArray<ConstantState> sPreloadedColorDrawables
- = new LongSparseArray<ConstantState>();
+ = new LongSparseArray<>();
private static final LongSparseArray<ColorStateListFactory> sPreloadedColorStateLists
- = new LongSparseArray<ColorStateListFactory>();
+ = new LongSparseArray<>();
// Pool of TypedArrays targeted to this Resources object.
- final SynchronizedPool<TypedArray> mTypedArrayPool = new SynchronizedPool<TypedArray>(5);
+ final SynchronizedPool<TypedArray> mTypedArrayPool = new SynchronizedPool<>(5);
// Used by BridgeResources in layoutlib
static Resources mSystem = null;
@@ -128,21 +128,19 @@ public class Resources {
private final Object mAccessLock = new Object();
private final Configuration mTmpConfig = new Configuration();
private final ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> mDrawableCache =
- new ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>>();
+ new ArrayMap<>();
private final ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> mColorDrawableCache =
- new ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>>();
+ new ArrayMap<>();
private final ConfigurationBoundResourceCache<ColorStateList> mColorStateListCache =
- new ConfigurationBoundResourceCache<ColorStateList>(this);
+ new ConfigurationBoundResourceCache<>(this);
private final ConfigurationBoundResourceCache<Animator> mAnimatorCache =
- new ConfigurationBoundResourceCache<Animator>(this);
+ new ConfigurationBoundResourceCache<>(this);
private final ConfigurationBoundResourceCache<StateListAnimator> mStateListAnimatorCache =
- new ConfigurationBoundResourceCache<StateListAnimator>(this);
+ new ConfigurationBoundResourceCache<>(this);
private TypedValue mTmpValue = new TypedValue();
private boolean mPreloading;
- private TypedArray mCachedStyledAttributes = null;
-
private int mLastCachedXmlBlockIndex = -1;
private final int[] mCachedXmlBlockIds = { 0, 0, 0, 0 };
private final XmlBlock[] mCachedXmlBlocks = new XmlBlock[4];
@@ -157,8 +155,8 @@ public class Resources {
static {
sPreloadedDrawables = new LongSparseArray[2];
- sPreloadedDrawables[0] = new LongSparseArray<ConstantState>();
- sPreloadedDrawables[1] = new LongSparseArray<ConstantState>();
+ sPreloadedDrawables[0] = new LongSparseArray<>();
+ sPreloadedDrawables[1] = new LongSparseArray<>();
}
/**
@@ -1876,7 +1874,7 @@ public class Resources {
// the framework.
mCompatibilityInfo.applyToDisplayMetrics(mMetrics);
- int configChanges = calcConfigChanges(config);
+ final int configChanges = calcConfigChanges(config);
if (mConfiguration.locale == null) {
mConfiguration.locale = Locale.getDefault();
mConfiguration.setLayoutDirection(mConfiguration.locale);
@@ -1891,7 +1889,8 @@ public class Resources {
if (mConfiguration.locale != null) {
locale = adjustLanguageTag(mConfiguration.locale.toLanguageTag());
}
- int width, height;
+
+ final int width, height;
if (mMetrics.widthPixels >= mMetrics.heightPixels) {
width = mMetrics.widthPixels;
height = mMetrics.heightPixels;
@@ -1901,12 +1900,15 @@ public class Resources {
//noinspection SuspiciousNameCombination
height = mMetrics.widthPixels;
}
- int keyboardHidden = mConfiguration.keyboardHidden;
- if (keyboardHidden == Configuration.KEYBOARDHIDDEN_NO
- && mConfiguration.hardKeyboardHidden
- == Configuration.HARDKEYBOARDHIDDEN_YES) {
+
+ final int keyboardHidden;
+ if (mConfiguration.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO
+ && mConfiguration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
keyboardHidden = Configuration.KEYBOARDHIDDEN_SOFT;
+ } else {
+ keyboardHidden = mConfiguration.keyboardHidden;
}
+
mAssets.setConfiguration(mConfiguration.mcc, mConfiguration.mnc,
locale, mConfiguration.orientation,
mConfiguration.touchscreen,
@@ -2508,10 +2510,10 @@ public class Resources {
// Clean out the caches before we add more. This shouldn't
// happen very often.
pruneCaches(caches);
- themedCache = new LongSparseArray<WeakReference<ConstantState>>(1);
+ themedCache = new LongSparseArray<>(1);
caches.put(themeKey, themedCache);
}
- themedCache.put(key, new WeakReference<ConstantState>(cs));
+ themedCache.put(key, new WeakReference<>(cs));
}
}
}
@@ -2830,15 +2832,6 @@ public class Resources {
+ Integer.toHexString(id));
}
- /*package*/ void recycleCachedStyledAttributes(TypedArray attrs) {
- synchronized (mAccessLock) {
- final TypedArray cached = mCachedStyledAttributes;
- if (cached == null || cached.mData.length < attrs.mData.length) {
- mCachedStyledAttributes = attrs;
- }
- }
- }
-
/**
* Obtains styled attributes from the theme, if available, or unstyled
* resources if the theme is null.
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index a6c3ea4..88fa339 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -54,11 +54,13 @@ public class SystemSensorManager extends SensorManager {
// Looper associated with the context in which this instance was created.
private final Looper mMainLooper;
private final int mTargetSdkLevel;
+ private final String mPackageName;
/** {@hide} */
public SystemSensorManager(Context context, Looper mainLooper) {
mMainLooper = mainLooper;
mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
+ mPackageName = context.getPackageName();
synchronized(sSensorModuleLock) {
if (!sSensorModuleInitialized) {
sSensorModuleInitialized = true;
@@ -117,14 +119,14 @@ public class SystemSensorManager extends SensorManager {
if (queue == null) {
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
queue = new SensorEventQueue(listener, looper, this);
- if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) {
+ if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
}
mSensorListeners.put(listener, queue);
return true;
} else {
- return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags);
+ return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
}
}
}
@@ -165,14 +167,14 @@ public class SystemSensorManager extends SensorManager {
TriggerEventQueue queue = mTriggerListeners.get(listener);
if (queue == null) {
queue = new TriggerEventQueue(listener, mMainLooper, this);
- if (!queue.addSensor(sensor, 0, 0, 0)) {
+ if (!queue.addSensor(sensor, 0, 0)) {
queue.dispose();
return false;
}
mTriggerListeners.put(listener, queue);
return true;
} else {
- return queue.addSensor(sensor, 0, 0, 0);
+ return queue.addSensor(sensor, 0, 0);
}
}
}
@@ -223,9 +225,9 @@ public class SystemSensorManager extends SensorManager {
*/
private static abstract class BaseEventQueue {
private native long nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ,
- float[] scratch);
+ float[] scratch, String packageName);
private static native int nativeEnableSensor(long eventQ, int handle, int rateUs,
- int maxBatchReportLatencyUs, int reservedFlags);
+ int maxBatchReportLatencyUs);
private static native int nativeDisableSensor(long eventQ, int handle);
private static native void nativeDestroySensorEventQueue(long eventQ);
private static native int nativeFlushSensor(long eventQ);
@@ -238,7 +240,8 @@ public class SystemSensorManager extends SensorManager {
protected final SystemSensorManager mManager;
BaseEventQueue(Looper looper, SystemSensorManager manager) {
- nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch);
+ nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch,
+ manager.mPackageName);
mCloseGuard.open("dispose");
mManager = manager;
}
@@ -248,7 +251,7 @@ public class SystemSensorManager extends SensorManager {
}
public boolean addSensor(
- Sensor sensor, int delayUs, int maxBatchReportLatencyUs, int reservedFlags) {
+ Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
// Check if already present.
int handle = sensor.getHandle();
if (mActiveSensors.get(handle)) return false;
@@ -256,10 +259,10 @@ public class SystemSensorManager extends SensorManager {
// Get ready to receive events before calling enable.
mActiveSensors.put(handle, true);
addSensorEvent(sensor);
- if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags) != 0) {
+ if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
// Try continuous mode if batching fails.
if (maxBatchReportLatencyUs == 0 ||
- maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0, 0) != 0) {
+ maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
removeSensor(sensor, false);
return false;
}
@@ -328,11 +331,11 @@ public class SystemSensorManager extends SensorManager {
}
private int enableSensor(
- Sensor sensor, int rateUs, int maxBatchReportLatencyUs, int reservedFlags) {
+ Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
if (nSensorEventQueue == 0) throw new NullPointerException();
if (sensor == null) throw new NullPointerException();
return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), rateUs,
- maxBatchReportLatencyUs, reservedFlags);
+ maxBatchReportLatencyUs);
}
private int disableSensor(Sensor sensor) {
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 34a0727..a0e2bf8 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2337,7 +2337,7 @@ public class ConnectivityManager {
* successfully finding a network for the applications request. Retrieve it with
* {@link android.content.Intent#getParcelableExtra(String)}.
* <p>
- * Note that if you intend to invoke (@link #setProcessDefaultNetwork(Network)) or
+ * Note that if you intend to invoke {@link #setProcessDefaultNetwork} or
* {@link Network#openConnection(java.net.URL)} then you must get a
* ConnectivityManager instance before doing so.
*/
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index 2c3881c..6436e42 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -27,6 +27,14 @@ interface INetworkStatsService {
/** Start a statistics query session. */
INetworkStatsSession openSession();
+ /** Start a statistics query session. If calling package is profile or device owner then it is
+ * granted automatic access if apiLevel is NetworkStatsManager.API_LEVEL_DPC_ALLOWED. If
+ * apiLevel is at least NetworkStatsManager.API_LEVEL_REQUIRES_PACKAGE_USAGE_STATS then
+ * PACKAGE_USAGE_STATS permission is always checked. If PACKAGE_USAGE_STATS is not granted
+ * READ_NETWORK_USAGE_STATS is checked for.
+ */
+ INetworkStatsSession openSessionForUsageStats(String callingPackage);
+
/** Return network layer usage total for traffic that matches template. */
long getNetworkTotalBytes(in NetworkTemplate template, long start, long end);
diff --git a/core/java/android/net/INetworkStatsSession.aidl b/core/java/android/net/INetworkStatsSession.aidl
index 1596fa2..7bcb043 100644
--- a/core/java/android/net/INetworkStatsSession.aidl
+++ b/core/java/android/net/INetworkStatsSession.aidl
@@ -23,6 +23,9 @@ import android.net.NetworkTemplate;
/** {@hide} */
interface INetworkStatsSession {
+ /** Return device aggregated network layer usage summary for traffic that matches template. */
+ NetworkStats getDeviceSummaryForNetwork(in NetworkTemplate template, long start, long end);
+
/** Return network layer usage summary for traffic that matches template. */
NetworkStats getSummaryForNetwork(in NetworkTemplate template, long start, long end);
/** Return historical network layer stats for traffic that matches template. */
@@ -33,6 +36,9 @@ interface INetworkStatsSession {
/** Return historical network layer stats for specific UID traffic that matches template. */
NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int set, int tag, int fields);
+ /** Return array of uids that have stats and are accessible to the calling user */
+ int[] getRelevantUids();
+
void close();
}
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index a7f9c5b..8c8bfab 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -148,9 +148,9 @@ public final class NetworkCapabilities implements Parcelable {
*/
public static final int NET_CAPABILITY_TRUSTED = 14;
- /*
+ /**
* Indicates that this network is not a VPN. This capability is set by default and should be
- * explicitly cleared when creating VPN networks.
+ * explicitly cleared for VPN networks.
*/
public static final int NET_CAPABILITY_NOT_VPN = 15;
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 0766253..77d7e0c 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -50,12 +50,19 @@ public class NetworkStats implements Parcelable {
public static final int UID_ALL = -1;
/** {@link #tag} value matching any tag. */
public static final int TAG_ALL = -1;
- /** {@link #set} value when all sets combined. */
+ /** {@link #set} value when all sets combined, not including debug sets. */
public static final int SET_ALL = -1;
/** {@link #set} value where background data is accounted. */
public static final int SET_DEFAULT = 0;
/** {@link #set} value where foreground data is accounted. */
public static final int SET_FOREGROUND = 1;
+ /** All {@link #set} value greater than SET_DEBUG_START are debug {@link #set} values. */
+ public static final int SET_DEBUG_START = 1000;
+ /** Debug {@link #set} value when the VPN stats are moved in. */
+ public static final int SET_DBG_VPN_IN = 1001;
+ /** Debug {@link #set} value when the VPN stats are moved out of a vpn UID. */
+ public static final int SET_DBG_VPN_OUT = 1002;
+
/** {@link #tag} value for total data across all tags. */
public static final int TAG_NONE = 0;
@@ -729,6 +736,10 @@ public class NetworkStats implements Parcelable {
return "DEFAULT";
case SET_FOREGROUND:
return "FOREGROUND";
+ case SET_DBG_VPN_IN:
+ return "DBG_VPN_IN";
+ case SET_DBG_VPN_OUT:
+ return "DBG_VPN_OUT";
default:
return "UNKNOWN";
}
@@ -745,12 +756,27 @@ public class NetworkStats implements Parcelable {
return "def";
case SET_FOREGROUND:
return "fg";
+ case SET_DBG_VPN_IN:
+ return "vpnin";
+ case SET_DBG_VPN_OUT:
+ return "vpnout";
default:
return "unk";
}
}
/**
+ * @return true if the querySet matches the dataSet.
+ */
+ public static boolean setMatches(int querySet, int dataSet) {
+ if (querySet == dataSet) {
+ return true;
+ }
+ // SET_ALL matches all non-debugging sets.
+ return querySet == SET_ALL && dataSet < SET_DEBUG_START;
+ }
+
+ /**
* Return text description of {@link #tag} value.
*/
public static String tagToString(int tag) {
@@ -843,6 +869,9 @@ public class NetworkStats implements Parcelable {
if (recycle.uid == UID_ALL) {
throw new IllegalStateException(
"Cannot adjust VPN accounting on an iface aggregated NetworkStats.");
+ } if (recycle.set == SET_DBG_VPN_IN || recycle.set == SET_DBG_VPN_OUT) {
+ throw new IllegalStateException(
+ "Cannot adjust VPN accounting on a NetworkStats containing SET_DBG_VPN_*");
}
if (recycle.uid == tunUid && recycle.tag == TAG_NONE
@@ -906,6 +935,9 @@ public class NetworkStats implements Parcelable {
combineValues(tmpEntry);
if (tag[i] == TAG_NONE) {
moved.add(tmpEntry);
+ // Add debug info
+ tmpEntry.set = SET_DBG_VPN_IN;
+ combineValues(tmpEntry);
}
}
}
@@ -913,6 +945,13 @@ public class NetworkStats implements Parcelable {
}
private void deductTrafficFromVpnApp(int tunUid, String underlyingIface, Entry moved) {
+ // Add debug info
+ moved.uid = tunUid;
+ moved.set = SET_DBG_VPN_OUT;
+ moved.tag = TAG_NONE;
+ moved.iface = underlyingIface;
+ combineValues(moved);
+
// Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
// the TAG_NONE traffic.
int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE);
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 26e6b85..8b3ecae 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -29,6 +29,7 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.telephony.SignalStrength;
import android.text.format.DateFormat;
+import android.util.ArrayMap;
import android.util.Printer;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -283,21 +284,21 @@ public abstract class BatteryStats implements Parcelable {
*
* @return a Map from Strings to Uid.Wakelock objects.
*/
- public abstract Map<String, ? extends Wakelock> getWakelockStats();
+ public abstract ArrayMap<String, ? extends Wakelock> getWakelockStats();
/**
* Returns a mapping containing sync statistics.
*
* @return a Map from Strings to Timer objects.
*/
- public abstract Map<String, ? extends Timer> getSyncStats();
+ public abstract ArrayMap<String, ? extends Timer> getSyncStats();
/**
* Returns a mapping containing scheduled job statistics.
*
* @return a Map from Strings to Timer objects.
*/
- public abstract Map<String, ? extends Timer> getJobStats();
+ public abstract ArrayMap<String, ? extends Timer> getJobStats();
/**
* The statistics associated with a particular wake lock.
@@ -323,14 +324,14 @@ public abstract class BatteryStats implements Parcelable {
*
* @return a Map from Strings to Uid.Proc objects.
*/
- public abstract Map<String, ? extends Proc> getProcessStats();
+ public abstract ArrayMap<String, ? extends Proc> getProcessStats();
/**
* Returns a mapping containing package statistics.
*
* @return a Map from Strings to Uid.Pkg objects.
*/
- public abstract Map<String, ? extends Pkg> getPackageStats();
+ public abstract ArrayMap<String, ? extends Pkg> getPackageStats();
/**
* {@hide}
@@ -501,17 +502,16 @@ public abstract class BatteryStats implements Parcelable {
public static abstract class Pkg {
/**
- * Returns the number of times this package has done something that could wake up the
- * device from sleep.
- *
- * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
+ * Returns information about all wakeup alarms that have been triggered for this
+ * package. The mapping keys are tag names for the alarms, the counter contains
+ * the number of times the alarm was triggered while on battery.
*/
- public abstract int getWakeups(int which);
+ public abstract ArrayMap<String, ? extends Counter> getWakeupAlarmStats();
/**
* Returns a mapping containing service statistics.
*/
- public abstract Map<String, ? extends Serv> getServiceStats();
+ public abstract ArrayMap<String, ? extends Serv> getServiceStats();
/**
* The statistics associated with a particular service.
@@ -1352,7 +1352,7 @@ public abstract class BatteryStats implements Parcelable {
int idx = code&HistoryItem.EVENT_TYPE_MASK;
HashMap<String, SparseIntArray> active = mActiveEvents[idx];
if (active == null) {
- active = new HashMap<String, SparseIntArray>();
+ active = new HashMap<>();
mActiveEvents[idx] = active;
}
SparseIntArray uids = active.get(name);
@@ -2382,12 +2382,12 @@ public abstract class BatteryStats implements Parcelable {
final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which);
- StringBuilder sb = new StringBuilder(128);
+ final StringBuilder sb = new StringBuilder(128);
- SparseArray<? extends Uid> uidStats = getUidStats();
+ final SparseArray<? extends Uid> uidStats = getUidStats();
final int NU = uidStats.size();
- String category = STAT_NAMES[which];
+ final String category = STAT_NAMES[which];
// Dump "battery" stat
dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
@@ -2402,37 +2402,35 @@ public abstract class BatteryStats implements Parcelable {
long partialWakeLockTimeTotal = 0;
for (int iu = 0; iu < NU; iu++) {
- Uid u = uidStats.valueAt(iu);
-
- Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
- if (wakelocks.size() > 0) {
- for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
- : wakelocks.entrySet()) {
- Uid.Wakelock wl = ent.getValue();
-
- Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
- if (fullWakeTimer != null) {
- fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime,
- which);
- }
+ final Uid u = uidStats.valueAt(iu);
- Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
- if (partialWakeTimer != null) {
- partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
- rawRealtime, which);
- }
+ final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
+ = u.getWakelockStats();
+ for (int iw=wakelocks.size()-1; iw>=0; iw--) {
+ final Uid.Wakelock wl = wakelocks.valueAt(iw);
+
+ final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
+ if (fullWakeTimer != null) {
+ fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime,
+ which);
+ }
+
+ final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
+ if (partialWakeTimer != null) {
+ partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
+ rawRealtime, which);
}
}
}
- long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
- long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
- long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
- long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
- long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
- long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
- long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
- long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
+ final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
+ final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
+ final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
+ final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
+ final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
+ final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+ final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
+ final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
// Dump network stats
dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA,
@@ -2544,7 +2542,7 @@ public abstract class BatteryStats implements Parcelable {
}
if (reqUid < 0) {
- Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
+ final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
if (kernelWakelocks.size() > 0) {
for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
sb.setLength(0);
@@ -2553,7 +2551,7 @@ public abstract class BatteryStats implements Parcelable {
sb.toString());
}
}
- Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
+ final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
if (wakeupReasons.size() > 0) {
for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
// Not doing the regular wake lock formatting to remain compatible
@@ -2566,10 +2564,10 @@ public abstract class BatteryStats implements Parcelable {
}
}
- BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
+ final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
helper.create(this);
helper.refreshStats(which, UserHandle.USER_ALL);
- List<BatterySipper> sippers = helper.getUsageList();
+ final List<BatterySipper> sippers = helper.getUsageList();
if (sippers != null && sippers.size() > 0) {
dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
@@ -2577,7 +2575,7 @@ public abstract class BatteryStats implements Parcelable {
BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
for (int i=0; i<sippers.size(); i++) {
- BatterySipper bs = sippers.get(i);
+ final BatterySipper bs = sippers.get(i);
int uid = 0;
String label;
switch (bs.drainType) {
@@ -2629,22 +2627,22 @@ public abstract class BatteryStats implements Parcelable {
if (reqUid >= 0 && uid != reqUid) {
continue;
}
- Uid u = uidStats.valueAt(iu);
+ final Uid u = uidStats.valueAt(iu);
// Dump Network stats per uid, if any
- long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
- long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
- long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
- long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
- long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
- long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
- long mobileActiveTime = u.getMobileRadioActiveTime(which);
- int mobileActiveCount = u.getMobileRadioActiveCount(which);
- long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
- long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
- long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
- long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
- int wifiScanCount = u.getWifiScanCount(which);
- long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
+ final long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
+ final long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
+ final long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
+ final long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
+ final long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
+ final long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+ final long mobileActiveTime = u.getMobileRadioActiveTime(which);
+ final int mobileActiveCount = u.getMobileRadioActiveCount(which);
+ final long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
+ final long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
+ final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
+ final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
+ final int wifiScanCount = u.getWifiScanCount(which);
+ final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
|| mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
@@ -2675,93 +2673,90 @@ public abstract class BatteryStats implements Parcelable {
}
}
- Map<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
- if (wakelocks.size() > 0) {
- for (Map.Entry<String, ? extends Uid.Wakelock> ent : wakelocks.entrySet()) {
- Uid.Wakelock wl = ent.getValue();
- String linePrefix = "";
- sb.setLength(0);
- linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
- rawRealtime, "f", which, linePrefix);
- linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
- rawRealtime, "p", which, linePrefix);
- linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
- rawRealtime, "w", which, linePrefix);
-
- // Only log if we had at lease one wakelock...
- if (sb.length() > 0) {
- String name = ent.getKey();
- if (name.indexOf(',') >= 0) {
- name = name.replace(',', '_');
- }
- dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
+ final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
+ for (int iw=wakelocks.size()-1; iw>=0; iw--) {
+ final Uid.Wakelock wl = wakelocks.valueAt(iw);
+ String linePrefix = "";
+ sb.setLength(0);
+ linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
+ rawRealtime, "f", which, linePrefix);
+ linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
+ rawRealtime, "p", which, linePrefix);
+ linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
+ rawRealtime, "w", which, linePrefix);
+
+ // Only log if we had at lease one wakelock...
+ if (sb.length() > 0) {
+ String name = wakelocks.keyAt(iw);
+ if (name.indexOf(',') >= 0) {
+ name = name.replace(',', '_');
}
+ dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
}
}
- Map<String, ? extends Timer> syncs = u.getSyncStats();
- if (syncs.size() > 0) {
- for (Map.Entry<String, ? extends Timer> ent : syncs.entrySet()) {
- Timer timer = ent.getValue();
- // Convert from microseconds to milliseconds with rounding
- long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
- int count = timer.getCountLocked(which);
- if (totalTime != 0) {
- dumpLine(pw, uid, category, SYNC_DATA, ent.getKey(), totalTime, count);
- }
+ final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
+ for (int isy=syncs.size()-1; isy>=0; isy--) {
+ final Timer timer = syncs.valueAt(isy);
+ // Convert from microseconds to milliseconds with rounding
+ final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+ final int count = timer.getCountLocked(which);
+ if (totalTime != 0) {
+ dumpLine(pw, uid, category, SYNC_DATA, syncs.keyAt(isy), totalTime, count);
}
}
- Map<String, ? extends Timer> jobs = u.getJobStats();
- if (jobs.size() > 0) {
- for (Map.Entry<String, ? extends Timer> ent : jobs.entrySet()) {
- Timer timer = ent.getValue();
- // Convert from microseconds to milliseconds with rounding
- long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
- int count = timer.getCountLocked(which);
- if (totalTime != 0) {
- dumpLine(pw, uid, category, JOB_DATA, ent.getKey(), totalTime, count);
- }
+ final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
+ for (int ij=jobs.size()-1; ij>=0; ij--) {
+ final Timer timer = jobs.valueAt(ij);
+ // Convert from microseconds to milliseconds with rounding
+ final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+ final int count = timer.getCountLocked(which);
+ if (totalTime != 0) {
+ dumpLine(pw, uid, category, JOB_DATA, jobs.keyAt(ij), totalTime, count);
}
}
- SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
- int NSE = sensors.size();
+ final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
+ final int NSE = sensors.size();
for (int ise=0; ise<NSE; ise++) {
- Uid.Sensor se = sensors.valueAt(ise);
- int sensorNumber = sensors.keyAt(ise);
- Timer timer = se.getSensorTime();
+ final Uid.Sensor se = sensors.valueAt(ise);
+ final int sensorNumber = sensors.keyAt(ise);
+ final Timer timer = se.getSensorTime();
if (timer != null) {
// Convert from microseconds to milliseconds with rounding
- long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
- int count = timer.getCountLocked(which);
+ final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500)
+ / 1000;
+ final int count = timer.getCountLocked(which);
if (totalTime != 0) {
dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
}
}
}
- Timer vibTimer = u.getVibratorOnTimer();
+ final Timer vibTimer = u.getVibratorOnTimer();
if (vibTimer != null) {
// Convert from microseconds to milliseconds with rounding
- long totalTime = (vibTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
- int count = vibTimer.getCountLocked(which);
+ final long totalTime = (vibTimer.getTotalTimeLocked(rawRealtime, which) + 500)
+ / 1000;
+ final int count = vibTimer.getCountLocked(which);
if (totalTime != 0) {
dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count);
}
}
- Timer fgTimer = u.getForegroundActivityTimer();
+ final Timer fgTimer = u.getForegroundActivityTimer();
if (fgTimer != null) {
// Convert from microseconds to milliseconds with rounding
- long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
- int count = fgTimer.getCountLocked(which);
+ final long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500)
+ / 1000;
+ final int count = fgTimer.getCountLocked(which);
if (totalTime != 0) {
dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count);
}
}
- Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
+ final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
long totalStateTime = 0;
for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
totalStateTime += u.getProcessStateTime(ips, rawRealtime, which);
@@ -2771,50 +2766,48 @@ public abstract class BatteryStats implements Parcelable {
dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes);
}
- Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
- if (processStats.size() > 0) {
- for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
- : processStats.entrySet()) {
- Uid.Proc ps = ent.getValue();
-
- final long userMillis = ps.getUserTime(which);
- final long systemMillis = ps.getSystemTime(which);
- final long foregroundMillis = ps.getForegroundTime(which);
- final int starts = ps.getStarts(which);
- final int numCrashes = ps.getNumCrashes(which);
- final int numAnrs = ps.getNumAnrs(which);
-
- if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
- || starts != 0 || numAnrs != 0 || numCrashes != 0) {
- dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis,
- systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
- }
+ final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
+ = u.getProcessStats();
+ for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
+ final Uid.Proc ps = processStats.valueAt(ipr);
+
+ final long userMillis = ps.getUserTime(which);
+ final long systemMillis = ps.getSystemTime(which);
+ final long foregroundMillis = ps.getForegroundTime(which);
+ final int starts = ps.getStarts(which);
+ final int numCrashes = ps.getNumCrashes(which);
+ final int numAnrs = ps.getNumAnrs(which);
+
+ if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
+ || starts != 0 || numAnrs != 0 || numCrashes != 0) {
+ dumpLine(pw, uid, category, PROCESS_DATA, processStats.keyAt(ipr), userMillis,
+ systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
}
}
- Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
- if (packageStats.size() > 0) {
- for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
- : packageStats.entrySet()) {
-
- Uid.Pkg ps = ent.getValue();
- int wakeups = ps.getWakeups(which);
- Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
- for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
- : serviceStats.entrySet()) {
- BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
- long startTime = ss.getStartTime(batteryUptime, which);
- int starts = ss.getStarts(which);
- int launches = ss.getLaunches(which);
- if (startTime != 0 || starts != 0 || launches != 0) {
- dumpLine(pw, uid, category, APK_DATA,
- wakeups, // wakeup alarms
- ent.getKey(), // Apk
- sent.getKey(), // service
- startTime / 1000, // time spent started, in ms
- starts,
- launches);
- }
+ final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
+ = u.getPackageStats();
+ for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
+ final Uid.Pkg ps = packageStats.valueAt(ipkg);
+ int wakeups = 0;
+ final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
+ for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
+ wakeups += alarms.valueAt(iwa).getCountLocked(which);
+ }
+ final ArrayMap<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
+ for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
+ final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
+ final long startTime = ss.getStartTime(batteryUptime, which);
+ final int starts = ss.getStarts(which);
+ final int launches = ss.getLaunches(which);
+ if (startTime != 0 || starts != 0 || launches != 0) {
+ dumpLine(pw, uid, category, APK_DATA,
+ wakeups, // wakeup alarms
+ packageStats.keyAt(ipkg), // Apk
+ serviceStats.keyAt(isvc), // service
+ startTime / 1000, // time spent started, in ms
+ starts,
+ launches);
}
}
}
@@ -2863,9 +2856,9 @@ public abstract class BatteryStats implements Parcelable {
final long batteryTimeRemaining = computeBatteryTimeRemaining(rawRealtime);
final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
- StringBuilder sb = new StringBuilder(128);
+ final StringBuilder sb = new StringBuilder(128);
- SparseArray<? extends Uid> uidStats = getUidStats();
+ final SparseArray<? extends Uid> uidStats = getUidStats();
final int NU = uidStats.size();
sb.setLength(0);
@@ -2992,7 +2985,7 @@ public abstract class BatteryStats implements Parcelable {
sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
sb.append(") "); sb.append(getPhoneOnCount(which)); sb.append("x");
}
- int connChanges = getNumConnectivityChange(which);
+ final int connChanges = getNumConnectivityChange(which);
if (connChanges != 0) {
pw.print(prefix);
pw.print(" Connectivity changes: "); pw.println(connChanges);
@@ -3002,50 +2995,48 @@ public abstract class BatteryStats implements Parcelable {
long fullWakeLockTimeTotalMicros = 0;
long partialWakeLockTimeTotalMicros = 0;
- final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
+ final ArrayList<TimerEntry> timers = new ArrayList<>();
for (int iu = 0; iu < NU; iu++) {
- Uid u = uidStats.valueAt(iu);
-
- Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
- if (wakelocks.size() > 0) {
- for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
- : wakelocks.entrySet()) {
- Uid.Wakelock wl = ent.getValue();
-
- Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
- if (fullWakeTimer != null) {
- fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
- rawRealtime, which);
- }
+ final Uid u = uidStats.valueAt(iu);
- Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
- if (partialWakeTimer != null) {
- long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
- rawRealtime, which);
- if (totalTimeMicros > 0) {
- if (reqUid < 0) {
- // Only show the ordered list of all wake
- // locks if the caller is not asking for data
- // about a specific uid.
- timers.add(new TimerEntry(ent.getKey(), u.getUid(),
- partialWakeTimer, totalTimeMicros));
- }
- partialWakeLockTimeTotalMicros += totalTimeMicros;
+ final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
+ = u.getWakelockStats();
+ for (int iw=wakelocks.size()-1; iw>=0; iw--) {
+ final Uid.Wakelock wl = wakelocks.valueAt(iw);
+
+ final Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
+ if (fullWakeTimer != null) {
+ fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
+ rawRealtime, which);
+ }
+
+ final Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
+ if (partialWakeTimer != null) {
+ final long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
+ rawRealtime, which);
+ if (totalTimeMicros > 0) {
+ if (reqUid < 0) {
+ // Only show the ordered list of all wake
+ // locks if the caller is not asking for data
+ // about a specific uid.
+ timers.add(new TimerEntry(wakelocks.keyAt(iw), u.getUid(),
+ partialWakeTimer, totalTimeMicros));
}
+ partialWakeLockTimeTotalMicros += totalTimeMicros;
}
}
}
}
- long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
- long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
- long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
- long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
- long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
- long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
- long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
- long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
+ final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
+ final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
+ final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
+ final long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
+ final long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
+ final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+ final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
+ final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
if (fullWakeLockTimeTotalMicros != 0) {
sb.setLength(0);
@@ -3242,9 +3233,9 @@ public abstract class BatteryStats implements Parcelable {
if (!didOne) sb.append(" (no activity)");
pw.println(sb.toString());
- final long wifiIdleTimeMs = getBluetoothControllerActivity(CONTROLLER_IDLE_TIME, which);
- final long wifiRxTimeMs = getBluetoothControllerActivity(CONTROLLER_RX_TIME, which);
- final long wifiTxTimeMs = getBluetoothControllerActivity(CONTROLLER_TX_TIME, which);
+ final long wifiIdleTimeMs = getWifiControllerActivity(CONTROLLER_IDLE_TIME, which);
+ final long wifiRxTimeMs = getWifiControllerActivity(CONTROLLER_RX_TIME, which);
+ final long wifiTxTimeMs = getWifiControllerActivity(CONTROLLER_TX_TIME, which);
final long wifiTotalTimeMs = wifiIdleTimeMs + wifiRxTimeMs + wifiTxTimeMs;
sb.setLength(0);
@@ -3367,7 +3358,7 @@ public abstract class BatteryStats implements Parcelable {
pw.println();
}
- BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
+ final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
helper.create(this);
helper.refreshStats(which, UserHandle.USER_ALL);
List<BatterySipper> sippers = helper.getUsageList();
@@ -3382,7 +3373,7 @@ public abstract class BatteryStats implements Parcelable {
}
pw.println();
for (int i=0; i<sippers.size(); i++) {
- BatterySipper bs = sippers.get(i);
+ final BatterySipper bs = sippers.get(i);
switch (bs.drainType) {
case IDLE:
pw.print(prefix); pw.print(" Idle: "); printmAh(pw, bs.value);
@@ -3439,7 +3430,7 @@ public abstract class BatteryStats implements Parcelable {
pw.print(prefix); pw.println(" Per-app mobile ms per packet:");
long totalTime = 0;
for (int i=0; i<sippers.size(); i++) {
- BatterySipper bs = sippers.get(i);
+ final BatterySipper bs = sippers.get(i);
sb.setLength(0);
sb.append(prefix); sb.append(" Uid ");
UserHandle.formatUid(sb, bs.uidObj.getUid());
@@ -3476,12 +3467,14 @@ public abstract class BatteryStats implements Parcelable {
};
if (reqUid < 0) {
- Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
+ final Map<String, ? extends BatteryStats.Timer> kernelWakelocks
+ = getKernelWakelockStats();
if (kernelWakelocks.size() > 0) {
- final ArrayList<TimerEntry> ktimers = new ArrayList<TimerEntry>();
- for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
- BatteryStats.Timer timer = ent.getValue();
- long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
+ final ArrayList<TimerEntry> ktimers = new ArrayList<>();
+ for (Map.Entry<String, ? extends BatteryStats.Timer> ent
+ : kernelWakelocks.entrySet()) {
+ final BatteryStats.Timer timer = ent.getValue();
+ final long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
if (totalTimeMillis > 0) {
ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
}
@@ -3490,7 +3483,7 @@ public abstract class BatteryStats implements Parcelable {
Collections.sort(ktimers, timerComparator);
pw.print(prefix); pw.println(" All kernel wake locks:");
for (int i=0; i<ktimers.size(); i++) {
- TimerEntry timer = ktimers.get(i);
+ final TimerEntry timer = ktimers.get(i);
String linePrefix = ": ";
sb.setLength(0);
sb.append(prefix);
@@ -3526,12 +3519,12 @@ public abstract class BatteryStats implements Parcelable {
pw.println();
}
- Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
+ final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats();
if (wakeupReasons.size() > 0) {
pw.print(prefix); pw.println(" All wakeup reasons:");
- final ArrayList<TimerEntry> reasons = new ArrayList<TimerEntry>();
+ final ArrayList<TimerEntry> reasons = new ArrayList<>();
for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) {
- Timer timer = ent.getValue();
+ final Timer timer = ent.getValue();
reasons.add(new TimerEntry(ent.getKey(), 0, timer,
timer.getCountLocked(which)));
}
@@ -3557,7 +3550,7 @@ public abstract class BatteryStats implements Parcelable {
continue;
}
- Uid u = uidStats.valueAt(iu);
+ final Uid u = uidStats.valueAt(iu);
pw.print(prefix);
pw.print(" ");
@@ -3565,20 +3558,20 @@ public abstract class BatteryStats implements Parcelable {
pw.println(":");
boolean uidActivity = false;
- long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
- long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
- long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
- long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
- long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
- long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
- long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
- int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
- long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
- long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
- long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
- long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
- int wifiScanCount = u.getWifiScanCount(which);
- long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
+ final long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
+ final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
+ final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
+ final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
+ final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
+ final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+ final long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
+ final int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
+ final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
+ final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
+ final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
+ final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
+ final int wifiScanCount = u.getWifiScanCount(which);
+ final long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
if (mobileRxBytes > 0 || mobileTxBytes > 0
|| mobileRxPackets > 0 || mobileTxPackets > 0) {
@@ -3636,7 +3629,7 @@ public abstract class BatteryStats implements Parcelable {
if (u.hasUserActivity()) {
boolean hasData = false;
for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
- int val = u.getUserActivityCount(i, which);
+ final int val = u.getUserActivityCount(i, which);
if (val != 0) {
if (!hasData) {
sb.setLength(0);
@@ -3655,125 +3648,121 @@ public abstract class BatteryStats implements Parcelable {
}
}
- Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
- if (wakelocks.size() > 0) {
- long totalFull = 0, totalPartial = 0, totalWindow = 0;
- int count = 0;
- for (Map.Entry<String, ? extends Uid.Wakelock> ent : wakelocks.entrySet()) {
- Uid.Wakelock wl = ent.getValue();
- String linePrefix = ": ";
+ final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelocks
+ = u.getWakelockStats();
+ long totalFullWakelock = 0, totalPartialWakelock = 0, totalWindowWakelock = 0;
+ int countWakelock = 0;
+ for (int iw=wakelocks.size()-1; iw>=0; iw--) {
+ final Uid.Wakelock wl = wakelocks.valueAt(iw);
+ String linePrefix = ": ";
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Wake lock ");
+ sb.append(wakelocks.keyAt(iw));
+ linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
+ "full", which, linePrefix);
+ linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime,
+ "partial", which, linePrefix);
+ linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
+ "window", which, linePrefix);
+ if (true || !linePrefix.equals(": ")) {
+ sb.append(" realtime");
+ // Only print out wake locks that were held
+ pw.println(sb.toString());
+ uidActivity = true;
+ countWakelock++;
+ }
+ totalFullWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
+ rawRealtime, which);
+ totalPartialWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
+ rawRealtime, which);
+ totalWindowWakelock += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
+ rawRealtime, which);
+ }
+ if (countWakelock > 1) {
+ if (totalFullWakelock != 0 || totalPartialWakelock != 0
+ || totalWindowWakelock != 0) {
sb.setLength(0);
sb.append(prefix);
- sb.append(" Wake lock ");
- sb.append(ent.getKey());
- linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
- "full", which, linePrefix);
- linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime,
- "partial", which, linePrefix);
- linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
- "window", which, linePrefix);
- if (true || !linePrefix.equals(": ")) {
- sb.append(" realtime");
- // Only print out wake locks that were held
- pw.println(sb.toString());
- uidActivity = true;
- count++;
+ sb.append(" TOTAL wake: ");
+ boolean needComma = false;
+ if (totalFullWakelock != 0) {
+ needComma = true;
+ formatTimeMs(sb, totalFullWakelock);
+ sb.append("full");
}
- totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
- rawRealtime, which);
- totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
- rawRealtime, which);
- totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
- rawRealtime, which);
- }
- if (count > 1) {
- if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) {
- sb.setLength(0);
- sb.append(prefix);
- sb.append(" TOTAL wake: ");
- boolean needComma = false;
- if (totalFull != 0) {
- needComma = true;
- formatTimeMs(sb, totalFull);
- sb.append("full");
- }
- if (totalPartial != 0) {
- if (needComma) {
- sb.append(", ");
- }
- needComma = true;
- formatTimeMs(sb, totalPartial);
- sb.append("partial");
+ if (totalPartialWakelock != 0) {
+ if (needComma) {
+ sb.append(", ");
}
- if (totalWindow != 0) {
- if (needComma) {
- sb.append(", ");
- }
- needComma = true;
- formatTimeMs(sb, totalWindow);
- sb.append("window");
+ needComma = true;
+ formatTimeMs(sb, totalPartialWakelock);
+ sb.append("partial");
+ }
+ if (totalWindowWakelock != 0) {
+ if (needComma) {
+ sb.append(", ");
}
- sb.append(" realtime");
- pw.println(sb.toString());
+ needComma = true;
+ formatTimeMs(sb, totalWindowWakelock);
+ sb.append("window");
}
+ sb.append(" realtime");
+ pw.println(sb.toString());
}
}
- Map<String, ? extends Timer> syncs = u.getSyncStats();
- if (syncs.size() > 0) {
- for (Map.Entry<String, ? extends Timer> ent : syncs.entrySet()) {
- Timer timer = ent.getValue();
- // Convert from microseconds to milliseconds with rounding
- long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
- int count = timer.getCountLocked(which);
- sb.setLength(0);
- sb.append(prefix);
- sb.append(" Sync ");
- sb.append(ent.getKey());
- sb.append(": ");
- if (totalTime != 0) {
- formatTimeMs(sb, totalTime);
- sb.append("realtime (");
- sb.append(count);
- sb.append(" times)");
- } else {
- sb.append("(not used)");
- }
- pw.println(sb.toString());
- uidActivity = true;
+ final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
+ for (int isy=syncs.size()-1; isy>=0; isy--) {
+ final Timer timer = syncs.valueAt(isy);
+ // Convert from microseconds to milliseconds with rounding
+ final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+ final int count = timer.getCountLocked(which);
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Sync ");
+ sb.append(syncs.keyAt(isy));
+ sb.append(": ");
+ if (totalTime != 0) {
+ formatTimeMs(sb, totalTime);
+ sb.append("realtime (");
+ sb.append(count);
+ sb.append(" times)");
+ } else {
+ sb.append("(not used)");
}
+ pw.println(sb.toString());
+ uidActivity = true;
}
- Map<String, ? extends Timer> jobs = u.getJobStats();
- if (jobs.size() > 0) {
- for (Map.Entry<String, ? extends Timer> ent : jobs.entrySet()) {
- Timer timer = ent.getValue();
- // Convert from microseconds to milliseconds with rounding
- long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
- int count = timer.getCountLocked(which);
- sb.setLength(0);
- sb.append(prefix);
- sb.append(" Job ");
- sb.append(ent.getKey());
- sb.append(": ");
- if (totalTime != 0) {
- formatTimeMs(sb, totalTime);
- sb.append("realtime (");
- sb.append(count);
- sb.append(" times)");
- } else {
- sb.append("(not used)");
- }
- pw.println(sb.toString());
- uidActivity = true;
+ final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
+ for (int ij=jobs.size()-1; ij>=0; ij--) {
+ final Timer timer = jobs.valueAt(ij);
+ // Convert from microseconds to milliseconds with rounding
+ final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+ final int count = timer.getCountLocked(which);
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Job ");
+ sb.append(jobs.keyAt(ij));
+ sb.append(": ");
+ if (totalTime != 0) {
+ formatTimeMs(sb, totalTime);
+ sb.append("realtime (");
+ sb.append(count);
+ sb.append(" times)");
+ } else {
+ sb.append("(not used)");
}
+ pw.println(sb.toString());
+ uidActivity = true;
}
- SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
- int NSE = sensors.size();
+ final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
+ final int NSE = sensors.size();
for (int ise=0; ise<NSE; ise++) {
- Uid.Sensor se = sensors.valueAt(ise);
- int sensorNumber = sensors.keyAt(ise);
+ final Uid.Sensor se = sensors.valueAt(ise);
+ final int sensorNumber = sensors.keyAt(ise);
sb.setLength(0);
sb.append(prefix);
sb.append(" Sensor ");
@@ -3785,12 +3774,12 @@ public abstract class BatteryStats implements Parcelable {
}
sb.append(": ");
- Timer timer = se.getSensorTime();
+ final Timer timer = se.getSensorTime();
if (timer != null) {
// Convert from microseconds to milliseconds with rounding
- long totalTime = (timer.getTotalTimeLocked(
+ final long totalTime = (timer.getTotalTimeLocked(
rawRealtime, which) + 500) / 1000;
- int count = timer.getCountLocked(which);
+ final int count = timer.getCountLocked(which);
//timer.logState();
if (totalTime != 0) {
formatTimeMs(sb, totalTime);
@@ -3808,12 +3797,12 @@ public abstract class BatteryStats implements Parcelable {
uidActivity = true;
}
- Timer vibTimer = u.getVibratorOnTimer();
+ final Timer vibTimer = u.getVibratorOnTimer();
if (vibTimer != null) {
// Convert from microseconds to milliseconds with rounding
- long totalTime = (vibTimer.getTotalTimeLocked(
+ final long totalTime = (vibTimer.getTotalTimeLocked(
rawRealtime, which) + 500) / 1000;
- int count = vibTimer.getCountLocked(which);
+ final int count = vibTimer.getCountLocked(which);
//timer.logState();
if (totalTime != 0) {
sb.setLength(0);
@@ -3828,11 +3817,12 @@ public abstract class BatteryStats implements Parcelable {
}
}
- Timer fgTimer = u.getForegroundActivityTimer();
+ final Timer fgTimer = u.getForegroundActivityTimer();
if (fgTimer != null) {
// Convert from microseconds to milliseconds with rounding
- long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
- int count = fgTimer.getCountLocked(which);
+ final long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500)
+ / 1000;
+ final int count = fgTimer.getCountLocked(which);
if (totalTime != 0) {
sb.setLength(0);
sb.append(prefix);
@@ -3862,125 +3852,121 @@ public abstract class BatteryStats implements Parcelable {
}
}
- Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
- if (processStats.size() > 0) {
- for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
- : processStats.entrySet()) {
- Uid.Proc ps = ent.getValue();
- long userTime;
- long systemTime;
- long foregroundTime;
- int starts;
- int numExcessive;
-
- userTime = ps.getUserTime(which);
- systemTime = ps.getSystemTime(which);
- foregroundTime = ps.getForegroundTime(which);
- starts = ps.getStarts(which);
- final int numCrashes = ps.getNumCrashes(which);
- final int numAnrs = ps.getNumAnrs(which);
- numExcessive = which == STATS_SINCE_CHARGED
- ? ps.countExcessivePowers() : 0;
-
- if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
- || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
- sb.setLength(0);
- sb.append(prefix); sb.append(" Proc ");
- sb.append(ent.getKey()); sb.append(":\n");
- sb.append(prefix); sb.append(" CPU: ");
- formatTimeMs(sb, userTime); sb.append("usr + ");
- formatTimeMs(sb, systemTime); sb.append("krn ; ");
- formatTimeMs(sb, foregroundTime); sb.append("fg");
- if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
- sb.append("\n"); sb.append(prefix); sb.append(" ");
- boolean hasOne = false;
- if (starts != 0) {
- hasOne = true;
- sb.append(starts); sb.append(" starts");
- }
- if (numCrashes != 0) {
- if (hasOne) {
- sb.append(", ");
- }
- hasOne = true;
- sb.append(numCrashes); sb.append(" crashes");
- }
- if (numAnrs != 0) {
- if (hasOne) {
- sb.append(", ");
- }
- sb.append(numAnrs); sb.append(" anrs");
+ final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
+ = u.getProcessStats();
+ for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
+ final Uid.Proc ps = processStats.valueAt(ipr);
+ long userTime;
+ long systemTime;
+ long foregroundTime;
+ int starts;
+ int numExcessive;
+
+ userTime = ps.getUserTime(which);
+ systemTime = ps.getSystemTime(which);
+ foregroundTime = ps.getForegroundTime(which);
+ starts = ps.getStarts(which);
+ final int numCrashes = ps.getNumCrashes(which);
+ final int numAnrs = ps.getNumAnrs(which);
+ numExcessive = which == STATS_SINCE_CHARGED
+ ? ps.countExcessivePowers() : 0;
+
+ if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
+ || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
+ sb.setLength(0);
+ sb.append(prefix); sb.append(" Proc ");
+ sb.append(processStats.keyAt(ipr)); sb.append(":\n");
+ sb.append(prefix); sb.append(" CPU: ");
+ formatTimeMs(sb, userTime); sb.append("usr + ");
+ formatTimeMs(sb, systemTime); sb.append("krn ; ");
+ formatTimeMs(sb, foregroundTime); sb.append("fg");
+ if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
+ sb.append("\n"); sb.append(prefix); sb.append(" ");
+ boolean hasOne = false;
+ if (starts != 0) {
+ hasOne = true;
+ sb.append(starts); sb.append(" starts");
+ }
+ if (numCrashes != 0) {
+ if (hasOne) {
+ sb.append(", ");
}
+ hasOne = true;
+ sb.append(numCrashes); sb.append(" crashes");
}
- pw.println(sb.toString());
- for (int e=0; e<numExcessive; e++) {
- Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
- if (ew != null) {
- pw.print(prefix); pw.print(" * Killed for ");
- if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
- pw.print("wake lock");
- } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
- pw.print("cpu");
- } else {
- pw.print("unknown");
- }
- pw.print(" use: ");
- TimeUtils.formatDuration(ew.usedTime, pw);
- pw.print(" over ");
- TimeUtils.formatDuration(ew.overTime, pw);
- if (ew.overTime != 0) {
- pw.print(" (");
- pw.print((ew.usedTime*100)/ew.overTime);
- pw.println("%)");
- }
+ if (numAnrs != 0) {
+ if (hasOne) {
+ sb.append(", ");
}
+ sb.append(numAnrs); sb.append(" anrs");
}
- uidActivity = true;
}
+ pw.println(sb.toString());
+ for (int e=0; e<numExcessive; e++) {
+ Uid.Proc.ExcessivePower ew = ps.getExcessivePower(e);
+ if (ew != null) {
+ pw.print(prefix); pw.print(" * Killed for ");
+ if (ew.type == Uid.Proc.ExcessivePower.TYPE_WAKE) {
+ pw.print("wake lock");
+ } else if (ew.type == Uid.Proc.ExcessivePower.TYPE_CPU) {
+ pw.print("cpu");
+ } else {
+ pw.print("unknown");
+ }
+ pw.print(" use: ");
+ TimeUtils.formatDuration(ew.usedTime, pw);
+ pw.print(" over ");
+ TimeUtils.formatDuration(ew.overTime, pw);
+ if (ew.overTime != 0) {
+ pw.print(" (");
+ pw.print((ew.usedTime*100)/ew.overTime);
+ pw.println("%)");
+ }
+ }
+ }
+ uidActivity = true;
}
}
- Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
- if (packageStats.size() > 0) {
- for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
- : packageStats.entrySet()) {
- pw.print(prefix); pw.print(" Apk "); pw.print(ent.getKey()); pw.println(":");
- boolean apkActivity = false;
- Uid.Pkg ps = ent.getValue();
- int wakeups = ps.getWakeups(which);
- if (wakeups != 0) {
- pw.print(prefix); pw.print(" ");
- pw.print(wakeups); pw.println(" wakeup alarms");
+ final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
+ = u.getPackageStats();
+ for (int ipkg=packageStats.size()-1; ipkg>=0; ipkg--) {
+ pw.print(prefix); pw.print(" Apk "); pw.print(packageStats.keyAt(ipkg));
+ pw.println(":");
+ boolean apkActivity = false;
+ final Uid.Pkg ps = packageStats.valueAt(ipkg);
+ final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
+ for (int iwa=alarms.size()-1; iwa>=0; iwa--) {
+ pw.print(prefix); pw.print(" Wakeup alarm ");
+ pw.print(alarms.keyAt(iwa)); pw.print(": ");
+ pw.print(alarms.valueAt(iwa).getCountLocked(which));
+ pw.println(" times");
+ apkActivity = true;
+ }
+ final ArrayMap<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
+ for (int isvc=serviceStats.size()-1; isvc>=0; isvc--) {
+ final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);
+ final long startTime = ss.getStartTime(batteryUptime, which);
+ final int starts = ss.getStarts(which);
+ final int launches = ss.getLaunches(which);
+ if (startTime != 0 || starts != 0 || launches != 0) {
+ sb.setLength(0);
+ sb.append(prefix); sb.append(" Service ");
+ sb.append(serviceStats.keyAt(isvc)); sb.append(":\n");
+ sb.append(prefix); sb.append(" Created for: ");
+ formatTimeMs(sb, startTime / 1000);
+ sb.append("uptime\n");
+ sb.append(prefix); sb.append(" Starts: ");
+ sb.append(starts);
+ sb.append(", launches: "); sb.append(launches);
+ pw.println(sb.toString());
apkActivity = true;
}
- Map<String, ? extends Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
- if (serviceStats.size() > 0) {
- for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
- : serviceStats.entrySet()) {
- BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
- long startTime = ss.getStartTime(batteryUptime, which);
- int starts = ss.getStarts(which);
- int launches = ss.getLaunches(which);
- if (startTime != 0 || starts != 0 || launches != 0) {
- sb.setLength(0);
- sb.append(prefix); sb.append(" Service ");
- sb.append(sent.getKey()); sb.append(":\n");
- sb.append(prefix); sb.append(" Created for: ");
- formatTimeMs(sb, startTime / 1000);
- sb.append("uptime\n");
- sb.append(prefix); sb.append(" Starts: ");
- sb.append(starts);
- sb.append(", launches: "); sb.append(launches);
- pw.println(sb.toString());
- apkActivity = true;
- }
- }
- }
- if (!apkActivity) {
- pw.print(prefix); pw.println(" (nothing executed)");
- }
- uidActivity = true;
}
+ if (!apkActivity) {
+ pw.print(prefix); pw.println(" (nothing executed)");
+ }
+ uidActivity = true;
}
if (!uidActivity) {
pw.print(prefix); pw.println(" (nothing executed)");
@@ -4498,7 +4484,6 @@ public abstract class BatteryStats implements Parcelable {
return true;
}
- public static final int DUMP_UNPLUGGED_ONLY = 1<<0;
public static final int DUMP_CHARGED_ONLY = 1<<1;
public static final int DUMP_DAILY_ONLY = 1<<2;
public static final int DUMP_HISTORY_ONLY = 1<<3;
@@ -4647,7 +4632,7 @@ public abstract class BatteryStats implements Parcelable {
prepareForDumpLocked();
final boolean filtering = (flags
- & (DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
+ & (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
final long historyTotalSize = getHistoryTotalSize();
@@ -4691,7 +4676,7 @@ public abstract class BatteryStats implements Parcelable {
}
}
- if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
+ if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
return;
}
@@ -4769,7 +4754,7 @@ public abstract class BatteryStats implements Parcelable {
LevelStepTracker csteps = getDailyChargeLevelStepTracker();
ArrayList<PackageChange> pkgc = getDailyPackageChanges();
if (dsteps.mNumStepDurations > 0 || csteps.mNumStepDurations > 0 || pkgc != null) {
- if ((flags&DUMP_DAILY_ONLY) != 0) {
+ if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
if (dumpDurationSteps(pw, " ", " Current daily discharge step durations:",
dsteps, false)) {
dumpDailyLevelStepSummary(pw, " ", "Discharge", dsteps,
@@ -4801,7 +4786,7 @@ public abstract class BatteryStats implements Parcelable {
pw.print(" to ");
pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", dit.mEndTime).toString());
pw.println(":");
- if ((flags&DUMP_DAILY_ONLY) != 0) {
+ if ((flags&DUMP_DAILY_ONLY) != 0 || !filtering) {
if (dumpDurationSteps(pw, " ",
" Discharge step durations:", dit.mDischargeSteps, false)) {
dumpDailyLevelStepSummary(pw, " ", "Discharge", dit.mDischargeSteps,
@@ -4830,11 +4815,6 @@ public abstract class BatteryStats implements Parcelable {
(flags&DUMP_DEVICE_WIFI_ONLY) != 0);
pw.println();
}
- if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
- pw.println("Statistics since last unplugged:");
- dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid,
- (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
- }
}
@SuppressWarnings("unused")
@@ -4848,7 +4828,7 @@ public abstract class BatteryStats implements Parcelable {
long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
final boolean filtering = (flags &
- (DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
+ (DUMP_HISTORY_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) != 0;
if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) {
if (startIteratingHistoryLocked()) {
@@ -4874,7 +4854,7 @@ public abstract class BatteryStats implements Parcelable {
}
}
- if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
+ if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) {
return;
}
@@ -4924,9 +4904,5 @@ public abstract class BatteryStats implements Parcelable {
dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1,
(flags&DUMP_DEVICE_WIFI_ONLY) != 0);
}
- if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
- dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1,
- (flags&DUMP_DEVICE_WIFI_ONLY) != 0);
- }
}
}
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 418641f..804d3d0 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -51,6 +51,7 @@ interface IPowerManager
void setStayOnSetting(int val);
void boostScreenBrightness(long time);
+ boolean isScreenBrightnessBoosted();
// temporarily overrides the screen brightness settings to allow the user to
// see the effect of a settings change without applying it immediately
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 81745b3..01c9a21 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -712,6 +712,22 @@ public final class PowerManager {
}
/**
+ * Returns whether the screen brightness is currently boosted to maximum, caused by a call
+ * to {@link #boostScreenBrightness(long)}.
+ * @return {@code True} if the screen brightness is currently boosted. {@code False} otherwise.
+ *
+ * @hide
+ */
+ @SystemApi
+ public boolean isScreenBrightnessBoosted() {
+ try {
+ return mService.isScreenBrightnessBoosted();
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
* Sets the brightness of the backlights (screen, keyboard, button).
* <p>
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
@@ -917,6 +933,16 @@ public final class PowerManager {
public static final String EXTRA_POWER_SAVE_MODE = "mode";
/**
+ * Intent that is broadcast when the state of {@link #isScreenBrightnessBoosted()} has changed.
+ * This broadcast is only sent to registered receivers.
+ *
+ * @hide
+ **/
+ @SystemApi
+ public static final String ACTION_SCREEN_BRIGHTNESS_BOOST_CHANGED
+ = "android.os.action.SCREEN_BRIGHTNESS_BOOST_CHANGED";
+
+ /**
* A wake lock is a mechanism to indicate that your application needs
* to have the device stay on.
* <p>
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index ccf2cfa..f32e8cf 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -706,8 +706,10 @@ public class Preference implements Comparable<Preference> {
* @param iconResId The icon as a resource ID.
*/
public void setIcon(@DrawableRes int iconResId) {
- mIconResId = iconResId;
- setIcon(mContext.getDrawable(iconResId));
+ if (mIconResId != iconResId) {
+ mIconResId = iconResId;
+ setIcon(mContext.getDrawable(iconResId));
+ }
}
/**
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 74b0a1c..e4a6f07 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -4809,6 +4809,14 @@ public final class ContactsContract {
Uri.withAppendedPath(AUTHORITY_URI, "raw_contact_entities");
/**
+ * The content:// style URI for this table in corp profile
+ *
+ * @hide
+ */
+ public static final Uri CORP_CONTENT_URI =
+ Uri.withAppendedPath(AUTHORITY_URI, "raw_contact_entities_corp");
+
+ /**
* The content:// style URI for this table, specific to the user's profile.
*/
public static final Uri PROFILE_CONTENT_URI =
diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl
index ac6bbb7..d24bc13 100644
--- a/core/java/android/security/IKeystoreService.aidl
+++ b/core/java/android/security/IKeystoreService.aidl
@@ -19,6 +19,7 @@ package android.security;
import android.security.keymaster.ExportResult;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
+import android.security.keymaster.KeymasterBlob;
import android.security.keymaster.OperationResult;
import android.security.KeystoreArguments;
@@ -61,11 +62,12 @@ interface IKeystoreService {
int addRngEntropy(in byte[] data);
int generateKey(String alias, in KeymasterArguments arguments, int uid, int flags,
out KeyCharacteristics characteristics);
- int getKeyCharacteristics(String alias, in byte[] clientId,
- in byte[] appId, out KeyCharacteristics characteristics);
+ int getKeyCharacteristics(String alias, in KeymasterBlob clientId, in KeymasterBlob appId,
+ out KeyCharacteristics characteristics);
int importKey(String alias, in KeymasterArguments arguments, int format,
in byte[] keyData, int uid, int flags, out KeyCharacteristics characteristics);
- ExportResult exportKey(String alias, int format, in byte[] clientId, in byte[] appId);
+ ExportResult exportKey(String alias, int format, in KeymasterBlob clientId,
+ in KeymasterBlob appId);
OperationResult begin(IBinder appToken, String alias, int purpose, boolean pruneable,
in KeymasterArguments params, out KeymasterArguments operationParams);
OperationResult update(IBinder token, in KeymasterArguments params, in byte[] input);
diff --git a/core/java/android/security/NetworkSecurityPolicy.java b/core/java/android/security/NetworkSecurityPolicy.java
index c7274e8..0b3bf45 100644
--- a/core/java/android/security/NetworkSecurityPolicy.java
+++ b/core/java/android/security/NetworkSecurityPolicy.java
@@ -19,48 +19,57 @@ package android.security;
/**
* Network security policy.
*
- * @hide
+ * <p>Network stacks/components should honor this policy to make it possible to centrally control
+ * the relevant aspects of network security behavior.
+ *
+ * <p>The policy currently consists of a single flag: whether cleartext network traffic is
+ * permitted. See {@link #isCleartextTrafficPermitted()}.
*/
public class NetworkSecurityPolicy {
- private static final NetworkSecurityPolicy INSTANCE = new NetworkSecurityPolicy();
-
- private boolean mCleartextTrafficPermitted = true;
+ private static final NetworkSecurityPolicy INSTANCE = new NetworkSecurityPolicy();
- private NetworkSecurityPolicy() {}
+ private NetworkSecurityPolicy() {}
- /**
- * Gets the policy.
- */
- public static NetworkSecurityPolicy getInstance() {
- return INSTANCE;
- }
+ /**
+ * Gets the policy for this process.
+ *
+ * <p>It's fine to cache this reference. Any changes to the policy will be immediately visible
+ * through the reference.
+ */
+ public static NetworkSecurityPolicy getInstance() {
+ return INSTANCE;
+ }
- /**
- * Checks whether cleartext network traffic (e.g., HTTP, WebSockets, XMPP, IMAP, SMTP -- without
- * TLS or STARTTLS) is permitted for this process.
- *
- * <p>When cleartext network traffic is not permitted, the platform's components (e.g., HTTP
- * stacks, {@code WebView}, {@code MediaPlayer}) will refuse this process's requests to use
- * cleartext traffic. Third-party libraries are encouraged to honor this setting as well.
- */
- public boolean isCleartextTrafficPermitted() {
- synchronized (this) {
- return mCleartextTrafficPermitted;
+ /**
+ * Returns whether cleartext network traffic (e.g. HTTP, FTP, WebSockets, XMPP, IMAP, SMTP --
+ * without TLS or STARTTLS) is permitted for this process.
+ *
+ * <p>When cleartext network traffic is not permitted, the platform's components (e.g. HTTP and
+ * FTP stacks, {@link android.webkit.WebView}, {@link android.media.MediaPlayer}) will refuse
+ * this process's requests to use cleartext traffic. Third-party libraries are strongly
+ * encouraged to honor this setting as well.
+ *
+ * <p>This flag is honored on a best effort basis because it's impossible to prevent all
+ * cleartext traffic from Android applications given the level of access provided to them. For
+ * example, there's no expectation that the {@link java.net.Socket} API will honor this flag
+ * because it cannot determine whether its traffic is in cleartext. However, most network
+ * traffic from applications is handled by higher-level network stacks/components which can
+ * honor this aspect of the policy.
+ */
+ public boolean isCleartextTrafficPermitted() {
+ return libcore.net.NetworkSecurityPolicy.isCleartextTrafficPermitted();
}
- }
- /**
- * Sets whether cleartext network traffic is permitted for this process.
- *
- * <p>This method is used by the platform early on in the application's initialization to set the
- * policy.
- *
- * @hide
- */
- public void setCleartextTrafficPermitted(boolean permitted) {
- synchronized (this) {
- mCleartextTrafficPermitted = permitted;
+ /**
+ * Sets whether cleartext network traffic is permitted for this process.
+ *
+ * <p>This method is used by the platform early on in the application's initialization to set
+ * the policy.
+ *
+ * @hide
+ */
+ public void setCleartextTrafficPermitted(boolean permitted) {
+ libcore.net.NetworkSecurityPolicy.setCleartextTrafficPermitted(permitted);
}
- }
}
diff --git a/core/java/android/security/keymaster/KeymasterBlob.aidl b/core/java/android/security/keymaster/KeymasterBlob.aidl
new file mode 100644
index 0000000..8f70f7c
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterBlob.aidl
@@ -0,0 +1,20 @@
+/**
+ * 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.keymaster;
+
+/* @hide */
+parcelable KeymasterBlob;
diff --git a/core/java/android/security/keymaster/KeymasterBlob.java b/core/java/android/security/keymaster/KeymasterBlob.java
new file mode 100644
index 0000000..cb95604
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterBlob.java
@@ -0,0 +1,55 @@
+/**
+ * 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.keymaster;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+public class KeymasterBlob implements Parcelable {
+ public byte[] blob;
+
+ public KeymasterBlob(byte[] blob) {
+ this.blob = blob;
+ }
+ public static final Parcelable.Creator<KeymasterBlob> CREATOR = new
+ Parcelable.Creator<KeymasterBlob>() {
+ public KeymasterBlob createFromParcel(Parcel in) {
+ return new KeymasterBlob(in);
+ }
+
+ public KeymasterBlob[] newArray(int length) {
+ return new KeymasterBlob[length];
+ }
+ };
+
+ protected KeymasterBlob(Parcel in) {
+ blob = in.createByteArray();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeByteArray(blob);
+ }
+}
diff --git a/core/java/android/security/keymaster/KeymasterBlobArgument.java b/core/java/android/security/keymaster/KeymasterBlobArgument.java
index 9af4445..7d587bf 100644
--- a/core/java/android/security/keymaster/KeymasterBlobArgument.java
+++ b/core/java/android/security/keymaster/KeymasterBlobArgument.java
@@ -26,6 +26,13 @@ class KeymasterBlobArgument extends KeymasterArgument {
public KeymasterBlobArgument(int tag, byte[] blob) {
super(tag);
+ switch (KeymasterDefs.getTagType(tag)) {
+ case KeymasterDefs.KM_BIGNUM:
+ case KeymasterDefs.KM_BYTES:
+ break; // OK.
+ default:
+ throw new IllegalArgumentException("Bad blob tag " + tag);
+ }
this.blob = blob;
}
diff --git a/core/java/android/security/keymaster/KeymasterBooleanArgument.java b/core/java/android/security/keymaster/KeymasterBooleanArgument.java
index 5481e8f..9c03674 100644
--- a/core/java/android/security/keymaster/KeymasterBooleanArgument.java
+++ b/core/java/android/security/keymaster/KeymasterBooleanArgument.java
@@ -28,6 +28,12 @@ class KeymasterBooleanArgument extends KeymasterArgument {
public KeymasterBooleanArgument(int tag) {
super(tag);
+ switch (KeymasterDefs.getTagType(tag)) {
+ case KeymasterDefs.KM_BOOL:
+ break; // OK.
+ default:
+ throw new IllegalArgumentException("Bad bool tag " + tag);
+ }
}
public KeymasterBooleanArgument(int tag, Parcel in) {
diff --git a/core/java/android/security/keymaster/KeymasterDateArgument.java b/core/java/android/security/keymaster/KeymasterDateArgument.java
index 310f546..bffd24d 100644
--- a/core/java/android/security/keymaster/KeymasterDateArgument.java
+++ b/core/java/android/security/keymaster/KeymasterDateArgument.java
@@ -27,6 +27,12 @@ class KeymasterDateArgument extends KeymasterArgument {
public KeymasterDateArgument(int tag, Date date) {
super(tag);
+ switch (KeymasterDefs.getTagType(tag)) {
+ case KeymasterDefs.KM_DATE:
+ break; // OK.
+ default:
+ throw new IllegalArgumentException("Bad date tag " + tag);
+ }
this.date = date;
}
diff --git a/core/java/android/security/keymaster/KeymasterIntArgument.java b/core/java/android/security/keymaster/KeymasterIntArgument.java
index c3738d7..da81715 100644
--- a/core/java/android/security/keymaster/KeymasterIntArgument.java
+++ b/core/java/android/security/keymaster/KeymasterIntArgument.java
@@ -26,6 +26,15 @@ class KeymasterIntArgument extends KeymasterArgument {
public KeymasterIntArgument(int tag, int value) {
super(tag);
+ switch (KeymasterDefs.getTagType(tag)) {
+ case KeymasterDefs.KM_INT:
+ case KeymasterDefs.KM_INT_REP:
+ case KeymasterDefs.KM_ENUM:
+ case KeymasterDefs.KM_ENUM_REP:
+ break; // OK.
+ default:
+ throw new IllegalArgumentException("Bad int tag " + tag);
+ }
this.value = value;
}
diff --git a/core/java/android/security/keymaster/KeymasterLongArgument.java b/core/java/android/security/keymaster/KeymasterLongArgument.java
index 3c565b8..9d2be09 100644
--- a/core/java/android/security/keymaster/KeymasterLongArgument.java
+++ b/core/java/android/security/keymaster/KeymasterLongArgument.java
@@ -26,6 +26,12 @@ class KeymasterLongArgument extends KeymasterArgument {
public KeymasterLongArgument(int tag, long value) {
super(tag);
+ switch (KeymasterDefs.getTagType(tag)) {
+ case KeymasterDefs.KM_LONG:
+ break; // OK.
+ default:
+ throw new IllegalArgumentException("Bad long tag " + tag);
+ }
this.value = value;
}
diff --git a/core/java/android/service/fingerprint/Fingerprint.aidl b/core/java/android/service/fingerprint/Fingerprint.aidl
new file mode 100644
index 0000000..c9fd989
--- /dev/null
+++ b/core/java/android/service/fingerprint/Fingerprint.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.service.fingerprint;
+
+// @hide
+parcelable Fingerprint;
diff --git a/core/java/android/service/fingerprint/Fingerprint.java b/core/java/android/service/fingerprint/Fingerprint.java
new file mode 100644
index 0000000..37552eb
--- /dev/null
+++ b/core/java/android/service/fingerprint/Fingerprint.java
@@ -0,0 +1,93 @@
+/*
+ * 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.service.fingerprint;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Container for fingerprint metadata.
+ * @hide
+ */
+public final class Fingerprint implements Parcelable {
+ private CharSequence mName;
+ private int mGroupId;
+ private int mFingerId;
+ private long mDeviceId; // physical device this is associated with
+
+ public Fingerprint(CharSequence name, int groupId, int fingerId, long deviceId) {
+ mName = name;
+ mGroupId = groupId;
+ mFingerId = fingerId;
+ mDeviceId = deviceId;
+ }
+
+ private Fingerprint(Parcel in) {
+ mName = in.readString();
+ mGroupId = in.readInt();
+ mFingerId = in.readInt();
+ mDeviceId = in.readLong();
+ }
+
+ /**
+ * Gets the human-readable name for the given fingerprint.
+ * @return name given to finger
+ */
+ public CharSequence getName() { return mName; }
+
+ /**
+ * Gets the device-specific finger id. Used by Settings to map a name to a specific
+ * fingerprint template.
+ * @return device-specific id for this finger
+ * @hide
+ */
+ public int getFingerId() { return mFingerId; }
+
+ /**
+ * Gets the group id specified when the fingerprint was enrolled.
+ * @return group id for the set of fingerprints this one belongs to.
+ * @hide
+ */
+ public int getGroupId() { return mGroupId; }
+
+ /**
+ * Device this fingerprint belongs to.
+ * @hide
+ */
+ public long getDeviceId() { return mDeviceId; }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(mName.toString());
+ out.writeInt(mGroupId);
+ out.writeInt(mFingerId);
+ out.writeLong(mDeviceId);
+ }
+
+ public static final Parcelable.Creator<Fingerprint> CREATOR
+ = new Parcelable.Creator<Fingerprint>() {
+ public Fingerprint createFromParcel(Parcel in) {
+ return new Fingerprint(in);
+ }
+
+ public Fingerprint[] newArray(int size) {
+ return new Fingerprint[size];
+ }
+ };
+}; \ No newline at end of file
diff --git a/core/java/android/service/fingerprint/FingerprintManager.java b/core/java/android/service/fingerprint/FingerprintManager.java
index 6375668..bb90e40 100644
--- a/core/java/android/service/fingerprint/FingerprintManager.java
+++ b/core/java/android/service/fingerprint/FingerprintManager.java
@@ -20,17 +20,25 @@ import android.app.ActivityManagerNative;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Binder;
+import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
+import android.service.fingerprint.FingerprintManager.EnrollmentCallback;
import android.util.Log;
import android.util.Slog;
+import java.security.Signature;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import javax.crypto.Cipher;
+
/**
* A class that coordinates access to the fingerprint hardware.
* @hide
@@ -45,9 +53,6 @@ public class FingerprintManager {
private static final int MSG_ERROR = 103;
private static final int MSG_REMOVED = 104;
- // Errors generated by layers above HAL
- public static final int FINGERPRINT_ERROR_NO_RECEIVER = -10;
-
// Message types. Must agree with HAL (fingerprint.h)
public static final int FINGERPRINT_ERROR = -1;
public static final int FINGERPRINT_ACQUIRED = 1;
@@ -60,254 +65,499 @@ public class FingerprintManager {
public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2;
public static final int FINGERPRINT_ERROR_TIMEOUT = 3;
public static final int FINGERPRINT_ERROR_NO_SPACE = 4;
+ public static final int FINGERPRINT_ERROR_CANCELED = 5;
+ public static final int FINGERPRINT_ERROR_VENDOR_BASE = 1000;
- // FINGERPRINT_ACQUIRED messages. Must agree with HAL (fingerprint.h)
+ // Image acquisition messages. Must agree with HAL (fingerprint.h)
public static final int FINGERPRINT_ACQUIRED_GOOD = 0;
public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1;
public static final int FINGERPRINT_ACQUIRED_INSUFFICIENT = 2;
- public static final int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 4;
- public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 8;
- public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 16;
+ public static final int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3;
+ public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 4;
+ public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 5;
+ public static final int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
private IFingerprintService mService;
- private FingerprintManagerReceiver mClientReceiver;
private Context mContext;
private IBinder mToken = new Binder();
+ private AuthenticationCallback mAuthenticationCallback;
+ private EnrollmentCallback mEnrollmentCallback;
+ private RemovalCallback mRemovalCallback;
+ private CryptoObject mCryptoObject;
+ private Fingerprint mRemovalFingerprint;
+ private boolean mListening;
- private Handler mHandler = new Handler() {
- public void handleMessage(android.os.Message msg) {
- if (mClientReceiver != null) {
- switch(msg.what) {
- case MSG_ENROLL_RESULT:
- mClientReceiver.onEnrollResult(msg.arg1, msg.arg2);
- break;
- case MSG_ACQUIRED:
- mClientReceiver.onAcquired(msg.arg1);
- break;
- case MSG_PROCESSED:
- mClientReceiver.onProcessed(msg.arg1);
- break;
- case MSG_ERROR:
- mClientReceiver.onError(msg.arg1);
- break;
- case MSG_REMOVED:
- mClientReceiver.onRemoved(msg.arg1);
- }
- }
- }
+ /**
+ * A wrapper class for a limited number of crypto objects supported by FingerprintManager.
+ */
+ public static class CryptoObject {
+ CryptoObject(Signature signature) { mSignature = signature; }
+ CryptoObject(Cipher cipher) { mCipher = cipher; }
+ private Signature mSignature;
+ private Cipher mCipher;
};
- public static final class FingerprintItem {
- public CharSequence name;
- public int id;
- FingerprintItem(CharSequence name, int id) {
- this.name = name;
- this.id = id;
+ /**
+ * Container for callback data from {@link FingerprintManager#authenticate(CryptoObject,
+ * AuthenticationCallback, CancellationSignal, int)}
+ */
+ public static final class AuthenticationResult {
+ private Fingerprint mFingerprint;
+ private CryptoObject mCryptoObject;
+
+ public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint) {
+ mCryptoObject = crypto;
+ mFingerprint = fingerprint;
}
- }
+
+ /**
+ * Obtain the crypto object associated with this transaction
+ * @return crypto object provided to {@link FingerprintManager#authenticate(CryptoObject,
+ * AuthenticationCallback, CancellationSignal, int)}
+ */
+ public CryptoObject getCryptoObject() { return mCryptoObject; }
+
+ /**
+ * Obtain the Fingerprint associated with this operation. Applications are discouraged
+ * from associating specific fingers with specific applications or operations. Hence this
+ * is not public.
+ * @hide
+ */
+ public Fingerprint getFingerprint() { return mFingerprint; }
+ };
/**
- * @hide
+ * Callback structure provided to {@link FingerprintManager#authenticate(CryptoObject,
+ * AuthenticationCallback, CancellationSignal, int)}. Users of {@link #FingerprintManager()}
+ * must provide an implementation of this to {@link FingerprintManager#authenticate(
+ * CryptoObject, AuthenticationCallback, CancellationSignal, int) for listening to fingerprint
+ * events.
*/
- public FingerprintManager(Context context, IFingerprintService service) {
- mContext = context;
- mService = service;
- if (mService == null) {
- Slog.v(TAG, "FingerprintManagerService was null");
- }
- }
+ public static abstract class AuthenticationCallback {
+ /**
+ * Called when an unrecoverable error has been encountered and the operation is complete.
+ * No further callbacks will be made on this object.
+ * @param errMsgId an integer identifying the error message.
+ * @param errString a human-readible error string that can be shown in UI.
+ */
+ public abstract void onAuthenticationError(int errMsgId, CharSequence errString);
- private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {
+ /**
+ * Called when a recoverable error has been encountered during authentication. The help
+ * string is provided to give the user guidance for what went wrong, such as
+ * "Sensor dirty, please clean it."
+ * @param helpMsgId an integer identifying the error message.
+ * @param helpString a human-readible string that can be shown in UI.
+ */
+ public abstract void onAuthenticationHelp(int helpMsgId, CharSequence helpString);
- public void onEnrollResult(int fingerprintId, int remaining) {
- mHandler.obtainMessage(MSG_ENROLL_RESULT, fingerprintId, remaining).sendToTarget();
- }
+ /**
+ * Called when a fingerprint is recognized.
+ * @param result an object containing authentication-related data.
+ */
+ public abstract void onAuthenticationSucceeded(AuthenticationResult result);
+ };
- public void onAcquired(int acquireInfo) {
- mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0).sendToTarget();
- }
+ /**
+ * Callback structure provided to {@link FingerprintManager#enroll(long, EnrollmentCallback,
+ * CancellationSignal, int). Users of {@link #FingerprintManager()}
+ * must provide an implementation of this to {@link FingerprintManager#enroll(long,
+ * EnrollmentCallback, CancellationSignal, int) for listening to fingerprint events.
+ */
+ public static abstract class EnrollmentCallback {
+ /**
+ * Called when an unrecoverable error has been encountered and the operation is complete.
+ * No further callbacks will be made on this object.
+ * @param errMsgId an integer identifying the error message.
+ * @param errString a human-readible error string that can be shown in UI.
+ */
+ public abstract void onEnrollmentError(int errMsgId, CharSequence errString);
- public void onProcessed(int fingerprintId) {
- mHandler.obtainMessage(MSG_PROCESSED, fingerprintId, 0).sendToTarget();
- }
+ /**
+ * Called when a recoverable error has been encountered during enrollment. The help
+ * string is provided to give the user guidance for what went wrong, such as
+ * "Sensor dirty, please clean it" or what they need to do next, such as
+ * "Touch sensor again."
+ * @param helpMsgId an integer identifying the error message.
+ * @param helpString a human-readible string that can be shown in UI.
+ */
+ public abstract void onEnrollmentHelp(int helpMsgId, CharSequence helpString);
- public void onError(int error) {
- mHandler.obtainMessage(MSG_ERROR, error, 0).sendToTarget();
- }
+ /**
+ * Called as each enrollment step progresses. Enrollment is considered complete when
+ * remaining reaches 0. This function will not be called if enrollment fails. See
+ * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)}
+ * @param remaining the number of remaining steps.
+ */
+ public abstract void onEnrollmentProgress(int remaining);
+ };
- public void onRemoved(int fingerprintId) {
- mHandler.obtainMessage(MSG_REMOVED, fingerprintId, 0).sendToTarget();
- }
+ /**
+ * Callback structure provided to {@link FingerprintManager#remove(int). Users of
+ * {@link #FingerprintManager()} may optionally provide an implementation of this to
+ * {@link FingerprintManager#remove(int, int, RemovalCallback)} for listening to
+ * fingerprint template removal events.
+ */
+ public static abstract class RemovalCallback {
+ /**
+ * Called when the given fingerprint can't be removed.
+ * @param fp the fingerprint that the call attempted to remove.
+ * @param errMsgId an associated error message id.
+ * @param errString an error message indicating why the fingerprint id can't be removed.
+ */
+ public abstract void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString);
+
+ /**
+ * Called when a given fingerprint is successfully removed.
+ * @param fingerprint the fingerprint template that was removed.
+ */
+ public abstract void onRemovalSucceeded(Fingerprint fingerprint);
};
/**
- * Determine whether the user has at least one fingerprint enrolled and enabled.
+ * Request authentication of a crypto object. This call warms up the fingerprint hardware
+ * and starts scanning for a fingerprint. It terminates when
+ * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
+ * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult) is called, at
+ * which point the object is no longer valid. The operation can be canceled by using the
+ * provided cancel object.
*
- * @return true if at least one is enrolled and enabled
+ * @param crypto object associated with the call or null if none required.
+ * @param callback an object to receive authentication events
+ * @param cancel an object that can be used to cancel authentication
+ * @param flags optional flags
*/
- public boolean enrolledAndEnabled() {
- ContentResolver res = mContext.getContentResolver();
- return Settings.Secure.getInt(res, "fingerprint_enabled", 0) != 0
- && FingerprintUtils.getFingerprintIdsForUser(res, getCurrentUserId()).length > 0;
+ public void authenticate(CryptoObject crypto, AuthenticationCallback callback,
+ CancellationSignal cancel, int flags) {
+ if (callback == null) {
+ throw new IllegalArgumentException("Must supply an authentication callback");
+ }
+
+ // TODO: handle cancel
+
+ if (mService != null) try {
+ mAuthenticationCallback = callback;
+ mCryptoObject = crypto;
+ long sessionId = 0; // TODO: get from crypto object
+ startListening();
+ mService.authenticate(mToken, sessionId, getCurrentUserId(), flags);
+ } catch (RemoteException e) {
+ Log.v(TAG, "Remote exception while authenticating: ", e);
+ stopListening();
+ }
}
/**
- * Start the enrollment process. Timeout dictates how long to wait for the user to
- * enroll a fingerprint.
- *
- * @param timeout
+ * Request fingerprint enrollment. This call warms up the fingerprint hardware
+ * and starts scanning for fingerprints. Progress will be indicated by callbacks to the
+ * {@link EnrollmentCallback} object. It terminates when
+ * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)} or
+ * {@link EnrollmentCallback#onEnrollmentProgress(int) is called with remaining == 0, at
+ * which point the object is no longer valid. The operation can be canceled by using the
+ * provided cancel object.
+ * @param challenge a unique id provided by a recent verification of device credentials
+ * (e.g. pin, pattern or password).
+ * @param callback an object to receive enrollment events
+ * @param cancel an object that can be used to cancel enrollment
+ * @param flags optional flags
*/
- public void enroll(long timeout) {
- if (mServiceReceiver == null) {
- sendError(FINGERPRINT_ERROR_NO_RECEIVER, 0, 0);
- return;
+ public void enroll(long challenge, EnrollmentCallback callback,
+ CancellationSignal cancel, int flags) {
+ if (callback == null) {
+ throw new IllegalArgumentException("Must supply an enrollment callback");
}
+
+ // TODO: handle cancel
+
if (mService != null) try {
- mService.enroll(mToken, timeout, getCurrentUserId());
+ mEnrollmentCallback = callback;
+ startListening();
+ mService.enroll(mToken, getCurrentUserId(), flags);
} catch (RemoteException e) {
- Log.v(TAG, "Remote exception while enrolling: ", e);
- sendError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0, 0);
+ Log.v(TAG, "Remote exception in enroll: ", e);
+ stopListening();
}
}
/**
- * Remove the given fingerprintId from the system. FingerprintId of 0 has special meaning
- * which is to delete all fingerprint data for the current user. Use with caution.
- * @param fingerprintId
+ * Remove given fingerprint template from fingerprint hardware and/or protected storage.
+ * @param fp the fingerprint item to remove
+ * @param callback an optional callback to verify that fingerprint templates have been
+ * successfully removed. May be null of no callback is required.
+ * @hide
*/
- public void remove(int fingerprintId) {
- if (mServiceReceiver == null) {
- sendError(FINGERPRINT_ERROR_NO_RECEIVER, 0, 0);
- return;
- }
- if (mService != null) {
- try {
- mService.remove(mToken, fingerprintId, getCurrentUserId());
- } catch (RemoteException e) {
- Log.v(TAG, "Remote exception during remove of fingerprintId: " + fingerprintId, e);
- }
- } else {
- Log.w(TAG, "remove(): Service not connected!");
- sendError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0, 0);
+ public void remove(Fingerprint fp, RemovalCallback callback) {
+ if (mService != null) try {
+ mRemovalCallback = callback;
+ mRemovalFingerprint = fp;
+ startListening();
+ mService.remove(mToken, fp.getFingerId(), getCurrentUserId());
+ } catch (RemoteException e) {
+ Log.v(TAG, "Remote in remove: ", e);
+ stopListening();
}
}
/**
- * Starts listening for fingerprint events. When a finger is scanned or recognized, the
- * client will be notified via the callback.
+ * Renames the given fingerprint template
+ * @param fpId the fingerprint id
+ * @param newName the new name
+ * @hide
*/
- public void startListening(FingerprintManagerReceiver receiver) {
- mClientReceiver = receiver;
+ public void rename(int fpId, String newName) {
+ // Renames the given fpId
if (mService != null) {
try {
- mService.startListening(mToken, mServiceReceiver, getCurrentUserId());
+ mService.rename(fpId, getCurrentUserId(), newName);
} catch (RemoteException e) {
- Log.v(TAG, "Remote exception in startListening(): ", e);
+ Log.v(TAG, "Remote exception in rename(): ", e);
}
} else {
- Log.w(TAG, "startListening(): Service not connected!");
- sendError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0, 0);
+ Log.w(TAG, "rename(): Service not connected!");
}
}
- private int getCurrentUserId() {
- try {
- return ActivityManagerNative.getDefault().getCurrentUser().id;
+ /**
+ * Obtain the list of enrolled fingerprints templates.
+ * @return list of current fingerprint items
+ */
+ public List<Fingerprint> getEnrolledFingerprints() {
+ if (mService != null) try {
+ return mService.getEnrolledFingerprints(getCurrentUserId());
} catch (RemoteException e) {
- Log.w(TAG, "Failed to get current user id\n");
- return UserHandle.USER_NULL;
+ Log.v(TAG, "Remote exception in getEnrolledFingerprints: ", e);
}
+ return null;
}
/**
- * Stops the client from listening to fingerprint events.
+ * Determine if fingerprint hardware is present and functional.
+ * @return true if hardware is present and functional, false otherwise.
+ * @hide
*/
- public void stopListening() {
+ public boolean isHardwareDetected() {
if (mService != null) {
try {
- mService.stopListening(mToken, getCurrentUserId());
- mClientReceiver = null;
+ long deviceId = 0; /* TODO: plumb hardware id to FPMS */
+ return mService.isHardwareDetected(deviceId);
} catch (RemoteException e) {
- Log.v(TAG, "Remote exception in stopListening(): ", e);
+ Log.v(TAG, "Remote exception in isFingerprintHardwareDetected(): ", e);
}
} else {
- Log.w(TAG, "stopListening(): Service not connected!");
- sendError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0, 0);
+ Log.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
}
+ return false;
}
- public void enrollCancel() {
- if (mServiceReceiver == null) {
- sendError(FINGERPRINT_ERROR_NO_RECEIVER, 0, 0);
- return;
+ private Handler mHandler = new Handler() {
+ public void handleMessage(android.os.Message msg) {
+ switch(msg.what) {
+ case MSG_ENROLL_RESULT:
+ sendEnrollResult((Fingerprint) msg.obj, msg.arg1 /* remaining */);
+ break;
+ case MSG_ACQUIRED:
+ sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */);
+ break;
+ case MSG_PROCESSED:
+ sendProcessedResult((Fingerprint) msg.obj);
+ break;
+ case MSG_ERROR:
+ sendErrorResult((Long) msg.obj /* deviceId */, msg.arg1 /* errMsgId */);
+ break;
+ case MSG_REMOVED:
+ sendRemovedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */,
+ msg.arg2 /* groupId */);
+ }
}
- if (mService != null) {
- try {
- mService.enrollCancel(mToken, getCurrentUserId());
- mClientReceiver = null;
- } catch (RemoteException e) {
- Log.v(TAG, "Remote exception in enrollCancel(): ", e);
- sendError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0, 0);
+
+ private void sendRemovedResult(long deviceId, int fingerId, int groupId) {
+ if (mRemovalCallback != null) {
+ int reqFingerId = mRemovalFingerprint.getFingerId();
+ int reqGroupId = mRemovalFingerprint.getGroupId();
+ if (fingerId != reqFingerId) {
+ Log.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
+ }
+ if (fingerId != reqFingerId) {
+ Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId);
+ }
+ mRemovalCallback.onRemovalSucceeded(mRemovalFingerprint);
}
- } else {
- Log.w(TAG, "enrollCancel(): Service not connected!");
}
- }
- private void sendError(int msg, int arg1, int arg2) {
- mHandler.obtainMessage(msg, arg1, arg2);
- }
+ private void sendErrorResult(long deviceId, int errMsgId) {
+ if (mEnrollmentCallback != null) {
+ mEnrollmentCallback.onEnrollmentError(errMsgId, getErrorString(errMsgId));
+ } else if (mAuthenticationCallback != null) {
+ mAuthenticationCallback.onAuthenticationError(errMsgId, getErrorString(errMsgId));
+ } else if (mRemovalCallback != null) {
+ mRemovalCallback.onRemovalError(mRemovalFingerprint, errMsgId,
+ getErrorString(errMsgId));
+ }
+ }
+
+ private void sendEnrollResult(Fingerprint fp, int remaining) {
+ if (mEnrollmentCallback != null) {
+ mEnrollmentCallback.onEnrollmentProgress(remaining);
+ }
+ }
+
+ private void sendProcessedResult(Fingerprint fp) {
+ if (mAuthenticationCallback != null) {
+ AuthenticationResult result = new AuthenticationResult(mCryptoObject, fp);
+ mAuthenticationCallback.onAuthenticationSucceeded(result);
+ }
+ }
+
+ private void sendAcquiredResult(long deviceId, int acquireInfo) {
+ final String msg = getAcquiredString(acquireInfo);
+ if (msg == null) return;
+
+ if (mEnrollmentCallback != null) {
+ mEnrollmentCallback.onEnrollmentHelp(acquireInfo, msg);
+ } else if (mAuthenticationCallback != null) {
+ mAuthenticationCallback.onAuthenticationHelp(acquireInfo, msg);
+ }
+ }
+
+ private String getErrorString(int errMsg) {
+ switch (errMsg) {
+ case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
+ return mContext.getString(
+ com.android.internal.R.string.fingerprint_error_unable_to_process);
+ case FINGERPRINT_ERROR_HW_UNAVAILABLE:
+ return mContext.getString(
+ com.android.internal.R.string.fingerprint_error_hw_not_available);
+ case FINGERPRINT_ERROR_NO_SPACE:
+ return mContext.getString(
+ com.android.internal.R.string.fingerprint_error_no_space);
+ case FINGERPRINT_ERROR_TIMEOUT:
+ return mContext.getString(
+ com.android.internal.R.string.fingerprint_error_timeout);
+ default:
+ if (errMsg >= FINGERPRINT_ERROR_VENDOR_BASE) {
+ int msgNumber = errMsg - FINGERPRINT_ERROR_VENDOR_BASE;
+ String[] msgArray = mContext.getResources().getStringArray(
+ com.android.internal.R.array.fingerprint_error_vendor);
+ if (msgNumber < msgArray.length) {
+ return msgArray[msgNumber];
+ }
+ }
+ return null;
+ }
+ }
+
+ private String getAcquiredString(int acquireInfo) {
+ switch (acquireInfo) {
+ case FINGERPRINT_ACQUIRED_GOOD:
+ return null;
+ case FINGERPRINT_ACQUIRED_PARTIAL:
+ return mContext.getString(
+ com.android.internal.R.string.fingerprint_acquired_partial);
+ case FINGERPRINT_ACQUIRED_INSUFFICIENT:
+ return mContext.getString(
+ com.android.internal.R.string.fingerprint_acquired_insufficient);
+ case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
+ return mContext.getString(
+ com.android.internal.R.string.fingerprint_acquired_imager_dirty);
+ case FINGERPRINT_ACQUIRED_TOO_SLOW:
+ return mContext.getString(
+ com.android.internal.R.string.fingerprint_acquired_too_slow);
+ case FINGERPRINT_ACQUIRED_TOO_FAST:
+ return mContext.getString(
+ com.android.internal.R.string.fingerprint_acquired_too_fast);
+ default:
+ if (acquireInfo >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
+ int msgNumber = acquireInfo - FINGERPRINT_ACQUIRED_VENDOR_BASE;
+ String[] msgArray = mContext.getResources().getStringArray(
+ com.android.internal.R.array.fingerprint_acquired_vendor);
+ if (msgNumber < msgArray.length) {
+ return msgArray[msgNumber];
+ }
+ }
+ return null;
+ }
+ }
+ };
/**
- * @return list of current fingerprint items
* @hide
*/
- public List<FingerprintItem> getEnrolledFingerprints() {
- int[] ids = FingerprintUtils.getFingerprintIdsForUser(mContext.getContentResolver(),
- getCurrentUserId());
- List<FingerprintItem> result = new ArrayList<FingerprintItem>();
- for (int i = 0; i < ids.length; i++) {
- // TODO: persist names in Settings
- FingerprintItem item = new FingerprintItem("Finger" + ids[i], ids[i]);
- result.add(item);
+ public FingerprintManager(Context context, IFingerprintService service) {
+ mContext = context;
+ mService = service;
+ if (mService == null) {
+ Slog.v(TAG, "FingerprintManagerService was null");
+ }
+ }
+
+ private int getCurrentUserId() {
+ try {
+ return ActivityManagerNative.getDefault().getCurrentUser().id;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to get current user id\n");
+ return UserHandle.USER_NULL;
}
- return result;
}
/**
- * Determine if fingerprint hardware is present and functional.
- * @return true if hardware is present and functional, false otherwise.
- * @hide
+ * Stops the client from listening to fingerprint events.
*/
- public boolean isHardwareDetected() {
+ private void stopListening() {
if (mService != null) {
try {
- return mService.isHardwareDetected();
+ if (mListening) {
+ mService.removeListener(mToken, mServiceReceiver);
+ mListening = false;
+ }
} catch (RemoteException e) {
- Log.v(TAG, "Remote exception in isFingerprintHardwareDetected(): ", e);
+ Log.v(TAG, "Remote exception in stopListening(): ", e);
}
} else {
- Log.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
+ Log.w(TAG, "stopListening(): Service not connected!");
}
- return false;
}
/**
- * Renames the given fingerprint template
- * @param fpId the fingerprint id
- * @param newName the new name
- * @hide
+ * Starts listening for fingerprint events for this client.
*/
- public void rename(int fpId, String newName) {
- // Renames the given fpId
+ private void startListening() {
if (mService != null) {
try {
- mService.rename(fpId, newName);
+ if (!mListening) {
+ mService.addListener(mToken, mServiceReceiver, getCurrentUserId());
+ mListening = true;
+ }
} catch (RemoteException e) {
- Log.v(TAG, "Remote exception in rename(): ", e);
+ Log.v(TAG, "Remote exception in startListening(): ", e);
}
} else {
- Log.w(TAG, "rename(): Service not connected!");
+ Log.w(TAG, "startListening(): Service not connected!");
}
}
+
+ private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {
+
+ public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
+ mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0,
+ new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
+ }
+
+ public void onAcquired(long deviceId, int acquireInfo) {
+ mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0, deviceId).sendToTarget();
+ }
+
+ public void onProcessed(long deviceId, int fingerId, int groupId) {
+ mHandler.obtainMessage(MSG_PROCESSED,
+ new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
+ }
+
+ public void onError(long deviceId, int error) {
+ mHandler.obtainMessage(MSG_ERROR, error, 0, deviceId).sendToTarget();
+ }
+
+ public void onRemoved(long deviceId, int fingerId, int groupId) {
+ mHandler.obtainMessage(MSG_REMOVED, fingerId, groupId, deviceId).sendToTarget();
+ }
+ };
+
} \ No newline at end of file
diff --git a/core/java/android/service/fingerprint/FingerprintManagerReceiver.java b/core/java/android/service/fingerprint/FingerprintManagerReceiver.java
deleted file mode 100644
index 85677ba..0000000
--- a/core/java/android/service/fingerprint/FingerprintManagerReceiver.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package android.service.fingerprint;
-/**
- * Copyright (C) 2014 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.
- */
-
-/**
- * @hide
- */
-public class FingerprintManagerReceiver {
- /**
- * Fingerprint enrollment progress update. Enrollment is considered complete if
- * remaining hits 0 without {@link #onError(int)} being called.
- *
- * @param fingerprintId the fingerprint we're currently enrolling
- * @param remaining the number of samples required to complete enrollment. It's up to
- * the hardware to define what each step in enrollment means. Some hardware
- * requires multiple samples of the same part of the finger. Others require sampling of
- * different parts of the finger. The enrollment flow can use remaining to
- * mean "step x" of the process or "just need another sample."
- */
- public void onEnrollResult(int fingerprintId, int remaining) { }
-
- /**
- * Fingerprint touch detected, but not processed yet. Clients will use this message to
- * determine a good or bad scan before the fingerprint is processed. This is meant for the
- * client to provide feedback about the scan or alert the user that recognition is to follow.
- *
- * @param acquiredInfo one of:
- * {@link FingerprintManager#FINGERPRINT_ACQUIRED_GOOD},
- * {@link FingerprintManager#FINGERPRINT_ACQUIRED_PARTIAL},
- * {@link FingerprintManager#FINGERPRINT_ACQUIRED_INSUFFICIENT},
- * {@link FingerprintManager#FINGERPRINT_ACQUIRED_IMAGER_DIRTY},
- * {@link FingerprintManager#FINGERPRINT_ACQUIRED_TOO_SLOW},
- * {@link FingerprintManager#FINGERPRINT_ACQUIRED_TOO_FAST}
- */
- public void onAcquired(int acquiredInfo) { }
-
- /**
- * Fingerprint has been detected and processed. A non-zero return indicates a valid
- * fingerprint was detected.
- *
- * @param fingerprintId the finger id, or 0 if not recognized.
- */
- public void onProcessed(int fingerprintId) { }
-
- /**
- * An error was detected during scan or enrollment. One of
- * {@link FingerprintManager#FINGERPRINT_ERROR_HW_UNAVAILABLE},
- * {@link FingerprintManager#FINGERPRINT_ERROR_UNABLE_TO_PROCESS} or
- * {@link FingerprintManager#FINGERPRINT_ERROR_TIMEOUT}
- * {@link FingerprintManager#FINGERPRINT_ERROR_NO_SPACE}
- *
- * @param error one of the above error codes
- */
- public void onError(int error) { }
-
- /**
- * The given fingerprint template was successfully removed by the driver.
- * See {@link FingerprintManager#remove(int)}
- *
- * @param fingerprintId id of template to remove.
- */
- public void onRemoved(int fingerprintId) { }
-} \ No newline at end of file
diff --git a/core/java/android/service/fingerprint/FingerprintUtils.java b/core/java/android/service/fingerprint/FingerprintUtils.java
index cc17b99..62acbb9 100644
--- a/core/java/android/service/fingerprint/FingerprintUtils.java
+++ b/core/java/android/service/fingerprint/FingerprintUtils.java
@@ -67,7 +67,7 @@ class FingerprintUtils {
return toIntArray(tmp);
}
- public static void addFingerprintIdForUser(int fingerId, ContentResolver res, int userId) {
+ public static void addFingerprintIdForUser(ContentResolver res, int fingerId, int userId) {
// FingerId 0 has special meaning.
if (fingerId == 0) {
Log.w(TAG, "Tried to add fingerId 0");
diff --git a/core/java/android/service/fingerprint/IFingerprintService.aidl b/core/java/android/service/fingerprint/IFingerprintService.aidl
index 9b4750b..e5d3ad4 100644
--- a/core/java/android/service/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/service/fingerprint/IFingerprintService.aidl
@@ -17,31 +17,42 @@ package android.service.fingerprint;
import android.os.Bundle;
import android.service.fingerprint.IFingerprintServiceReceiver;
+import android.service.fingerprint.Fingerprint;
+import java.util.List;
/**
* Communication channel from client to the fingerprint service.
* @hide
*/
interface IFingerprintService {
- // Any errors resulting from this call will be returned to the listener
- void enroll(IBinder token, long timeout, int userId);
+ // Authenticate the given sessionId with a fingerprint
+ void authenticate(IBinder token, long sessionId, int groupId, int flags);
- // Any errors resulting from this call will be returned to the listener
- void enrollCancel(IBinder token, int userId);
+ // Start fingerprint enrollment
+ void enroll(IBinder token, int groupId, int flags);
// Any errors resulting from this call will be returned to the listener
- void remove(IBinder token, int fingerprintId, int userId);
+ void remove(IBinder token, int fingerId, int groupId);
+
+ // Rename the fingerprint specified by fingerId and groupId to the given name
+ void rename(int fingerId, int groupId, String name);
- // Start listening for fingerprint events. This has the side effect of starting
- // the hardware if not already started.
- void startListening(IBinder token, IFingerprintServiceReceiver receiver, int userId);
+ // Get a list of enrolled fingerprints in the given group.
+ List<Fingerprint> getEnrolledFingerprints(int groupId);
- // Stops listening for fingerprints
- void stopListening(IBinder token, int userId);
+ // Register listener for an instance of FingerprintManager
+ void addListener(IBinder token, IFingerprintServiceReceiver receiver, int userId);
+
+ // Unregister listener for an instance of FingerprintManager
+ void removeListener(IBinder token, IFingerprintServiceReceiver receiver);
// Determine if HAL is loaded and ready
- boolean isHardwareDetected();
+ boolean isHardwareDetected(long deviceId);
+
+ // Gets the number of hardware devices
+ // int getHardwareDeviceCount();
+
+ // Gets the unique device id for hardware enumerated at i
+ // long getHardwareDevice(int i);
- // Rename the given fingerprint id
- void rename(int fpId, String name);
}
diff --git a/core/java/android/service/fingerprint/IFingerprintServiceReceiver.aidl b/core/java/android/service/fingerprint/IFingerprintServiceReceiver.aidl
index af4128f..f025064 100644
--- a/core/java/android/service/fingerprint/IFingerprintServiceReceiver.aidl
+++ b/core/java/android/service/fingerprint/IFingerprintServiceReceiver.aidl
@@ -23,9 +23,9 @@ import android.os.UserHandle;
* @hide
*/
oneway interface IFingerprintServiceReceiver {
- void onEnrollResult(int fingerprintId, int remaining);
- void onAcquired(int acquiredInfo);
- void onProcessed(int fingerprintId);
- void onError(int error);
- void onRemoved(int fingerprintId);
+ void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining);
+ void onAcquired(long deviceId, int acquiredInfo);
+ void onProcessed(long deviceId, int fingerId, int groupId);
+ void onError(long deviceId, int error);
+ void onRemoved(long deviceId, int fingerId, int groupId);
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index d46b6f5..1674950 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -155,7 +155,6 @@ public abstract class WallpaperService extends Service {
WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
int mCurWindowFlags = mWindowFlags;
int mCurWindowPrivateFlags = mWindowPrivateFlags;
- int mOutsetBottomPx;
final Rect mVisibleInsets = new Rect();
final Rect mWinFrame = new Rect();
final Rect mOverscanInsets = new Rect();
@@ -624,18 +623,9 @@ public abstract class WallpaperService extends Service {
mLayout.token = mWindowToken;
if (!mCreated) {
- // Retrieve watch round and outset info
- final WindowManager windowService = (WindowManager)getSystemService(
- Context.WINDOW_SERVICE);
+ // Retrieve watch round info
TypedArray windowStyle = obtainStyledAttributes(
com.android.internal.R.styleable.Window);
- final Display display = windowService.getDefaultDisplay();
- final boolean shouldUseBottomOutset =
- display.getDisplayId() == Display.DEFAULT_DISPLAY;
- if (shouldUseBottomOutset) {
- mOutsetBottomPx = ScreenShapeHelper.getWindowOutsetBottomPx(
- getResources().getDisplayMetrics(), windowStyle);
- }
mWindowIsRound = ScreenShapeHelper.getWindowIsRound(getResources());
windowStyle.recycle();
@@ -770,10 +760,7 @@ public abstract class WallpaperService extends Service {
mDispatchedStableInsets.set(mStableInsets);
mFinalSystemInsets.set(mDispatchedOverscanInsets);
mFinalStableInsets.set(mDispatchedStableInsets);
- if (mOutsetBottomPx != 0) {
- mFinalSystemInsets.bottom =
- mIWallpaperEngine.mDisplayPadding.bottom + mOutsetBottomPx;
- }
+ mFinalSystemInsets.bottom = mIWallpaperEngine.mDisplayPadding.bottom;
WindowInsets insets = new WindowInsets(mFinalSystemInsets,
null, mFinalStableInsets, mWindowIsRound);
onApplyWindowInsets(insets);
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index 8cf1b4b..7bebbfb 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -244,13 +244,18 @@ public class Html {
next++;
}
- withinParagraph(out, text, i, next - nl, nl, next == end);
+ if (withinParagraph(out, text, i, next - nl, nl, next == end)) {
+ /* Paragraph should be closed */
+ out.append("</p>\n");
+ out.append(getOpenParaTagWithDirection(text, next, end));
+ }
}
out.append("</p>\n");
}
- private static void withinParagraph(StringBuilder out, Spanned text,
+ /* Returns true if the caller should close and reopen the paragraph. */
+ private static boolean withinParagraph(StringBuilder out, Spanned text,
int start, int end, int nl,
boolean last) {
int next;
@@ -363,17 +368,14 @@ public class Html {
}
}
- String p = last ? "" : "</p>\n" + getOpenParaTagWithDirection(text, start, end);
-
if (nl == 1) {
out.append("<br>\n");
- } else if (nl == 2) {
- out.append(p);
+ return false;
} else {
for (int i = 2; i < nl; i++) {
out.append("<br>");
}
- out.append(p);
+ return !last;
}
}
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index fcf1828..928bf16 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1153,7 +1153,10 @@ public abstract class Layout {
return end - 1;
}
- if (ch != ' ' && ch != '\t') {
+ // Note: keep this in sync with Minikin LineBreaker::isLineEndSpace()
+ if (!(ch == ' ' || ch == '\t' || ch == 0x1680 ||
+ (0x2000 <= ch && ch <= 0x200A && ch != 0x2007) ||
+ ch == 0x205F || ch == 0x3000)) {
break;
}
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index ee39e27..b47418f 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -170,8 +170,9 @@ public class StaticLayout extends Layout {
* Measurement and break iteration is done in native code. The protocol for using
* the native code is as follows.
*
- * For each paragraph, do a nSetText of the paragraph text. Then, for each run within the
- * paragraph:
+ * For each paragraph, do a nSetText of the paragraph text. Also do nSetLineWidth.
+ *
+ * Then, for each run within the paragraph:
* - setLocale (this must be done at least for the first run, optional afterwards)
* - one of the following, depending on the type of run:
* + addStyleRun (a text run, to be measured in native code)
@@ -459,7 +460,26 @@ public class StaticLayout extends Layout {
byte[] chdirs = measured.mLevels;
int dir = measured.mDir;
boolean easy = measured.mEasy;
- nSetText(b.mNativePtr, chs, paraEnd - paraStart);
+
+ // tab stop locations
+ int[] variableTabStops = null;
+ if (spanned != null) {
+ TabStopSpan[] spans = getParagraphSpans(spanned, paraStart,
+ paraEnd, TabStopSpan.class);
+ if (spans.length > 0) {
+ int[] stops = new int[spans.length];
+ for (int i = 0; i < spans.length; i++) {
+ stops[i] = spans[i].getTabStop();
+ }
+ Arrays.sort(stops, 0, stops.length);
+ variableTabStops = stops;
+ }
+ }
+
+ int breakStrategy = 0; // 0 = kBreakStrategy_Greedy
+ nSetupParagraph(b.mNativePtr, chs, paraEnd - paraStart,
+ firstWidth, firstWidthLineCount, restWidth,
+ variableTabStops, TAB_INCREMENT, breakStrategy);
// measurement has to be done before performing line breaking
// but we don't want to recompute fontmetrics or span ranges the
@@ -505,25 +525,9 @@ public class StaticLayout extends Layout {
spanEndCacheCount++;
}
- // tab stop locations
- int[] variableTabStops = null;
- if (spanned != null) {
- TabStopSpan[] spans = getParagraphSpans(spanned, paraStart,
- paraEnd, TabStopSpan.class);
- if (spans.length > 0) {
- int[] stops = new int[spans.length];
- for (int i = 0; i < spans.length; i++) {
- stops[i] = spans[i].getTabStop();
- }
- Arrays.sort(stops, 0, stops.length);
- variableTabStops = stops;
- }
- }
-
nGetWidths(b.mNativePtr, widths);
- int breakCount = nComputeLineBreaks(b.mNativePtr, paraEnd - paraStart, firstWidth,
- firstWidthLineCount, restWidth, variableTabStops, TAB_INCREMENT, false, lineBreaks,
- lineBreaks.breaks, lineBreaks.widths, lineBreaks.flags, lineBreaks.breaks.length);
+ int breakCount = nComputeLineBreaks(b.mNativePtr, lineBreaks, lineBreaks.breaks,
+ lineBreaks.widths, lineBreaks.flags, lineBreaks.breaks.length);
int[] breaks = lineBreaks.breaks;
float[] lineWidths = lineBreaks.widths;
@@ -966,7 +970,10 @@ public class StaticLayout extends Layout {
private static native void nFinishBuilder(long nativePtr);
private static native void nSetLocale(long nativePtr, String locale);
- private static native void nSetText(long nativePtr, char[] text, int length);
+ // Set up paragraph text and settings; done as one big method to minimize jni crossings
+ private static native void nSetupParagraph(long nativePtr, char[] text, int length,
+ float firstWidth, int firstWidthLineCount, float restWidth,
+ int[] variableTabStops, int defaultTabStop, int breakStrategy);
private static native float nAddStyleRun(long nativePtr, long nativePaint,
long nativeTypeface, int start, int end, boolean isRtl);
@@ -983,9 +990,7 @@ public class StaticLayout extends Layout {
// the arrays inside the LineBreaks objects are passed in as well
// to reduce the number of JNI calls in the common case where the
// arrays do not have to be resized
- private static native int nComputeLineBreaks(long nativePtr,
- int length, float firstWidth, int firstWidthLineCount, float restWidth,
- int[] variableTabStops, int defaultTabStop, boolean optimize, LineBreaks recycle,
+ private static native int nComputeLineBreaks(long nativePtr, LineBreaks recycle,
int[] recycleBreaks, float[] recycleWidths, boolean[] recycleFlags, int recycleLength);
private int mLineCount;
diff --git a/core/java/android/text/style/URLSpan.java b/core/java/android/text/style/URLSpan.java
index d29bfb6..0669b6f 100644
--- a/core/java/android/text/style/URLSpan.java
+++ b/core/java/android/text/style/URLSpan.java
@@ -16,6 +16,7 @@
package android.text.style;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
@@ -23,6 +24,7 @@ import android.os.Parcel;
import android.provider.Browser;
import android.text.ParcelableSpan;
import android.text.TextUtils;
+import android.util.Log;
import android.view.View;
public class URLSpan extends ClickableSpan implements ParcelableSpan {
@@ -59,6 +61,10 @@ public class URLSpan extends ClickableSpan implements ParcelableSpan {
Context context = widget.getContext();
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
- context.startActivity(intent);
+ try {
+ context.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w("URLSpan", "Actvity was not found for intent, " + intent.toString());
+ }
}
}
diff --git a/core/java/android/util/IntArray.java b/core/java/android/util/IntArray.java
index e8d3947..9326203 100644
--- a/core/java/android/util/IntArray.java
+++ b/core/java/android/util/IntArray.java
@@ -18,6 +18,7 @@ package android.util;
import com.android.internal.util.ArrayUtils;
+import java.util.Arrays;
import libcore.util.EmptyArray;
/**
@@ -78,6 +79,24 @@ public class IntArray implements Cloneable {
}
/**
+ * Searches the array for the specified value using the binary search algorithm. The array must
+ * be sorted (as by the {@link Arrays#sort(int[], int, int)} method) prior to making this call.
+ * If it is not sorted, the results are undefined. If the range contains multiple elements with
+ * the specified value, there is no guarantee which one will be found.
+ *
+ * @param value The value to search for.
+ * @return index of the search key, if it is contained in the array; otherwise, <i>(-(insertion
+ * point) - 1)</i>. The insertion point is defined as the point at which the key would
+ * be inserted into the array: the index of the first element greater than the key, or
+ * {@link #size()} if all elements in the array are less than the specified key.
+ * Note that this guarantees that the return value will be >= 0 if and only if the key
+ * is found.
+ */
+ public int binarySearch(int value) {
+ return ContainerHelpers.binarySearch(mValues, mSize, value);
+ }
+
+ /**
* Adds the values in the specified array to this array.
*/
public void addAll(IntArray values) {
@@ -159,4 +178,11 @@ public class IntArray implements Cloneable {
public int size() {
return mSize;
}
+
+ /**
+ * Returns a new array with the contents of this IntArray.
+ */
+ public int[] toArray() {
+ return Arrays.copyOf(mValues, mSize);
+ }
}
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 59ec058..ad34f02 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -723,6 +723,12 @@ public class TextureView extends View {
mSurface.release();
}
mSurface = surfaceTexture;
+
+ // If the view is visible, update the listener in the new surface to use
+ // the existing listener in the view.
+ if (((mViewFlags & VISIBILITY_MASK) == VISIBLE)) {
+ mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler);
+ }
mUpdateSurface = true;
invalidateParentIfNeeded();
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f5de8e3..cfcc6fe 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -83,6 +83,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEventSource;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -3168,6 +3169,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private Drawable mBackground;
private TintInfo mBackgroundTint;
+ @ViewDebug.ExportedProperty(deepExport = true, prefix = "fg_")
+ private ForegroundInfo mForegroundInfo;
+
/**
* RenderNode used for backgrounds.
* <p>
@@ -3182,13 +3186,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private String mTransitionName;
- private static class TintInfo {
+ static class TintInfo {
ColorStateList mTintList;
PorterDuff.Mode mTintMode;
boolean mHasTintMode;
boolean mHasTintList;
}
+ private static class ForegroundInfo {
+ private Drawable mDrawable;
+ private TintInfo mTintInfo;
+ private int mGravity = Gravity.FILL;
+ private boolean mInsidePadding = true;
+ private boolean mBoundsChanged = true;
+ private final Rect mSelfBounds = new Rect();
+ private final Rect mOverlayBounds = new Rect();
+ }
+
static class ListenerInfo {
/**
* Listener used to dispatch focus change events.
@@ -4056,6 +4070,25 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
setOutlineProviderFromAttribute(a.getInt(R.styleable.View_outlineProvider,
PROVIDER_BACKGROUND));
break;
+ case R.styleable.View_foreground:
+ setForeground(a.getDrawable(attr));
+ break;
+ case R.styleable.View_foregroundGravity:
+ setForegroundGravity(a.getInt(attr, Gravity.NO_GRAVITY));
+ break;
+ case R.styleable.View_foregroundTintMode:
+ setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null));
+ break;
+ case R.styleable.View_foregroundTint:
+ setForegroundTintList(a.getColorStateList(attr));
+ break;
+ case R.styleable.View_foregroundInsidePadding:
+ if (mForegroundInfo == null) {
+ mForegroundInfo = new ForegroundInfo();
+ }
+ mForegroundInfo.mInsidePadding = a.getBoolean(attr,
+ mForegroundInfo.mInsidePadding);
+ break;
}
}
@@ -4813,10 +4846,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
protected boolean performButtonActionOnTouchDown(MotionEvent event) {
- if ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
- if (showContextMenu(event.getX(), event.getY(), event.getMetaState())) {
- return true;
- }
+ if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE &&
+ (event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {
+ showContextMenu(event.getX(), event.getY(), event.getMetaState());
+ mPrivateFlags |= PFLAG_CANCEL_NEXT_UP_EVENT;
+ return true;
}
return false;
}
@@ -5781,6 +5815,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
| AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
}
+
+ info.addAction(AccessibilityAction.ACTION_SHOW_ON_SCREEN);
}
private View findLabelForView(View view, int labeledId) {
@@ -8228,6 +8264,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return true;
}
} break;
+ case R.id.accessibility_action_show_on_screen: {
+ if (mAttachInfo != null) {
+ final Rect r = mAttachInfo.mTmpInvalRect;
+ getDrawingRect(r);
+ return requestRectangleOnScreen(r, true);
+ }
+ } break;
}
return false;
}
@@ -8801,6 +8844,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (dr != null && visible != dr.isVisible()) {
dr.setVisible(visible, false);
}
+ final Drawable fg = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
+ if (fg != null && visible != fg.isVisible()) {
+ fg.setVisible(visible, false);
+ }
}
/**
@@ -9917,6 +9964,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
mBackgroundSizeChanged = true;
+ if (mForegroundInfo != null) {
+ mForegroundInfo.mBoundsChanged = true;
+ }
final AttachInfo ai = mAttachInfo;
if (ai != null) {
@@ -10755,6 +10805,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
invalidate(true);
}
mBackgroundSizeChanged = true;
+ if (mForegroundInfo != null) {
+ mForegroundInfo.mBoundsChanged = true;
+ }
invalidateParentIfNeeded();
if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
@@ -10820,6 +10873,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
invalidate(true);
}
mBackgroundSizeChanged = true;
+ if (mForegroundInfo != null) {
+ mForegroundInfo.mBoundsChanged = true;
+ }
invalidateParentIfNeeded();
if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
@@ -10879,6 +10935,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
invalidate(true);
}
mBackgroundSizeChanged = true;
+ if (mForegroundInfo != null) {
+ mForegroundInfo.mBoundsChanged = true;
+ }
invalidateParentIfNeeded();
if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
@@ -10935,6 +10994,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
invalidate(true);
}
mBackgroundSizeChanged = true;
+ if (mForegroundInfo != null) {
+ mForegroundInfo.mBoundsChanged = true;
+ }
invalidateParentIfNeeded();
if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
@@ -15313,13 +15375,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// Step 4, draw the children
dispatchDraw(canvas);
- // Step 6, draw decorations (scrollbars)
- onDrawScrollBars(canvas);
-
+ // Overlay is part of the content and draws beneath Foreground
if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().dispatchDraw(canvas);
}
+ // Step 6, draw decorations (foreground, scrollbars)
+ onDrawForeground(canvas);
+
// we're done...
return;
}
@@ -15461,12 +15524,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
canvas.restoreToCount(saveCount);
- // Step 6, draw decorations (scrollbars)
- onDrawScrollBars(canvas);
-
+ // Overlay is part of the content and draws beneath Foreground
if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().dispatchDraw(canvas);
}
+
+ // Step 6, draw decorations (foreground, scrollbars)
+ onDrawForeground(canvas);
}
/**
@@ -15849,6 +15913,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mPrivateFlags |= drawn;
mBackgroundSizeChanged = true;
+ if (mForegroundInfo != null) {
+ mForegroundInfo.mBoundsChanged = true;
+ }
notifySubtreeAccessibilityStateChangedIfNeeded();
}
@@ -15992,6 +16059,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mBackground != null) {
mBackground.setLayoutDirection(layoutDirection);
}
+ if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
+ mForegroundInfo.mDrawable.setLayoutDirection(layoutDirection);
+ }
mPrivateFlags2 |= PFLAG2_DRAWABLE_RESOLVED;
onResolveDrawables(layoutDirection);
}
@@ -16047,7 +16117,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@CallSuper
protected boolean verifyDrawable(Drawable who) {
- return who == mBackground || (mScrollCache != null && mScrollCache.scrollBar == who);
+ return who == mBackground || (mScrollCache != null && mScrollCache.scrollBar == who)
+ || (mForegroundInfo != null && mForegroundInfo.mDrawable == who);
}
/**
@@ -16065,9 +16136,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
protected void drawableStateChanged() {
final int[] state = getDrawableState();
- final Drawable d = mBackground;
- if (d != null && d.isStateful()) {
- d.setState(state);
+ final Drawable bg = mBackground;
+ if (bg != null && bg.isStateful()) {
+ bg.setState(state);
+ }
+
+ final Drawable fg = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
+ if (fg != null && fg.isStateful()) {
+ fg.setState(state);
}
if (mScrollCache != null) {
@@ -16099,6 +16175,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mBackground != null) {
mBackground.setHotspot(x, y);
}
+ if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
+ mForegroundInfo.mDrawable.setHotspot(x, y);
+ }
dispatchDrawableHotspotChanged(x, y);
}
@@ -16270,6 +16349,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mStateListAnimator != null) {
mStateListAnimator.jumpToCurrentState();
}
+ if (mForegroundInfo != null && mForegroundInfo.mDrawable != null) {
+ mForegroundInfo.mDrawable.jumpToCurrentState();
+ }
}
/**
@@ -16554,6 +16636,249 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Returns the drawable used as the foreground of this View. The
+ * foreground drawable, if non-null, is always drawn on top of the view's content.
+ *
+ * @return a Drawable or null if no foreground was set
+ *
+ * @see #onDrawForeground(Canvas)
+ */
+ public Drawable getForeground() {
+ return mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
+ }
+
+ /**
+ * Supply a Drawable that is to be rendered on top of all of the content in the view.
+ *
+ * @param foreground the Drawable to be drawn on top of the children
+ *
+ * @attr ref android.R.styleable#View_foreground
+ */
+ public void setForeground(Drawable foreground) {
+ if (mForegroundInfo == null) {
+ if (foreground == null) {
+ // Nothing to do.
+ return;
+ }
+ mForegroundInfo = new ForegroundInfo();
+ }
+
+ if (foreground == mForegroundInfo.mDrawable) {
+ // Nothing to do
+ return;
+ }
+
+ if (mForegroundInfo.mDrawable != null) {
+ mForegroundInfo.mDrawable.setCallback(null);
+ unscheduleDrawable(mForegroundInfo.mDrawable);
+ }
+
+ mForegroundInfo.mDrawable = foreground;
+ mForegroundInfo.mBoundsChanged = true;
+ if (foreground != null) {
+ setWillNotDraw(false);
+ foreground.setCallback(this);
+ foreground.setLayoutDirection(getLayoutDirection());
+ if (foreground.isStateful()) {
+ foreground.setState(getDrawableState());
+ }
+ applyForegroundTint();
+ }
+ requestLayout();
+ invalidate();
+ }
+
+ /**
+ * Magic bit used to support features of framework-internal window decor implementation details.
+ * This used to live exclusively in FrameLayout.
+ *
+ * @return true if the foreground should draw inside the padding region or false
+ * if it should draw inset by the view's padding
+ * @hide internal use only; only used by FrameLayout and internal screen layouts.
+ */
+ public boolean isForegroundInsidePadding() {
+ return mForegroundInfo != null ? mForegroundInfo.mInsidePadding : true;
+ }
+
+ /**
+ * Describes how the foreground is positioned.
+ *
+ * @return foreground gravity.
+ *
+ * @see #setForegroundGravity(int)
+ *
+ * @attr ref android.R.styleable#View_foregroundGravity
+ */
+ public int getForegroundGravity() {
+ return mForegroundInfo != null ? mForegroundInfo.mGravity
+ : Gravity.START | Gravity.TOP;
+ }
+
+ /**
+ * Describes how the foreground is positioned. Defaults to START and TOP.
+ *
+ * @param gravity see {@link android.view.Gravity}
+ *
+ * @see #getForegroundGravity()
+ *
+ * @attr ref android.R.styleable#View_foregroundGravity
+ */
+ public void setForegroundGravity(int gravity) {
+ if (mForegroundInfo == null) {
+ mForegroundInfo = new ForegroundInfo();
+ }
+
+ if (mForegroundInfo.mGravity != gravity) {
+ if ((gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
+ gravity |= Gravity.START;
+ }
+
+ if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
+ gravity |= Gravity.TOP;
+ }
+
+ mForegroundInfo.mGravity = gravity;
+ requestLayout();
+ }
+ }
+
+ /**
+ * Applies a tint to the foreground drawable. Does not modify the current tint
+ * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+ * <p>
+ * Subsequent calls to {@link #setForeground(Drawable)} will automatically
+ * mutate the drawable and apply the specified tint and tint mode using
+ * {@link Drawable#setTintList(ColorStateList)}.
+ *
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ *
+ * @attr ref android.R.styleable#View_foregroundTint
+ * @see #getForegroundTintList()
+ * @see Drawable#setTintList(ColorStateList)
+ */
+ public void setForegroundTintList(@Nullable ColorStateList tint) {
+ if (mForegroundInfo == null) {
+ mForegroundInfo = new ForegroundInfo();
+ }
+ if (mForegroundInfo.mTintInfo == null) {
+ mForegroundInfo.mTintInfo = new TintInfo();
+ }
+ mForegroundInfo.mTintInfo.mTintList = tint;
+ mForegroundInfo.mTintInfo.mHasTintList = true;
+
+ applyForegroundTint();
+ }
+
+ /**
+ * Return the tint applied to the foreground drawable, if specified.
+ *
+ * @return the tint applied to the foreground drawable
+ * @attr ref android.R.styleable#View_foregroundTint
+ * @see #setForegroundTintList(ColorStateList)
+ */
+ @Nullable
+ public ColorStateList getForegroundTintList() {
+ return mForegroundInfo != null && mForegroundInfo.mTintInfo != null
+ ? mBackgroundTint.mTintList : null;
+ }
+
+ /**
+ * Specifies the blending mode used to apply the tint specified by
+ * {@link #setForegroundTintList(ColorStateList)}} to the background
+ * drawable. The default mode is {@link PorterDuff.Mode#SRC_IN}.
+ *
+ * @param tintMode the blending mode used to apply the tint, may be
+ * {@code null} to clear tint
+ * @attr ref android.R.styleable#View_foregroundTintMode
+ * @see #getForegroundTintMode()
+ * @see Drawable#setTintMode(PorterDuff.Mode)
+ */
+ public void setForegroundTintMode(@Nullable PorterDuff.Mode tintMode) {
+ if (mBackgroundTint == null) {
+ mBackgroundTint = new TintInfo();
+ }
+ mBackgroundTint.mTintMode = tintMode;
+ mBackgroundTint.mHasTintMode = true;
+
+ applyBackgroundTint();
+ }
+
+ /**
+ * Return the blending mode used to apply the tint to the foreground
+ * drawable, if specified.
+ *
+ * @return the blending mode used to apply the tint to the foreground
+ * drawable
+ * @attr ref android.R.styleable#View_foregroundTintMode
+ * @see #setBackgroundTintMode(PorterDuff.Mode)
+ */
+ @Nullable
+ public PorterDuff.Mode getForegroundTintMode() {
+ return mForegroundInfo != null && mForegroundInfo.mTintInfo != null
+ ? mForegroundInfo.mTintInfo.mTintMode : null;
+ }
+
+ private void applyForegroundTint() {
+ if (mForegroundInfo != null && mForegroundInfo.mDrawable != null
+ && mForegroundInfo.mTintInfo != null) {
+ final TintInfo tintInfo = mForegroundInfo.mTintInfo;
+ if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
+ mForegroundInfo.mDrawable = mForegroundInfo.mDrawable.mutate();
+
+ if (tintInfo.mHasTintList) {
+ mForegroundInfo.mDrawable.setTintList(tintInfo.mTintList);
+ }
+
+ if (tintInfo.mHasTintMode) {
+ mForegroundInfo.mDrawable.setTintMode(tintInfo.mTintMode);
+ }
+
+ // The drawable (or one of its children) may not have been
+ // stateful before applying the tint, so let's try again.
+ if (mForegroundInfo.mDrawable.isStateful()) {
+ mForegroundInfo.mDrawable.setState(getDrawableState());
+ }
+ }
+ }
+ }
+
+ /**
+ * Draw any foreground content for this view.
+ *
+ * <p>Foreground content may consist of scroll bars, a {@link #setForeground foreground}
+ * drawable or other view-specific decorations. The foreground is drawn on top of the
+ * primary view content.</p>
+ *
+ * @param canvas canvas to draw into
+ */
+ public void onDrawForeground(Canvas canvas) {
+ onDrawScrollBars(canvas);
+
+ final Drawable foreground = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
+ if (foreground != null) {
+ if (mForegroundInfo.mBoundsChanged) {
+ mForegroundInfo.mBoundsChanged = false;
+ final Rect selfBounds = mForegroundInfo.mSelfBounds;
+ final Rect overlayBounds = mForegroundInfo.mOverlayBounds;
+
+ if (mForegroundInfo.mInsidePadding) {
+ selfBounds.set(0, 0, getWidth(), getHeight());
+ } else {
+ selfBounds.set(getPaddingLeft(), getPaddingTop(),
+ getWidth() - getPaddingRight(), getHeight() - getPaddingBottom());
+ }
+
+ final int ld = getLayoutDirection();
+ Gravity.apply(mForegroundInfo.mGravity, foreground.getIntrinsicWidth(),
+ foreground.getIntrinsicHeight(), selfBounds, overlayBounds, ld);
+ foreground.setBounds(overlayBounds);
+ }
+
+ foreground.draw(canvas);
+ }
+ }
+
+ /**
* Sets the padding. The view may add on the space required to display
* the scrollbars, depending on the style and visibility of the scrollbars.
* So the values returned from {@link #getPaddingLeft}, {@link #getPaddingTop},
@@ -18090,6 +18415,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// parts from this transparent region.
applyDrawableToTransparentRegion(mBackground, region);
}
+ final Drawable foreground = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
+ if (foreground != null) {
+ applyDrawableToTransparentRegion(mForegroundInfo.mDrawable, region);
+ }
}
return true;
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 6096d7d..77082b0 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -29,6 +29,8 @@ import android.util.LongArray;
import android.util.Pools.SynchronizedPool;
import android.view.View;
+import com.android.internal.R;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -3402,6 +3404,15 @@ public class AccessibilityNodeInfo implements Parcelable {
new AccessibilityAction(
AccessibilityNodeInfo.ACTION_SET_TEXT, null);
+ /**
+ * Action that requests the node make its bounding rectangle visible
+ * on the screen, scrolling if necessary just enough.
+ *
+ * @see View#requestRectangleOnScreen(Rect)
+ */
+ public static final AccessibilityAction ACTION_SHOW_ON_SCREEN =
+ new AccessibilityAction(R.id.accessibility_action_show_on_screen, null);
+
private static final ArraySet<AccessibilityAction> sStandardActions = new ArraySet<AccessibilityAction>();
static {
sStandardActions.add(ACTION_FOCUS);
@@ -3426,6 +3437,7 @@ public class AccessibilityNodeInfo implements Parcelable {
sStandardActions.add(ACTION_COLLAPSE);
sStandardActions.add(ACTION_DISMISS);
sStandardActions.add(ACTION_SET_TEXT);
+ sStandardActions.add(ACTION_SHOW_ON_SCREEN);
}
private final int mActionId;
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index 4737e9b..0b18bb8 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -284,13 +284,19 @@ public class WebChromeClient {
* currently set for that origin. The host application should invoke the
* specified callback with the desired permission state. See
* {@link GeolocationPermissions} for details.
+ *
+ * If this method isn't overridden, the callback is invoked with permission
+ * denied state.
+ *
* @param origin The origin of the web content attempting to use the
* Geolocation API.
* @param callback The callback to use to set the permission state for the
* origin.
*/
public void onGeolocationPermissionsShowPrompt(String origin,
- GeolocationPermissions.Callback callback) {}
+ GeolocationPermissions.Callback callback) {
+ callback.invoke(origin, false, false);
+ }
/**
* Notify the host application that a request for Geolocation permissions,
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 87fcd81..6e24837 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -4664,8 +4664,8 @@ public class Editor {
// Otherwise the user inserted the composition.
String newText = TextUtils.substring(source, start, end);
- EditOperation edit = new EditOperation(mEditor, false, "", dstart, newText);
- recordEdit(edit);
+ EditOperation edit = new EditOperation(mEditor, "", dstart, newText);
+ recordEdit(edit, false /* forceMerge */);
return true;
}
@@ -4684,11 +4684,15 @@ public class Editor {
// Build a new operation with all the information from this edit.
String newText = TextUtils.substring(source, start, end);
String oldText = TextUtils.substring(dest, dstart, dend);
- EditOperation edit = new EditOperation(mEditor, forceMerge, oldText, dstart, newText);
- recordEdit(edit);
+ EditOperation edit = new EditOperation(mEditor, oldText, dstart, newText);
+ recordEdit(edit, forceMerge);
}
- private void recordEdit(EditOperation edit) {
+ /**
+ * Fetches the last undo operation and checks to see if a new edit should be merged into it.
+ * If forceMerge is true then the new edit is always merged.
+ */
+ private void recordEdit(EditOperation edit, boolean forceMerge) {
// Fetch the last edit operation and attempt to merge in the new edit.
final UndoManager um = mEditor.mUndoManager;
um.beginUpdate("Edit text");
@@ -4698,6 +4702,11 @@ public class Editor {
// Add this as the first edit.
if (DEBUG_UNDO) Log.d(TAG, "filter: adding first op " + edit);
um.addOperation(edit, UndoManager.MERGE_MODE_NONE);
+ } else if (forceMerge) {
+ // Forced merges take priority because they could be the result of a non-user-edit
+ // change and this case should not create a new undo operation.
+ if (DEBUG_UNDO) Log.d(TAG, "filter: force merge " + edit);
+ lastEdit.forceMergeWith(edit);
} else if (!mIsUserEdit) {
// An application directly modified the Editable outside of a text edit. Treat this
// as a new change and don't attempt to merge.
@@ -4773,7 +4782,6 @@ public class Editor {
private static final int TYPE_REPLACE = 2;
private int mType;
- private boolean mForceMerge;
private String mOldText;
private int mOldTextStart;
private String mNewText;
@@ -4784,13 +4792,10 @@ public class Editor {
/**
* Constructs an edit operation from a text input operation on editor that replaces the
- * oldText starting at dstart with newText. If forceMerge is true then always forcibly
- * merge this operation with any previous one.
+ * oldText starting at dstart with newText.
*/
- public EditOperation(Editor editor, boolean forceMerge, String oldText, int dstart,
- String newText) {
+ public EditOperation(Editor editor, String oldText, int dstart, String newText) {
super(editor.mUndoOwner);
- mForceMerge = forceMerge;
mOldText = oldText;
mNewText = newText;
@@ -4817,7 +4822,6 @@ public class Editor {
public EditOperation(Parcel src, ClassLoader loader) {
super(src, loader);
mType = src.readInt();
- mForceMerge = src.readInt() != 0;
mOldText = src.readString();
mOldTextStart = src.readInt();
mNewText = src.readString();
@@ -4829,7 +4833,6 @@ public class Editor {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mType);
- dest.writeInt(mForceMerge ? 1 : 0);
dest.writeString(mOldText);
dest.writeInt(mOldTextStart);
dest.writeString(mNewText);
@@ -4881,10 +4884,6 @@ public class Editor {
Log.d(TAG, "mergeWith old " + this);
Log.d(TAG, "mergeWith new " + edit);
}
- if (edit.mForceMerge) {
- forceMergeWith(edit);
- return true;
- }
switch (mType) {
case TYPE_INSERT:
return mergeInsertWith(edit);
@@ -4942,7 +4941,7 @@ public class Editor {
* Forcibly creates a single merged edit operation by simulating the entire text
* contents being replaced.
*/
- private void forceMergeWith(EditOperation edit) {
+ public void forceMergeWith(EditOperation edit) {
if (DEBUG_UNDO) Log.d(TAG, "forceMerge");
Editor editor = getOwnerData();
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index f6d198b..0602944 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -53,8 +53,6 @@ import com.android.internal.R;
* only if {@link #setMeasureAllChildren(boolean) setConsiderGoneChildrenWhenMeasuring()}
* is set to true.
*
- * @attr ref android.R.styleable#FrameLayout_foreground
- * @attr ref android.R.styleable#FrameLayout_foregroundGravity
* @attr ref android.R.styleable#FrameLayout_measureAllChildren
*/
@RemoteView
@@ -64,13 +62,6 @@ public class FrameLayout extends ViewGroup {
@ViewDebug.ExportedProperty(category = "measurement")
boolean mMeasureAllChildren = false;
- @ViewDebug.ExportedProperty(category = "drawing")
- private Drawable mForeground;
- private ColorStateList mForegroundTintList = null;
- private PorterDuff.Mode mForegroundTintMode = null;
- private boolean mHasForegroundTint = false;
- private boolean mHasForegroundTintMode = false;
-
@ViewDebug.ExportedProperty(category = "padding")
private int mForegroundPaddingLeft = 0;
@@ -85,15 +76,6 @@ public class FrameLayout extends ViewGroup {
private final Rect mSelfBounds = new Rect();
private final Rect mOverlayBounds = new Rect();
-
- @ViewDebug.ExportedProperty(category = "drawing")
- private int mForegroundGravity = Gravity.FILL;
-
- /** {@hide} */
- @ViewDebug.ExportedProperty(category = "drawing")
- protected boolean mForegroundInPadding = true;
-
- boolean mForegroundBoundsChanged = false;
private final ArrayList<View> mMatchParentChildren = new ArrayList<View>(1);
@@ -115,48 +97,12 @@ public class FrameLayout extends ViewGroup {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.FrameLayout, defStyleAttr, defStyleRes);
-
- mForegroundGravity = a.getInt(
- com.android.internal.R.styleable.FrameLayout_foregroundGravity, mForegroundGravity);
-
- final Drawable d = a.getDrawable(com.android.internal.R.styleable.FrameLayout_foreground);
- if (d != null) {
- setForeground(d);
- }
if (a.getBoolean(com.android.internal.R.styleable.FrameLayout_measureAllChildren, false)) {
setMeasureAllChildren(true);
}
- if (a.hasValue(R.styleable.FrameLayout_foregroundTintMode)) {
- mForegroundTintMode = Drawable.parseTintMode(a.getInt(
- R.styleable.FrameLayout_foregroundTintMode, -1), mForegroundTintMode);
- mHasForegroundTintMode = true;
- }
-
- if (a.hasValue(R.styleable.FrameLayout_foregroundTint)) {
- mForegroundTintList = a.getColorStateList(R.styleable.FrameLayout_foregroundTint);
- mHasForegroundTint = true;
- }
-
- mForegroundInPadding = a.getBoolean(R.styleable.FrameLayout_foregroundInsidePadding, true);
-
a.recycle();
-
- applyForegroundTint();
- }
-
- /**
- * Describes how the foreground is positioned.
- *
- * @return foreground gravity.
- *
- * @see #setForegroundGravity(int)
- *
- * @attr ref android.R.styleable#FrameLayout_foregroundGravity
- */
- public int getForegroundGravity() {
- return mForegroundGravity;
}
/**
@@ -166,25 +112,18 @@ public class FrameLayout extends ViewGroup {
*
* @see #getForegroundGravity()
*
- * @attr ref android.R.styleable#FrameLayout_foregroundGravity
+ * @attr ref android.R.styleable#View_foregroundGravity
*/
@android.view.RemotableViewMethod
public void setForegroundGravity(int foregroundGravity) {
- if (mForegroundGravity != foregroundGravity) {
- if ((foregroundGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
- foregroundGravity |= Gravity.START;
- }
-
- if ((foregroundGravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
- foregroundGravity |= Gravity.TOP;
- }
-
- mForegroundGravity = foregroundGravity;
-
+ if (getForegroundGravity() != foregroundGravity) {
+ super.setForegroundGravity(foregroundGravity);
- if (mForegroundGravity == Gravity.FILL && mForeground != null) {
+ // calling get* again here because the set above may apply default constraints
+ final Drawable foreground = getForeground();
+ if (getForegroundGravity() == Gravity.FILL && foreground != null) {
Rect padding = new Rect();
- if (mForeground.getPadding(padding)) {
+ if (foreground.getPadding(padding)) {
mForegroundPaddingLeft = padding.left;
mForegroundPaddingTop = padding.top;
mForegroundPaddingRight = padding.right;
@@ -201,53 +140,6 @@ public class FrameLayout extends ViewGroup {
}
}
- @Override
- protected void onVisibilityChanged(@NonNull View changedView, @Visibility int visibility) {
- super.onVisibilityChanged(changedView, visibility);
-
- final Drawable dr = mForeground;
- if (dr != null) {
- final boolean visible = visibility == VISIBLE && getVisibility() == VISIBLE;
- if (visible != dr.isVisible()) {
- dr.setVisible(visible, false);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected boolean verifyDrawable(Drawable who) {
- return super.verifyDrawable(who) || (who == mForeground);
- }
-
- @Override
- public void jumpDrawablesToCurrentState() {
- super.jumpDrawablesToCurrentState();
- if (mForeground != null) mForeground.jumpToCurrentState();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
- if (mForeground != null && mForeground.isStateful()) {
- mForeground.setState(getDrawableState());
- }
- }
-
- @Override
- public void drawableHotspotChanged(float x, float y) {
- super.drawableHotspotChanged(x, y);
-
- if (mForeground != null) {
- mForeground.setHotspot(x, y);
- }
- }
-
/**
* Returns a set of layout parameters with a width of
* {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT},
@@ -258,161 +150,23 @@ public class FrameLayout extends ViewGroup {
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
- /**
- * Supply a Drawable that is to be rendered on top of all of the child
- * views in the frame layout. Any padding in the Drawable will be taken
- * into account by ensuring that the children are inset to be placed
- * inside of the padding area.
- *
- * @param d The Drawable to be drawn on top of the children.
- *
- * @attr ref android.R.styleable#FrameLayout_foreground
- */
- public void setForeground(Drawable d) {
- if (mForeground != d) {
- if (mForeground != null) {
- mForeground.setCallback(null);
- unscheduleDrawable(mForeground);
- }
-
- mForeground = d;
- mForegroundPaddingLeft = 0;
- mForegroundPaddingTop = 0;
- mForegroundPaddingRight = 0;
- mForegroundPaddingBottom = 0;
-
- if (d != null) {
- setWillNotDraw(false);
- d.setCallback(this);
- d.setLayoutDirection(getLayoutDirection());
- if (d.isStateful()) {
- d.setState(getDrawableState());
- }
- applyForegroundTint();
- if (mForegroundGravity == Gravity.FILL) {
- Rect padding = new Rect();
- if (d.getPadding(padding)) {
- mForegroundPaddingLeft = padding.left;
- mForegroundPaddingTop = padding.top;
- mForegroundPaddingRight = padding.right;
- mForegroundPaddingBottom = padding.bottom;
- }
- }
- } else {
- setWillNotDraw(true);
- }
- requestLayout();
- invalidate();
- }
- }
-
- /**
- * Returns the drawable used as the foreground of this FrameLayout. The
- * foreground drawable, if non-null, is always drawn on top of the children.
- *
- * @return A Drawable or null if no foreground was set.
- */
- public Drawable getForeground() {
- return mForeground;
- }
-
- /**
- * Applies a tint to the foreground drawable. Does not modify the current
- * tint mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
- * <p>
- * Subsequent calls to {@link #setForeground(Drawable)} will automatically
- * mutate the drawable and apply the specified tint and tint mode using
- * {@link Drawable#setTintList(ColorStateList)}.
- *
- * @param tint the tint to apply, may be {@code null} to clear tint
- *
- * @attr ref android.R.styleable#FrameLayout_foregroundTint
- * @see #getForegroundTintList()
- * @see Drawable#setTintList(ColorStateList)
- */
- public void setForegroundTintList(@Nullable ColorStateList tint) {
- mForegroundTintList = tint;
- mHasForegroundTint = true;
-
- applyForegroundTint();
- }
-
- /**
- * @return the tint applied to the foreground drawable
- * @attr ref android.R.styleable#FrameLayout_foregroundTint
- * @see #setForegroundTintList(ColorStateList)
- */
- @Nullable
- public ColorStateList getForegroundTintList() {
- return mForegroundTintList;
- }
-
- /**
- * Specifies the blending mode used to apply the tint specified by
- * {@link #setForegroundTintList(ColorStateList)}} to the foreground drawable.
- * The default mode is {@link PorterDuff.Mode#SRC_IN}.
- *
- * @param tintMode the blending mode used to apply the tint, may be
- * {@code null} to clear tint
- * @attr ref android.R.styleable#FrameLayout_foregroundTintMode
- * @see #getForegroundTintMode()
- * @see Drawable#setTintMode(PorterDuff.Mode)
- */
- public void setForegroundTintMode(@Nullable PorterDuff.Mode tintMode) {
- mForegroundTintMode = tintMode;
- mHasForegroundTintMode = true;
-
- applyForegroundTint();
- }
-
- /**
- * @return the blending mode used to apply the tint to the foreground
- * drawable
- * @attr ref android.R.styleable#FrameLayout_foregroundTintMode
- * @see #setForegroundTintMode(PorterDuff.Mode)
- */
- @Nullable
- public PorterDuff.Mode getForegroundTintMode() {
- return mForegroundTintMode;
- }
-
- private void applyForegroundTint() {
- if (mForeground != null && (mHasForegroundTint || mHasForegroundTintMode)) {
- mForeground = mForeground.mutate();
-
- if (mHasForegroundTint) {
- mForeground.setTintList(mForegroundTintList);
- }
-
- if (mHasForegroundTintMode) {
- mForeground.setTintMode(mForegroundTintMode);
- }
-
- // The drawable (or one of its children) may not have been
- // stateful before applying the tint, so let's try again.
- if (mForeground.isStateful()) {
- mForeground.setState(getDrawableState());
- }
- }
- }
-
int getPaddingLeftWithForeground() {
- return mForegroundInPadding ? Math.max(mPaddingLeft, mForegroundPaddingLeft) :
+ return isForegroundInsidePadding() ? Math.max(mPaddingLeft, mForegroundPaddingLeft) :
mPaddingLeft + mForegroundPaddingLeft;
}
int getPaddingRightWithForeground() {
- return mForegroundInPadding ? Math.max(mPaddingRight, mForegroundPaddingRight) :
+ return isForegroundInsidePadding() ? Math.max(mPaddingRight, mForegroundPaddingRight) :
mPaddingRight + mForegroundPaddingRight;
}
private int getPaddingTopWithForeground() {
- return mForegroundInPadding ? Math.max(mPaddingTop, mForegroundPaddingTop) :
+ return isForegroundInsidePadding() ? Math.max(mPaddingTop, mForegroundPaddingTop) :
mPaddingTop + mForegroundPaddingTop;
}
private int getPaddingBottomWithForeground() {
- return mForegroundInPadding ? Math.max(mPaddingBottom, mForegroundPaddingBottom) :
+ return isForegroundInsidePadding() ? Math.max(mPaddingBottom, mForegroundPaddingBottom) :
mPaddingBottom + mForegroundPaddingBottom;
}
@@ -527,8 +281,6 @@ public class FrameLayout extends ViewGroup {
final int parentTop = getPaddingTopWithForeground();
final int parentBottom = bottom - top - getPaddingBottomWithForeground();
- mForegroundBoundsChanged = true;
-
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
@@ -585,62 +337,6 @@ public class FrameLayout extends ViewGroup {
}
/**
- * {@inheritDoc}
- */
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- mForegroundBoundsChanged = true;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void draw(Canvas canvas) {
- super.draw(canvas);
-
- if (mForeground != null) {
- final Drawable foreground = mForeground;
-
- if (mForegroundBoundsChanged) {
- mForegroundBoundsChanged = false;
- final Rect selfBounds = mSelfBounds;
- final Rect overlayBounds = mOverlayBounds;
-
- final int w = mRight-mLeft;
- final int h = mBottom-mTop;
-
- if (mForegroundInPadding) {
- selfBounds.set(0, 0, w, h);
- } else {
- selfBounds.set(mPaddingLeft, mPaddingTop, w - mPaddingRight, h - mPaddingBottom);
- }
-
- final int layoutDirection = getLayoutDirection();
- Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
- foreground.getIntrinsicHeight(), selfBounds, overlayBounds,
- layoutDirection);
- foreground.setBounds(overlayBounds);
- }
-
- foreground.draw(canvas);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean gatherTransparentRegion(Region region) {
- boolean opaque = super.gatherTransparentRegion(region);
- if (region != null && mForeground != null) {
- applyDrawableToTransparentRegion(mForeground, region);
- }
- return opaque;
- }
-
- /**
* Sets whether to consider all children, or just those in
* the VISIBLE or INVISIBLE state, when measuring. Defaults to false.
*
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index af5a8bf..b187c1c 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -1209,13 +1209,13 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_LEFT:
- if (movePrevious()) {
+ if (moveDirection(-1)) {
playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
return true;
}
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
- if (moveNext()) {
+ if (moveDirection(1)) {
playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
return true;
}
@@ -1255,18 +1255,12 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
return super.onKeyUp(keyCode, event);
}
- boolean movePrevious() {
- if (mItemCount > 0 && mSelectedPosition > 0) {
- scrollToChild(mSelectedPosition - mFirstPosition - 1);
- return true;
- } else {
- return false;
- }
- }
+ boolean moveDirection(int direction) {
+ direction = isLayoutRtl() ? -direction : direction;
+ int targetPosition = mSelectedPosition + direction;
- boolean moveNext() {
- if (mItemCount > 0 && mSelectedPosition < mItemCount - 1) {
- scrollToChild(mSelectedPosition - mFirstPosition + 1);
+ if (mItemCount > 0 && targetPosition >= 0 && targetPosition < mItemCount) {
+ scrollToChild(targetPosition - mFirstPosition);
return true;
} else {
return false;
diff --git a/core/java/com/android/internal/logging/EventLogTags.logtags b/core/java/com/android/internal/logging/EventLogTags.logtags
new file mode 100644
index 0000000..9e178df
--- /dev/null
+++ b/core/java/com/android/internal/logging/EventLogTags.logtags
@@ -0,0 +1,7 @@
+# See system/core/logcat/event.logtags for a description of the format of this file.
+
+option java_package com.android.internal.logging;
+
+# interaction logs
+524287 sysui_view_visibility (category|1|5),(visible|1|6)
+524288 sysui_action (category|1|5),(type|1|6)
diff --git a/core/java/com/android/internal/logging/MetricsConstants.java b/core/java/com/android/internal/logging/MetricsConstants.java
new file mode 100644
index 0000000..e5cba84
--- /dev/null
+++ b/core/java/com/android/internal/logging/MetricsConstants.java
@@ -0,0 +1,153 @@
+/*
+ * 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.logging;
+
+/**
+ * Constants for mestrics logs.
+ *
+ * @hide
+ */
+public interface MetricsConstants {
+ // These constants must match those in the analytic pipeline.
+ public static final int ACCESSIBILITY = 2;
+ public static final int ACCESSIBILITY_CAPTION_PROPERTIES = 3;
+ public static final int ACCESSIBILITY_SERVICE = 4;
+ public static final int ACCESSIBILITY_TOGGLE_DALTONIZER = 5;
+ public static final int ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE = 6;
+ public static final int ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 7;
+ public static final int ACCOUNT = 8;
+ public static final int ACCOUNTS_ACCOUNT_SYNC = 9;
+ public static final int ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY = 10;
+ public static final int ACCOUNTS_MANAGE_ACCOUNTS = 11;
+ public static final int APN = 12;
+ public static final int APN_EDITOR = 13;
+ public static final int APPLICATION = 16;
+ public static final int APPLICATIONS_APP_LAUNCH = 17;
+ public static final int APPLICATIONS_APP_PERMISSION = 18;
+ public static final int APPLICATIONS_APP_STORAGE = 19;
+ public static final int APPLICATIONS_INSTALLED_APP_DETAILS = 20;
+ public static final int APPLICATIONS_PROCESS_STATS_DETAIL = 21;
+ public static final int APPLICATIONS_PROCESS_STATS_MEM_DETAIL = 22;
+ public static final int APPLICATIONS_PROCESS_STATS_UI = 23;
+ public static final int APP_OPS_DETAILS = 14;
+ public static final int APP_OPS_SUMMARY = 15;
+ public static final int BLUETOOTH = 24;
+ public static final int BLUETOOTH_DEVICE_PICKER = 25;
+ public static final int BLUETOOTH_DEVICE_PROFILES = 26;
+ public static final int CHOOSE_LOCK_GENERIC = 27;
+ public static final int CHOOSE_LOCK_PASSWORD = 28;
+ public static final int CHOOSE_LOCK_PATTERN = 29;
+ public static final int CONFIRM_LOCK_PASSWORD = 30;
+ public static final int CONFIRM_LOCK_PATTERN = 31;
+ public static final int CRYPT_KEEPER = 32;
+ public static final int CRYPT_KEEPER_CONFIRM = 33;
+ public static final int DASHBOARD_SEARCH_RESULTS = 34;
+ public static final int DASHBOARD_SUMMARY = 35;
+ public static final int DATA_USAGE = 36;
+ public static final int DATA_USAGE_SUMMARY = 37;
+ public static final int DATE_TIME = 38;
+ public static final int DEVELOPMENT = 39;
+ public static final int DEVICEINFO = 40;
+ public static final int DEVICEINFO_IMEI_INFORMATION = 41;
+ public static final int DEVICEINFO_MEMORY = 42;
+ public static final int DEVICEINFO_SIM_STATUS = 43;
+ public static final int DEVICEINFO_STATUS = 44;
+ public static final int DEVICEINFO_USB = 45;
+ public static final int DISPLAY = 46;
+ public static final int DREAM = 47;
+ public static final int ENCRYPTION = 48;
+ public static final int FINGERPRINT = 49;
+ public static final int FINGERPRINT_ENROLL = 50;
+ public static final int FUELGAUGE_BATTERY_HISTORY_DETAIL = 51;
+ public static final int FUELGAUGE_BATTERY_SAVER = 52;
+ public static final int FUELGAUGE_POWER_USAGE_DETAIL = 53;
+ public static final int FUELGAUGE_POWER_USAGE_SUMMARY = 54;
+ public static final int HOME = 55;
+ public static final int ICC_LOCK = 56;
+ public static final int INPUTMETHOD_KEYBOARD = 58;
+ public static final int INPUTMETHOD_LANGUAGE = 57;
+ public static final int INPUTMETHOD_SPELL_CHECKERS = 59;
+ public static final int INPUTMETHOD_SUBTYPE_ENABLER = 60;
+ public static final int INPUTMETHOD_USER_DICTIONARY = 61;
+ public static final int INPUTMETHOD_USER_DICTIONARY_ADD_WORD = 62;
+ public static final int LOCATION = 63;
+ public static final int LOCATION_MODE = 64;
+ public static final int MAIN_SETTINGS = 1;
+ public static final int MANAGE_APPLICATIONS = 65;
+ public static final int MASTER_CLEAR = 66;
+ public static final int MASTER_CLEAR_CONFIRM = 67;
+ public static final int NET_DATA_USAGE_METERED = 68;
+ public static final int NFC_BEAM = 69;
+ public static final int NFC_PAYMENT = 70;
+ public static final int NOTIFICATION = 71;
+ public static final int NOTIFICATION_APP_NOTIFICATION = 72;
+ public static final int NOTIFICATION_OTHER_SOUND = 73;
+ public static final int NOTIFICATION_REDACTION = 74;
+ public static final int NOTIFICATION_STATION = 75;
+ public static final int NOTIFICATION_ZEN_MODE = 76;
+ public static final int OWNER_INFO = 77;
+ public static final int PRINT_JOB_SETTINGS = 78;
+ public static final int PRINT_SERVICE_SETTINGS = 79;
+ public static final int PRINT_SETTINGS = 80;
+ public static final int PRIVACY = 81;
+ public static final int PROXY_SELECTOR = 82;
+ public static final int QS_AIRPLANEMODE = 112;
+ public static final int QS_BLUETOOTH = 113;
+ public static final int QS_CAST = 114;
+ public static final int QS_CELLULAR = 115;
+ public static final int QS_COLORINVERSION = 116;
+ public static final int QS_DATAUSAGEDETAIL = 117;
+ public static final int QS_DND = 118;
+ public static final int QS_FLASHLIGHT = 119;
+ public static final int QS_HOTSPOT = 120;
+ public static final int QS_INTENT = 121;
+ public static final int QS_LOCATION = 122;
+ public static final int QS_PANEL = 111;
+ public static final int QS_ROTATIONLOCK = 123;
+ public static final int QS_USERDETAIL = 125;
+ public static final int QS_USERDETAILITE = 124;
+ public static final int QS_WIFI = 126;
+ public static final int RESET_NETWORK = 83;
+ public static final int RESET_NETWORK_CONFIRM = 84;
+ public static final int RUNNING_SERVICE_DETAILS = 85;
+ public static final int SCREEN_PINNING = 86;
+ public static final int SECURITY = 87;
+ public static final int SIM = 88;
+ public static final int TESTING = 89;
+ public static final int TETHER = 90;
+ public static final int TRUSTED_CREDENTIALS = 92;
+ public static final int TRUST_AGENT = 91;
+ public static final int TTS_ENGINE_SETTINGS = 93;
+ public static final int TTS_TEXT_TO_SPEECH = 94;
+ public static final int TYPE_UNKNOWN = 0;
+ public static final int USAGE_ACCESS = 95;
+ public static final int USER = 96;
+ public static final int USERS_APP_RESTRICTIONS = 97;
+ public static final int USER_DETAILS = 98;
+ public static final int VIEW_UNKNOWN = 0;
+ public static final int VOICE_INPUT = 99;
+ public static final int VPN = 100;
+ public static final int WALLPAPER_TYPE = 101;
+ public static final int WFD_WIFI_DISPLAY = 102;
+ public static final int WIFI = 103;
+ public static final int WIFI_ADVANCED = 104;
+ public static final int WIFI_APITEST = 107;
+ public static final int WIFI_CALLING = 105;
+ public static final int WIFI_INFO = 108;
+ public static final int WIFI_P2P = 109;
+ public static final int WIFI_SAVED_ACCESS_POINTS = 106;
+ public static final int WIRELESS = 110;
+}
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
new file mode 100644
index 0000000..2de7394
--- /dev/null
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -0,0 +1,47 @@
+/*
+ * 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.logging;
+
+
+import android.content.Context;
+import android.os.Build;
+
+/**
+ * Log all the things.
+ *
+ * @hide
+ */
+public class MetricsLogger implements MetricsConstants {
+ // These constants are temporary, they should migrate to MetricsConstants.
+ public static final int APPLICATIONS_ADVANCED = 132;
+ public static final int LOCATION_SCANNING = 133;
+ public static final int MANAGE_APPLICATIONS_ALL = 134;
+ public static final int MANAGE_APPLICATIONS_NOTIFICATIONS = 135;
+
+ public static void visible(Context context, int category) throws IllegalArgumentException {
+ if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
+ throw new IllegalArgumentException("Must define metric category");
+ }
+ EventLogTags.writeSysuiViewVisibility(category, 100);
+ }
+
+ public static void hidden(Context context, int category) {
+ if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
+ throw new IllegalArgumentException("Must define metric category");
+ }
+ EventLogTags.writeSysuiViewVisibility(category, 0);
+ }
+}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index eaa0dc7..93dc995 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -16,18 +16,14 @@
package com.android.internal.os;
-import static android.net.NetworkStats.UID_ALL;
-import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
-
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.bluetooth.BluetoothActivityEnergyInfo;
-import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkStats;
-import android.net.wifi.IWifiManager;
import android.net.wifi.WifiActivityEnergyInfo;
import android.net.wifi.WifiManager;
import android.os.BadParcelableException;
@@ -42,8 +38,6 @@ import android.os.Parcel;
import android.os.ParcelFormatException;
import android.os.Parcelable;
import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.WorkSource;
@@ -65,13 +59,14 @@ import android.util.TimeUtils;
import android.util.Xml;
import android.view.Display;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.net.NetworkStatsFactory;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.XmlUtils;
+import com.android.server.NetworkManagementSocketTagger;
+import libcore.util.EmptyArray;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -109,7 +104,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 121 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 122 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -132,6 +127,9 @@ public final class BatteryStatsImpl extends BatteryStats {
static final int MSG_REPORT_POWER_CHANGE = 2;
static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
+ private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
+ private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
+
public interface BatteryCallback {
public void batteryNeedsCpuUpdate();
public void batteryPowerChanged(boolean onBattery);
@@ -160,7 +158,12 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ public interface ExternalStatsSync {
+ void scheduleSync();
+ }
+
public final MyHandler mHandler;
+ private final ExternalStatsSync mExternalSync;
private BatteryCallback mCallback;
@@ -330,7 +333,7 @@ public final class BatteryStatsImpl extends BatteryStats {
int mPhoneSignalStrengthBin = -1;
int mPhoneSignalStrengthBinRaw = -1;
- final StopwatchTimer[] mPhoneSignalStrengthsTimer =
+ final StopwatchTimer[] mPhoneSignalStrengthsTimer =
new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
StopwatchTimer mPhoneSignalScanningTimer;
@@ -445,18 +448,17 @@ public final class BatteryStatsImpl extends BatteryStats {
private int mLoadedNumConnectivityChange;
private int mUnpluggedNumConnectivityChange;
+ private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
+
/*
* Holds a SamplingTimer associated with each kernel wakelock name being tracked.
*/
- private final HashMap<String, SamplingTimer> mKernelWakelockStats =
- new HashMap<String, SamplingTimer>();
+ private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>();
public Map<String, ? extends Timer> getKernelWakelockStats() {
return mKernelWakelockStats;
}
- private static int sKernelWakelockUpdateVersion = 0;
-
String mLastWakeupReason = null;
long mLastWakeupUptimeMs = 0;
private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>();
@@ -465,56 +467,12 @@ public final class BatteryStatsImpl extends BatteryStats {
return mWakeupReasonStats;
}
- private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
- Process.PROC_TAB_TERM|Process.PROC_OUT_STRING| // 0: name
- Process.PROC_QUOTES,
- Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
- Process.PROC_TAB_TERM,
- Process.PROC_TAB_TERM,
- Process.PROC_TAB_TERM,
- Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
- };
-
- private static final int[] WAKEUP_SOURCES_FORMAT = new int[] {
- Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
- Process.PROC_TAB_TERM|Process.PROC_COMBINE|
- Process.PROC_OUT_LONG, // 1: count
- Process.PROC_TAB_TERM|Process.PROC_COMBINE,
- Process.PROC_TAB_TERM|Process.PROC_COMBINE,
- Process.PROC_TAB_TERM|Process.PROC_COMBINE,
- Process.PROC_TAB_TERM|Process.PROC_COMBINE,
- Process.PROC_TAB_TERM|Process.PROC_COMBINE
- |Process.PROC_OUT_LONG, // 6: totalTime
- };
-
- private final String[] mProcWakelocksName = new String[3];
- private final long[] mProcWakelocksData = new long[3];
-
- /*
- * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added
- * to mKernelWakelockStats.
- */
- private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
- new HashMap<String, KernelWakelockStats>();
-
- private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
- private NetworkStats mCurMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
- private NetworkStats mLastMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
- private NetworkStats mCurWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
- private NetworkStats mLastWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
- private NetworkStats mTmpNetworkStats;
- private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
-
- @GuardedBy("this")
- private String[] mMobileIfaces = new String[0];
- @GuardedBy("this")
- private String[] mWifiIfaces = new String[0];
-
public BatteryStatsImpl() {
mFile = null;
mCheckinFile = null;
mDailyFile = null;
mHandler = null;
+ mExternalSync = null;
clearHistoryLocked();
}
@@ -524,7 +482,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
static class TimeBase {
- private final ArrayList<TimeBaseObs> mObservers = new ArrayList<TimeBaseObs>();
+ private final ArrayList<TimeBaseObs> mObservers = new ArrayList<>();
private long mUptime;
private long mRealtime;
@@ -1779,147 +1737,6 @@ public final class BatteryStatsImpl extends BatteryStats {
return timer;
}
- private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
-
- FileInputStream is;
- byte[] buffer = new byte[32*1024];
- int len;
- boolean wakeup_sources;
-
- try {
- try {
- is = new FileInputStream("/d/wakeup_sources");
- wakeup_sources = true;
- } catch (java.io.FileNotFoundException e) {
- try {
- is = new FileInputStream("/proc/wakelocks");
- wakeup_sources = false;
- } catch (java.io.FileNotFoundException e2) {
- return null;
- }
- }
-
- len = is.read(buffer);
- is.close();
- } catch (java.io.IOException e) {
- return null;
- }
-
- if (len > 0) {
- if (len >= buffer.length) {
- Slog.wtf(TAG, "Kernel wake locks exceeded buffer size " + buffer.length);
- }
- int i;
- for (i=0; i<len; i++) {
- if (buffer[i] == '\0') {
- len = i;
- break;
- }
- }
- }
-
- return parseProcWakelocks(buffer, len, wakeup_sources);
- }
-
- private final Map<String, KernelWakelockStats> parseProcWakelocks(
- byte[] wlBuffer, int len, boolean wakeup_sources) {
- String name;
- int count;
- long totalTime;
- int startIndex;
- int endIndex;
- int numUpdatedWlNames = 0;
-
- // Advance past the first line.
- int i;
- for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
- startIndex = endIndex = i + 1;
-
- synchronized(this) {
- Map<String, KernelWakelockStats> m = mProcWakelockFileStats;
-
- sKernelWakelockUpdateVersion++;
- while (endIndex < len) {
- for (endIndex=startIndex;
- endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
- endIndex++);
- endIndex++; // endIndex is an exclusive upper bound.
- // Don't go over the end of the buffer, Process.parseProcLine might
- // write to wlBuffer[endIndex]
- if (endIndex >= (len - 1) ) {
- return m;
- }
-
- String[] nameStringArray = mProcWakelocksName;
- long[] wlData = mProcWakelocksData;
- // Stomp out any bad characters since this is from a circular buffer
- // A corruption is seen sometimes that results in the vm crashing
- // This should prevent crashes and the line will probably fail to parse
- for (int j = startIndex; j < endIndex; j++) {
- if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
- }
- boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
- wakeup_sources ? WAKEUP_SOURCES_FORMAT :
- PROC_WAKELOCKS_FORMAT,
- nameStringArray, wlData, null);
-
- name = nameStringArray[0];
- count = (int) wlData[1];
-
- if (wakeup_sources) {
- // convert milliseconds to microseconds
- totalTime = wlData[2] * 1000;
- } else {
- // convert nanoseconds to microseconds with rounding.
- totalTime = (wlData[2] + 500) / 1000;
- }
-
- if (parsed && name.length() > 0) {
- if (!m.containsKey(name)) {
- m.put(name, new KernelWakelockStats(count, totalTime,
- sKernelWakelockUpdateVersion));
- numUpdatedWlNames++;
- } else {
- KernelWakelockStats kwlStats = m.get(name);
- if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
- kwlStats.mCount += count;
- kwlStats.mTotalTime += totalTime;
- } else {
- kwlStats.mCount = count;
- kwlStats.mTotalTime = totalTime;
- kwlStats.mVersion = sKernelWakelockUpdateVersion;
- numUpdatedWlNames++;
- }
- }
- }
- startIndex = endIndex;
- }
-
- if (m.size() != numUpdatedWlNames) {
- // Don't report old data.
- Iterator<KernelWakelockStats> itr = m.values().iterator();
- while (itr.hasNext()) {
- if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
- itr.remove();
- }
- }
- }
- return m;
- }
- }
-
- private class KernelWakelockStats {
- public int mCount;
- public long mTotalTime;
- public int mVersion;
-
- KernelWakelockStats(int count, long totalTime, int version) {
- mCount = count;
- mTotalTime = totalTime;
- mVersion = version;
- }
- }
-
/*
* Get the KernelWakelockTimer associated with name, and create a new one if one
* doesn't already exist.
@@ -3391,7 +3208,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
} else {
mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
- updateNetworkActivityLocked(NET_UPDATE_MOBILE, realElapsedRealtimeMs);
+ updateMobileRadioStateLocked(realElapsedRealtimeMs);
mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
}
}
@@ -3729,6 +3546,7 @@ public final class BatteryStatsImpl extends BatteryStats {
addHistoryRecordLocked(elapsedRealtime, uptime);
mWifiOn = true;
mWifiOnTimer.startRunningLocked(elapsedRealtime);
+ scheduleSyncExternalStatsLocked();
}
}
@@ -3742,6 +3560,7 @@ public final class BatteryStatsImpl extends BatteryStats {
addHistoryRecordLocked(elapsedRealtime, uptime);
mWifiOn = false;
mWifiOnTimer.stopRunningLocked(elapsedRealtime);
+ scheduleSyncExternalStatsLocked();
}
}
@@ -3904,6 +3723,7 @@ public final class BatteryStatsImpl extends BatteryStats {
int uid = mapUid(ws.get(i));
getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
}
+ scheduleSyncExternalStatsLocked();
} else {
Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
}
@@ -3942,6 +3762,7 @@ public final class BatteryStatsImpl extends BatteryStats {
int uid = mapUid(ws.get(i));
getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
}
+ scheduleSyncExternalStatsLocked();
} else {
Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
}
@@ -3956,6 +3777,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mWifiState = wifiState;
mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
+ scheduleSyncExternalStatsLocked();
}
}
@@ -4027,6 +3849,7 @@ public final class BatteryStatsImpl extends BatteryStats {
addHistoryRecordLocked(elapsedRealtime, uptime);
mBluetoothOn = true;
mBluetoothOnTimer.startRunningLocked(elapsedRealtime);
+ scheduleSyncExternalStatsLocked();
}
}
@@ -4040,6 +3863,7 @@ public final class BatteryStatsImpl extends BatteryStats {
addHistoryRecordLocked(elapsedRealtime, uptime);
mBluetoothOn = false;
mBluetoothOnTimer.stopRunningLocked(elapsedRealtime);
+ scheduleSyncExternalStatsLocked();
}
}
@@ -4066,6 +3890,7 @@ public final class BatteryStatsImpl extends BatteryStats {
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
+ Integer.toHexString(mHistoryCur.states));
addHistoryRecordLocked(elapsedRealtime, uptime);
+ scheduleSyncExternalStatsLocked();
}
mWifiFullLockNesting++;
getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
@@ -4081,6 +3906,7 @@ public final class BatteryStatsImpl extends BatteryStats {
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
+ Integer.toHexString(mHistoryCur.states));
addHistoryRecordLocked(elapsedRealtime, uptime);
+ scheduleSyncExternalStatsLocked();
}
getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
}
@@ -4138,6 +3964,7 @@ public final class BatteryStatsImpl extends BatteryStats {
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
+ Integer.toHexString(mHistoryCur.states));
addHistoryRecordLocked(elapsedRealtime, uptime);
+ scheduleSyncExternalStatsLocked();
}
mWifiMulticastNesting++;
getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
@@ -4153,6 +3980,7 @@ public final class BatteryStatsImpl extends BatteryStats {
if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
+ Integer.toHexString(mHistoryCur.states));
addHistoryRecordLocked(elapsedRealtime, uptime);
+ scheduleSyncExternalStatsLocked();
}
getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
}
@@ -4260,7 +4088,8 @@ public final class BatteryStatsImpl extends BatteryStats {
// During device boot, qtaguid isn't enabled until after the inital
// loading of battery stats. Now that they're enabled, take our initial
// snapshot for future delta calculation.
- updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
+ updateMobileRadioStateLocked(SystemClock.elapsedRealtime());
+ updateWifiStateLocked(null);
}
@Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
@@ -4607,17 +4436,17 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@Override
- public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
+ public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
return mWakelockStats.getMap();
}
@Override
- public Map<String, ? extends BatteryStats.Timer> getSyncStats() {
+ public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() {
return mSyncStats.getMap();
}
@Override
- public Map<String, ? extends BatteryStats.Timer> getJobStats() {
+ public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() {
return mJobStats.getMap();
}
@@ -4627,12 +4456,12 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@Override
- public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
+ public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
return mProcessStats;
}
@Override
- public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
+ public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
return mPackageStats;
}
@@ -5950,7 +5779,7 @@ public final class BatteryStatsImpl extends BatteryStats {
Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
return false;
}
-
+
mExcessivePower = new ArrayList<ExcessivePower>();
for (int i=0; i<N; i++) {
ExcessivePower ew = new ExcessivePower();
@@ -6153,40 +5982,20 @@ public final class BatteryStatsImpl extends BatteryStats {
*/
public final class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
/**
- * Number of times this package has done something that could wake up the
- * device from sleep.
- */
- int mWakeups;
-
- /**
- * Number of things that could wake up the device loaded from a
- * previous save.
- */
- int mLoadedWakeups;
-
- /**
- * Number of things that could wake up the device as of the
- * last run.
- */
- int mLastWakeups;
-
- /**
- * Number of things that could wake up the device as of the
- * last run.
+ * Number of times wakeup alarms have occurred for this app.
*/
- int mUnpluggedWakeups;
+ ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>();
/**
* The statics we have collected for this package's services.
*/
- final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
+ final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>();
Pkg() {
mOnBatteryScreenOffTimeBase.add(this);
}
public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
- mUnpluggedWakeups = mWakeups;
}
public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
@@ -6197,10 +6006,12 @@ public final class BatteryStatsImpl extends BatteryStats {
}
void readFromParcelLocked(Parcel in) {
- mWakeups = in.readInt();
- mLoadedWakeups = in.readInt();
- mLastWakeups = 0;
- mUnpluggedWakeups = in.readInt();
+ int numWA = in.readInt();
+ mWakeupAlarms.clear();
+ for (int i=0; i<numWA; i++) {
+ String tag = in.readString();
+ mWakeupAlarms.put(tag, new Counter(mOnBatteryTimeBase, in));
+ }
int numServs = in.readInt();
mServiceStats.clear();
@@ -6214,34 +6025,39 @@ public final class BatteryStatsImpl extends BatteryStats {
}
void writeToParcelLocked(Parcel out) {
- out.writeInt(mWakeups);
- out.writeInt(mLoadedWakeups);
- out.writeInt(mUnpluggedWakeups);
-
- out.writeInt(mServiceStats.size());
- for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
- out.writeString(servEntry.getKey());
- Uid.Pkg.Serv serv = servEntry.getValue();
-
+ int numWA = mWakeupAlarms.size();
+ out.writeInt(numWA);
+ for (int i=0; i<numWA; i++) {
+ out.writeString(mWakeupAlarms.keyAt(i));
+ mWakeupAlarms.valueAt(i).writeToParcel(out);
+ }
+
+ final int NS = mServiceStats.size();
+ out.writeInt(NS);
+ for (int i=0; i<NS; i++) {
+ out.writeString(mServiceStats.keyAt(i));
+ Uid.Pkg.Serv serv = mServiceStats.valueAt(i);
serv.writeToParcelLocked(out);
}
}
@Override
- public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
- return mServiceStats;
+ public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() {
+ return mWakeupAlarms;
}
- @Override
- public int getWakeups(int which) {
- int val = mWakeups;
- if (which == STATS_CURRENT) {
- val -= mLoadedWakeups;
- } else if (which == STATS_SINCE_UNPLUGGED) {
- val -= mUnpluggedWakeups;
+ public void noteWakeupAlarmLocked(String tag) {
+ Counter c = mWakeupAlarms.get(tag);
+ if (c == null) {
+ c = new Counter(mOnBatteryTimeBase);
+ mWakeupAlarms.put(tag, c);
}
+ c.stepAtomic();
+ }
- return val;
+ @Override
+ public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
+ return mServiceStats;
}
/**
@@ -6483,14 +6299,6 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- public BatteryStatsImpl getBatteryStats() {
- return BatteryStatsImpl.this;
- }
-
- public void incWakeupsLocked() {
- mWakeups++;
- }
-
final Serv newServiceStatsLocked() {
return new Serv();
}
@@ -6749,7 +6557,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- public BatteryStatsImpl(File systemDir, Handler handler) {
+ public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) {
if (systemDir != null) {
mFile = new JournaledFile(new File(systemDir, "batterystats.bin"),
new File(systemDir, "batterystats.bin.tmp"));
@@ -6758,6 +6566,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
+ mExternalSync = externalSync;
mHandler = new MyHandler(handler.getLooper());
mStartCount++;
mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase);
@@ -6830,6 +6639,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mCheckinFile = null;
mDailyFile = null;
mHandler = null;
+ mExternalSync = null;
clearHistoryLocked();
readFromParcel(p);
}
@@ -7501,21 +7311,233 @@ public final class BatteryStatsImpl extends BatteryStats {
mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
}
}
-
+
public void pullPendingStateUpdatesLocked() {
- updateKernelWakelocksLocked();
- updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
- // TODO(adamlesinski): enable when bluedroid stops deadlocking. b/19248786
- // updateBluetoothControllerActivityLocked();
- // TODO(adamlesinski): disabled to avoid deadlock. Need to change how external
- // data is pulled/accessed from BatteryStats. b/19729960
- // updateWifiControllerActivityLocked();
if (mOnBatteryInternal) {
final boolean screenOn = mScreenState == Display.STATE_ON;
updateDischargeScreenLevelsLocked(screenOn, screenOn);
}
}
+ private String[] mMobileIfaces = EmptyArray.STRING;
+ private String[] mWifiIfaces = EmptyArray.STRING;
+
+ private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
+
+ private static final int NETWORK_STATS_LAST = 0;
+ private static final int NETWORK_STATS_NEXT = 1;
+ private static final int NETWORK_STATS_DELTA = 2;
+
+ private final NetworkStats[] mMobileNetworkStats = new NetworkStats[] {
+ new NetworkStats(SystemClock.elapsedRealtime(), 50),
+ new NetworkStats(SystemClock.elapsedRealtime(), 50),
+ new NetworkStats(SystemClock.elapsedRealtime(), 50)
+ };
+
+ private final NetworkStats[] mWifiNetworkStats = new NetworkStats[] {
+ new NetworkStats(SystemClock.elapsedRealtime(), 50),
+ new NetworkStats(SystemClock.elapsedRealtime(), 50),
+ new NetworkStats(SystemClock.elapsedRealtime(), 50)
+ };
+
+ /**
+ * Retrieves the delta of network stats for the given network ifaces. Uses networkStatsBuffer
+ * as a buffer of NetworkStats objects to cycle through when computing deltas.
+ */
+ private NetworkStats getNetworkStatsDeltaLocked(String[] ifaces,
+ NetworkStats[] networkStatsBuffer)
+ throws IOException {
+ if (!SystemProperties.getBoolean(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED,
+ false)) {
+ return null;
+ }
+
+ final NetworkStats stats = mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL,
+ ifaces, NetworkStats.TAG_NONE, networkStatsBuffer[NETWORK_STATS_NEXT]);
+ networkStatsBuffer[NETWORK_STATS_DELTA] = NetworkStats.subtract(stats,
+ networkStatsBuffer[NETWORK_STATS_LAST], null, null,
+ networkStatsBuffer[NETWORK_STATS_DELTA]);
+ networkStatsBuffer[NETWORK_STATS_NEXT] = networkStatsBuffer[NETWORK_STATS_LAST];
+ networkStatsBuffer[NETWORK_STATS_LAST] = stats;
+ return networkStatsBuffer[NETWORK_STATS_DELTA];
+ }
+
+ /**
+ * Distribute WiFi energy info and network traffic to apps.
+ * @param info The energy information from the WiFi controller.
+ */
+ public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) {
+ final NetworkStats delta;
+ try {
+ delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats);
+ } catch (IOException e) {
+ Slog.wtf(TAG, "Failed to get wifi network stats", e);
+ return;
+ }
+
+ if (!mOnBatteryInternal) {
+ return;
+ }
+
+ if (delta != null) {
+ final int size = delta.size();
+ for (int i = 0; i < size; i++) {
+ final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
+
+ if (DEBUG) {
+ Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
+ + " tx=" + entry.txBytes);
+ }
+
+ if (entry.rxBytes == 0 || entry.txBytes == 0) {
+ continue;
+ }
+
+ final Uid u = getUidStatsLocked(mapUid(entry.uid));
+ u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
+ entry.rxPackets);
+ u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
+ entry.txPackets);
+
+ mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+ entry.rxBytes);
+ mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+ entry.txBytes);
+ mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+ entry.rxPackets);
+ mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+ entry.txPackets);
+ }
+ }
+
+ if (info != null) {
+ // Update WiFi controller stats.
+ mWifiActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
+ info.getControllerRxTimeMillis());
+ mWifiActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
+ info.getControllerTxTimeMillis());
+ mWifiActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
+ info.getControllerIdleTimeMillis());
+ mWifiActivityCounters[CONTROLLER_ENERGY].addCountLocked(
+ info.getControllerEnergyUsed());
+ }
+ }
+
+ /**
+ * Distribute Cell radio energy info and network traffic to apps.
+ */
+ public void updateMobileRadioStateLocked(long elapsedRealtimeMs) {
+ final NetworkStats delta;
+
+ try {
+ delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats);
+ } catch (IOException e) {
+ Slog.wtf(TAG, "Failed to get mobile network stats", e);
+ return;
+ }
+
+ if (delta == null || !mOnBatteryInternal) {
+ return;
+ }
+
+ long radioTime = mMobileRadioActivePerAppTimer.checkpointRunningLocked(elapsedRealtimeMs);
+ long totalPackets = delta.getTotalPackets();
+
+ final int size = delta.size();
+ for (int i = 0; i < size; i++) {
+ final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
+
+ if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
+
+ final Uid u = getUidStatsLocked(mapUid(entry.uid));
+ u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
+ entry.rxPackets);
+ u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
+ entry.txPackets);
+
+ if (radioTime > 0) {
+ // Distribute total radio active time in to this app.
+ long appPackets = entry.rxPackets + entry.txPackets;
+ long appRadioTime = (radioTime*appPackets)/totalPackets;
+ u.noteMobileRadioActiveTimeLocked(appRadioTime);
+ // Remove this app from the totals, so that we don't lose any time
+ // due to rounding.
+ radioTime -= appRadioTime;
+ totalPackets -= appPackets;
+ }
+
+ mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
+ entry.rxBytes);
+ mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
+ entry.txBytes);
+ mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
+ entry.rxPackets);
+ mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
+ entry.txPackets);
+ }
+
+ if (radioTime > 0) {
+ // Whoops, there is some radio time we can't blame on an app!
+ mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
+ mMobileRadioActiveUnknownCount.addCountLocked(1);
+ }
+ }
+
+ /**
+ * Distribute Bluetooth energy info and network traffic to apps.
+ * @param info The energy information from the bluetooth controller.
+ */
+ public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
+ if (info != null && mOnBatteryInternal) {
+ mBluetoothActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
+ info.getControllerRxTimeMillis());
+ mBluetoothActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
+ info.getControllerTxTimeMillis());
+ mBluetoothActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
+ info.getControllerIdleTimeMillis());
+ mBluetoothActivityCounters[CONTROLLER_ENERGY].addCountLocked(
+ info.getControllerEnergyUsed());
+ }
+ }
+
+ /**
+ * Read and distribute kernel wake lock use across apps.
+ */
+ public void updateKernelWakelocksLocked() {
+ final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(
+ mTmpWakelockStats);
+ if (wakelockStats == null) {
+ // Not crashing might make board bringup easier.
+ Slog.w(TAG, "Couldn't get kernel wake lock stats");
+ return;
+ }
+
+ for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
+ String name = ent.getKey();
+ KernelWakelockStats.Entry kws = ent.getValue();
+
+ SamplingTimer kwlt = mKernelWakelockStats.get(name);
+ if (kwlt == null) {
+ kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase,
+ true /* track reported val */);
+ mKernelWakelockStats.put(name, kwlt);
+ }
+ kwlt.updateCurrentReportedCount(kws.mCount);
+ kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
+ kwlt.setUpdateVersion(kws.mVersion);
+ }
+
+ if (wakelockStats.size() != mKernelWakelockStats.size()) {
+ // Set timers to stale if they didn't appear in /proc/wakelocks this time.
+ for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
+ SamplingTimer st = ent.getValue();
+ if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) {
+ st.setStale();
+ }
+ }
+ }
+ }
+
void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery,
final int oldStatus, final int level) {
boolean doWrite = false;
@@ -7669,340 +7691,132 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ private void scheduleSyncExternalStatsLocked() {
+ if (mExternalSync != null) {
+ mExternalSync.scheduleSync();
+ }
+ }
+
// This should probably be exposed in the API, though it's not critical
- private static final int BATTERY_PLUGGED_NONE = 0;
+ public static final int BATTERY_PLUGGED_NONE = 0;
- public void setBatteryState(int status, int health, int plugType, int level,
+ public void setBatteryStateLocked(int status, int health, int plugType, int level,
int temp, int volt) {
- synchronized(this) {
- final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
- final long uptime = SystemClock.uptimeMillis();
- final long elapsedRealtime = SystemClock.elapsedRealtime();
- if (!mHaveBatteryLevel) {
- mHaveBatteryLevel = true;
- // We start out assuming that the device is plugged in (not
- // on battery). If our first report is now that we are indeed
- // plugged in, then twiddle our state to correctly reflect that
- // since we won't be going through the full setOnBattery().
- if (onBattery == mOnBattery) {
- if (onBattery) {
- mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
- } else {
- mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
- }
- }
- mHistoryCur.batteryStatus = (byte)status;
- mHistoryCur.batteryLevel = (byte)level;
- mMaxChargeStepLevel = mMinDischargeStepLevel =
- mLastChargeStepLevel = mLastDischargeStepLevel = level;
- } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
- recordDailyStatsIfNeededLocked(level >= 100 && onBattery);
- }
- int oldStatus = mHistoryCur.batteryStatus;
- if (onBattery) {
- mDischargeCurrentLevel = level;
- if (!mRecordingHistory) {
- mRecordingHistory = true;
- startRecordingHistory(elapsedRealtime, uptime, true);
- }
- } else if (level < 96) {
- if (!mRecordingHistory) {
- mRecordingHistory = true;
- startRecordingHistory(elapsedRealtime, uptime, true);
- }
- }
- mCurrentBatteryLevel = level;
- if (mDischargePlugLevel < 0) {
- mDischargePlugLevel = level;
- }
- if (onBattery != mOnBattery) {
- mHistoryCur.batteryLevel = (byte)level;
- mHistoryCur.batteryStatus = (byte)status;
- mHistoryCur.batteryHealth = (byte)health;
- mHistoryCur.batteryPlugType = (byte)plugType;
- mHistoryCur.batteryTemperature = (short)temp;
- mHistoryCur.batteryVoltage = (char)volt;
- setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
- } else {
- boolean changed = false;
- if (mHistoryCur.batteryLevel != level) {
- mHistoryCur.batteryLevel = (byte)level;
- changed = true;
- }
- if (mHistoryCur.batteryStatus != status) {
- mHistoryCur.batteryStatus = (byte)status;
- changed = true;
- }
- if (mHistoryCur.batteryHealth != health) {
- mHistoryCur.batteryHealth = (byte)health;
- changed = true;
- }
- if (mHistoryCur.batteryPlugType != plugType) {
- mHistoryCur.batteryPlugType = (byte)plugType;
- changed = true;
- }
- if (temp >= (mHistoryCur.batteryTemperature+10)
- || temp <= (mHistoryCur.batteryTemperature-10)) {
- mHistoryCur.batteryTemperature = (short)temp;
- changed = true;
- }
- if (volt > (mHistoryCur.batteryVoltage+20)
- || volt < (mHistoryCur.batteryVoltage-20)) {
- mHistoryCur.batteryVoltage = (char)volt;
- changed = true;
- }
- if (changed) {
- addHistoryRecordLocked(elapsedRealtime, uptime);
- }
- long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
- | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT)
- | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT);
+ final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
+ final long uptime = SystemClock.uptimeMillis();
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ if (!mHaveBatteryLevel) {
+ mHaveBatteryLevel = true;
+ // We start out assuming that the device is plugged in (not
+ // on battery). If our first report is now that we are indeed
+ // plugged in, then twiddle our state to correctly reflect that
+ // since we won't be going through the full setOnBattery().
+ if (onBattery == mOnBattery) {
if (onBattery) {
- if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
- mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
- modeBits, elapsedRealtime);
- mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
- modeBits, elapsedRealtime);
- mLastDischargeStepLevel = level;
- mMinDischargeStepLevel = level;
- mInitStepMode = mCurStepMode;
- mModStepMode = 0;
- }
+ mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
} else {
- if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
- mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
- modeBits, elapsedRealtime);
- mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
- modeBits, elapsedRealtime);
- mLastChargeStepLevel = level;
- mMaxChargeStepLevel = level;
- mInitStepMode = mCurStepMode;
- mModStepMode = 0;
- }
+ mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
}
}
- if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
- // We don't record history while we are plugged in and fully charged.
- // The next time we are unplugged, history will be cleared.
- mRecordingHistory = DEBUG;
+ mHistoryCur.batteryStatus = (byte)status;
+ mHistoryCur.batteryLevel = (byte)level;
+ mMaxChargeStepLevel = mMinDischargeStepLevel =
+ mLastChargeStepLevel = mLastDischargeStepLevel = level;
+ } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
+ recordDailyStatsIfNeededLocked(level >= 100 && onBattery);
+ }
+ int oldStatus = mHistoryCur.batteryStatus;
+ if (onBattery) {
+ mDischargeCurrentLevel = level;
+ if (!mRecordingHistory) {
+ mRecordingHistory = true;
+ startRecordingHistory(elapsedRealtime, uptime, true);
+ }
+ } else if (level < 96) {
+ if (!mRecordingHistory) {
+ mRecordingHistory = true;
+ startRecordingHistory(elapsedRealtime, uptime, true);
}
}
- }
-
- public void updateKernelWakelocksLocked() {
- Map<String, KernelWakelockStats> m = readKernelWakelockStats();
-
- if (m == null) {
- // Not crashing might make board bringup easier.
- Slog.w(TAG, "Couldn't get kernel wake lock stats");
- return;
+ mCurrentBatteryLevel = level;
+ if (mDischargePlugLevel < 0) {
+ mDischargePlugLevel = level;
}
+ if (onBattery != mOnBattery) {
+ mHistoryCur.batteryLevel = (byte)level;
+ mHistoryCur.batteryStatus = (byte)status;
+ mHistoryCur.batteryHealth = (byte)health;
+ mHistoryCur.batteryPlugType = (byte)plugType;
+ mHistoryCur.batteryTemperature = (short)temp;
+ mHistoryCur.batteryVoltage = (char)volt;
+ setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
+ } else {
+ boolean changed = false;
+ if (mHistoryCur.batteryLevel != level) {
+ mHistoryCur.batteryLevel = (byte)level;
+ changed = true;
- for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) {
- String name = ent.getKey();
- KernelWakelockStats kws = ent.getValue();
-
- SamplingTimer kwlt = mKernelWakelockStats.get(name);
- if (kwlt == null) {
- kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase,
- true /* track reported val */);
- mKernelWakelockStats.put(name, kwlt);
+ // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record
+ // which will pull external stats.
+ scheduleSyncExternalStatsLocked();
}
- kwlt.updateCurrentReportedCount(kws.mCount);
- kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
- kwlt.setUpdateVersion(sKernelWakelockUpdateVersion);
- }
-
- if (m.size() != mKernelWakelockStats.size()) {
- // Set timers to stale if they didn't appear in /proc/wakelocks this time.
- for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
- SamplingTimer st = ent.getValue();
- if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) {
- st.setStale();
- }
+ if (mHistoryCur.batteryStatus != status) {
+ mHistoryCur.batteryStatus = (byte)status;
+ changed = true;
}
- }
- }
-
- static final int NET_UPDATE_MOBILE = 1<<0;
- static final int NET_UPDATE_WIFI = 1<<1;
- static final int NET_UPDATE_ALL = 0xffff;
-
- private void updateNetworkActivityLocked(int which, long elapsedRealtimeMs) {
- if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return;
-
- if ((which&NET_UPDATE_MOBILE) != 0 && mMobileIfaces.length > 0) {
- final NetworkStats snapshot;
- final NetworkStats last = mCurMobileSnapshot;
- try {
- snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
- mMobileIfaces, NetworkStats.TAG_NONE, mLastMobileSnapshot);
- } catch (IOException e) {
- Log.wtf(TAG, "Failed to read mobile network stats", e);
- return;
+ if (mHistoryCur.batteryHealth != health) {
+ mHistoryCur.batteryHealth = (byte)health;
+ changed = true;
}
-
- mCurMobileSnapshot = snapshot;
- mLastMobileSnapshot = last;
-
- if (mOnBatteryInternal) {
- final NetworkStats delta = NetworkStats.subtract(snapshot, last,
- null, null, mTmpNetworkStats);
- mTmpNetworkStats = delta;
-
- long radioTime = mMobileRadioActivePerAppTimer.checkpointRunningLocked(
- elapsedRealtimeMs);
- long totalPackets = delta.getTotalPackets();
-
- final int size = delta.size();
- for (int i = 0; i < size; i++) {
- final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
-
- if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
-
- final Uid u = getUidStatsLocked(mapUid(entry.uid));
- u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
- entry.rxPackets);
- u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
- entry.txPackets);
-
- if (radioTime > 0) {
- // Distribute total radio active time in to this app.
- long appPackets = entry.rxPackets + entry.txPackets;
- long appRadioTime = (radioTime*appPackets)/totalPackets;
- u.noteMobileRadioActiveTimeLocked(appRadioTime);
- // Remove this app from the totals, so that we don't lose any time
- // due to rounding.
- radioTime -= appRadioTime;
- totalPackets -= appPackets;
- }
-
- mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
- entry.rxBytes);
- mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
- entry.txBytes);
- mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
- entry.rxPackets);
- mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
- entry.txPackets);
- }
-
- if (radioTime > 0) {
- // Whoops, there is some radio time we can't blame on an app!
- mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
- mMobileRadioActiveUnknownCount.addCountLocked(1);
- }
+ if (mHistoryCur.batteryPlugType != plugType) {
+ mHistoryCur.batteryPlugType = (byte)plugType;
+ changed = true;
}
- }
-
- if ((which&NET_UPDATE_WIFI) != 0 && mWifiIfaces.length > 0) {
- final NetworkStats snapshot;
- final NetworkStats last = mCurWifiSnapshot;
- try {
- snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
- mWifiIfaces, NetworkStats.TAG_NONE, mLastWifiSnapshot);
- } catch (IOException e) {
- Log.wtf(TAG, "Failed to read wifi network stats", e);
- return;
+ if (temp >= (mHistoryCur.batteryTemperature+10)
+ || temp <= (mHistoryCur.batteryTemperature-10)) {
+ mHistoryCur.batteryTemperature = (short)temp;
+ changed = true;
}
-
- mCurWifiSnapshot = snapshot;
- mLastWifiSnapshot = last;
-
- if (mOnBatteryInternal) {
- final NetworkStats delta = NetworkStats.subtract(snapshot, last,
- null, null, mTmpNetworkStats);
- mTmpNetworkStats = delta;
-
- final int size = delta.size();
- for (int i = 0; i < size; i++) {
- final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
-
- if (DEBUG) {
- final NetworkStats.Entry cur = snapshot.getValues(i, null);
- Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
- + " tx=" + entry.txBytes + ", cur rx=" + cur.rxBytes
- + " tx=" + cur.txBytes);
- }
-
- if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
-
- final Uid u = getUidStatsLocked(mapUid(entry.uid));
- u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
- entry.rxPackets);
- u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
- entry.txPackets);
-
- mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
- entry.rxBytes);
- mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
- entry.txBytes);
- mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
- entry.rxPackets);
- mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
- entry.txPackets);
+ if (volt > (mHistoryCur.batteryVoltage+20)
+ || volt < (mHistoryCur.batteryVoltage-20)) {
+ mHistoryCur.batteryVoltage = (char)volt;
+ changed = true;
+ }
+ if (changed) {
+ addHistoryRecordLocked(elapsedRealtime, uptime);
+ }
+ long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
+ | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT)
+ | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT);
+ if (onBattery) {
+ if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
+ mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
+ modeBits, elapsedRealtime);
+ mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
+ modeBits, elapsedRealtime);
+ mLastDischargeStepLevel = level;
+ mMinDischargeStepLevel = level;
+ mInitStepMode = mCurStepMode;
+ mModStepMode = 0;
+ }
+ } else {
+ if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
+ mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
+ modeBits, elapsedRealtime);
+ mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
+ modeBits, elapsedRealtime);
+ mLastChargeStepLevel = level;
+ mMaxChargeStepLevel = level;
+ mInitStepMode = mCurStepMode;
+ mModStepMode = 0;
}
}
}
- }
-
- private void updateBluetoothControllerActivityLocked() {
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- if (adapter == null) {
- return;
- }
-
- // We read the data even if we are not on battery. Each read clears
- // the previous data, so we must always read to make sure the
- // data is for the current interval.
- BluetoothActivityEnergyInfo info = adapter.getControllerActivityEnergyInfo(
- BluetoothAdapter.ACTIVITY_ENERGY_INFO_REFRESHED);
- if (info == null || !info.isValid() || !mOnBatteryInternal) {
- // Bad info or we are not on battery.
- return;
- }
-
- mBluetoothActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
- info.getControllerRxTimeMillis());
- mBluetoothActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
- info.getControllerTxTimeMillis());
- mBluetoothActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
- info.getControllerIdleTimeMillis());
- mBluetoothActivityCounters[CONTROLLER_ENERGY].addCountLocked(
- info.getControllerEnergyUsed());
- }
-
- private void updateWifiControllerActivityLocked() {
- IWifiManager wifiManager = IWifiManager.Stub.asInterface(
- ServiceManager.getService(Context.WIFI_SERVICE));
- if (wifiManager == null) {
- return;
- }
-
- WifiActivityEnergyInfo info;
- try {
- // We read the data even if we are not on battery. Each read clears
- // the previous data, so we must always read to make sure the
- // data is for the current interval.
- info = wifiManager.reportActivityInfo();
- } catch (RemoteException e) {
- // Nothing to report, WiFi is dead.
- return;
+ if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
+ // We don't record history while we are plugged in and fully charged.
+ // The next time we are unplugged, history will be cleared.
+ mRecordingHistory = DEBUG;
}
-
- if (info == null || !info.isValid() || !mOnBatteryInternal) {
- // Bad info or we are not on battery.
- return;
- }
-
- mWifiActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
- info.getControllerRxTimeMillis());
- mWifiActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
- info.getControllerTxTimeMillis());
- mWifiActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
- info.getControllerIdleTimeMillis());
- mWifiActivityCounters[CONTROLLER_ENERGY].addCountLocked(
- info.getControllerEnergyUsed());
}
public long getAwakeTimeBattery() {
@@ -8938,7 +8752,18 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int ip = 0; ip < NP; ip++) {
String pkgName = in.readString();
Uid.Pkg p = u.getPackageStatsLocked(pkgName);
- p.mWakeups = p.mLoadedWakeups = in.readInt();
+ final int NWA = in.readInt();
+ if (NWA > 1000) {
+ Slog.w(TAG, "File corrupt: too many wakeup alarms " + NWA);
+ return;
+ }
+ p.mWakeupAlarms.clear();
+ for (int iwa=0; iwa<NWA; iwa++) {
+ String tag = in.readString();
+ Counter c = new Counter(mOnBatteryTimeBase);
+ c.readSummaryFromParcelLocked(in);
+ p.mWakeupAlarms.put(tag, c);
+ }
NS = in.readInt();
if (NS > 1000) {
Slog.w(TAG, "File corrupt: too many services " + NS);
@@ -9263,20 +9088,22 @@ public final class BatteryStatsImpl extends BatteryStats {
: u.mPackageStats.entrySet()) {
out.writeString(ent.getKey());
Uid.Pkg ps = ent.getValue();
- out.writeInt(ps.mWakeups);
+ final int NWA = ps.mWakeupAlarms.size();
+ out.writeInt(NWA);
+ for (int iwa=0; iwa<NWA; iwa++) {
+ out.writeString(ps.mWakeupAlarms.keyAt(iwa));
+ ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out);
+ }
NS = ps.mServiceStats.size();
out.writeInt(NS);
- if (NS > 0) {
- for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent
- : ps.mServiceStats.entrySet()) {
- out.writeString(sent.getKey());
- BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
- long time = ss.getStartTimeToNowLocked(
- mOnBatteryTimeBase.getUptime(NOW_SYS));
- out.writeLong(time);
- out.writeInt(ss.mStarts);
- out.writeInt(ss.mLaunches);
- }
+ for (int is=0; is<NS; is++) {
+ out.writeString(ps.mServiceStats.keyAt(is));
+ BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is);
+ long time = ss.getStartTimeToNowLocked(
+ mOnBatteryTimeBase.getUptime(NOW_SYS));
+ out.writeLong(time);
+ out.writeInt(ss.mStarts);
+ out.writeInt(ss.mLaunches);
}
}
}
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
new file mode 100644
index 0000000..768d586
--- /dev/null
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -0,0 +1,192 @@
+/*
+ * 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.os;
+
+import android.os.Process;
+import android.util.Slog;
+
+import java.io.FileInputStream;
+import java.util.Iterator;
+
+/**
+ * Reads and parses wakelock stats from the kernel (/proc/wakelocks).
+ */
+public class KernelWakelockReader {
+ private static final String TAG = "KernelWakelockReader";
+ private static int sKernelWakelockUpdateVersion = 0;
+ private static final String sWakelockFile = "/proc/wakelocks";
+ private static final String sWakeupSourceFile = "/d/wakeup_sources";
+
+ private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
+ Process.PROC_TAB_TERM|Process.PROC_OUT_STRING| // 0: name
+ Process.PROC_QUOTES,
+ Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count
+ Process.PROC_TAB_TERM,
+ Process.PROC_TAB_TERM,
+ Process.PROC_TAB_TERM,
+ Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime
+ };
+
+ private static final int[] WAKEUP_SOURCES_FORMAT = new int[] {
+ Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name
+ Process.PROC_TAB_TERM|Process.PROC_COMBINE|
+ Process.PROC_OUT_LONG, // 1: count
+ Process.PROC_TAB_TERM|Process.PROC_COMBINE,
+ Process.PROC_TAB_TERM|Process.PROC_COMBINE,
+ Process.PROC_TAB_TERM|Process.PROC_COMBINE,
+ Process.PROC_TAB_TERM|Process.PROC_COMBINE,
+ Process.PROC_TAB_TERM|Process.PROC_COMBINE
+ |Process.PROC_OUT_LONG, // 6: totalTime
+ };
+
+ private final String[] mProcWakelocksName = new String[3];
+ private final long[] mProcWakelocksData = new long[3];
+
+ /**
+ * Reads kernel wakelock stats and updates the staleStats with the new information.
+ * @param staleStats Existing object to update.
+ * @return the updated data.
+ */
+ public final KernelWakelockStats readKernelWakelockStats(KernelWakelockStats staleStats) {
+ byte[] buffer = new byte[32*1024];
+ int len;
+ boolean wakeup_sources;
+
+ try {
+ FileInputStream is;
+ try {
+ is = new FileInputStream(sWakeupSourceFile);
+ wakeup_sources = true;
+ } catch (java.io.FileNotFoundException e) {
+ try {
+ is = new FileInputStream(sWakelockFile);
+ wakeup_sources = false;
+ } catch (java.io.FileNotFoundException e2) {
+ return null;
+ }
+ }
+
+ len = is.read(buffer);
+ is.close();
+ } catch (java.io.IOException e) {
+ return null;
+ }
+
+ if (len > 0) {
+ if (len >= buffer.length) {
+ Slog.wtf(TAG, "Kernel wake locks exceeded buffer size " + buffer.length);
+ }
+ int i;
+ for (i=0; i<len; i++) {
+ if (buffer[i] == '\0') {
+ len = i;
+ break;
+ }
+ }
+ }
+ return parseProcWakelocks(buffer, len, wakeup_sources, staleStats);
+ }
+
+ /**
+ * Reads the wakelocks and updates the staleStats with the new information.
+ */
+ private KernelWakelockStats parseProcWakelocks(byte[] wlBuffer, int len, boolean wakeup_sources,
+ final KernelWakelockStats staleStats) {
+ String name;
+ int count;
+ long totalTime;
+ int startIndex;
+ int endIndex;
+ int numUpdatedWlNames = 0;
+
+ // Advance past the first line.
+ int i;
+ for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++);
+ startIndex = endIndex = i + 1;
+
+ synchronized(this) {
+ sKernelWakelockUpdateVersion++;
+ while (endIndex < len) {
+ for (endIndex=startIndex;
+ endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
+ endIndex++);
+ endIndex++; // endIndex is an exclusive upper bound.
+ // Don't go over the end of the buffer, Process.parseProcLine might
+ // write to wlBuffer[endIndex]
+ if (endIndex >= (len - 1) ) {
+ return staleStats;
+ }
+
+ String[] nameStringArray = mProcWakelocksName;
+ long[] wlData = mProcWakelocksData;
+ // Stomp out any bad characters since this is from a circular buffer
+ // A corruption is seen sometimes that results in the vm crashing
+ // This should prevent crashes and the line will probably fail to parse
+ for (int j = startIndex; j < endIndex; j++) {
+ if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?';
+ }
+ boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex,
+ wakeup_sources ? WAKEUP_SOURCES_FORMAT :
+ PROC_WAKELOCKS_FORMAT,
+ nameStringArray, wlData, null);
+
+ name = nameStringArray[0];
+ count = (int) wlData[1];
+
+ if (wakeup_sources) {
+ // convert milliseconds to microseconds
+ totalTime = wlData[2] * 1000;
+ } else {
+ // convert nanoseconds to microseconds with rounding.
+ totalTime = (wlData[2] + 500) / 1000;
+ }
+
+ if (parsed && name.length() > 0) {
+ if (!staleStats.containsKey(name)) {
+ staleStats.put(name, new KernelWakelockStats.Entry(count, totalTime,
+ sKernelWakelockUpdateVersion));
+ numUpdatedWlNames++;
+ } else {
+ KernelWakelockStats.Entry kwlStats = staleStats.get(name);
+ if (kwlStats.mVersion == sKernelWakelockUpdateVersion) {
+ kwlStats.mCount += count;
+ kwlStats.mTotalTime += totalTime;
+ } else {
+ kwlStats.mCount = count;
+ kwlStats.mTotalTime = totalTime;
+ kwlStats.mVersion = sKernelWakelockUpdateVersion;
+ numUpdatedWlNames++;
+ }
+ }
+ }
+ startIndex = endIndex;
+ }
+
+ if (staleStats.size() != numUpdatedWlNames) {
+ // Don't report old data.
+ Iterator<KernelWakelockStats.Entry> itr = staleStats.values().iterator();
+ while (itr.hasNext()) {
+ if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
+ itr.remove();
+ }
+ }
+ }
+
+ staleStats.kernelWakelockVersion = sKernelWakelockUpdateVersion;
+ return staleStats;
+ }
+ }
+}
diff --git a/core/java/com/android/internal/os/KernelWakelockStats.java b/core/java/com/android/internal/os/KernelWakelockStats.java
new file mode 100644
index 0000000..144ea00
--- /dev/null
+++ b/core/java/com/android/internal/os/KernelWakelockStats.java
@@ -0,0 +1,37 @@
+/*
+ * 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.os;
+
+import java.util.HashMap;
+
+/**
+ * Kernel wakelock stats object.
+ */
+public class KernelWakelockStats extends HashMap<String, KernelWakelockStats.Entry> {
+ public static class Entry {
+ public int mCount;
+ public long mTotalTime;
+ public int mVersion;
+
+ Entry(int count, long totalTime, int version) {
+ mCount = count;
+ mTotalTime = totalTime;
+ mVersion = version;
+ }
+ }
+
+ int kernelWakelockVersion;
+}
diff --git a/core/java/com/android/internal/util/Protocol.java b/core/java/com/android/internal/util/Protocol.java
index d9ebc25..a106f48 100644
--- a/core/java/com/android/internal/util/Protocol.java
+++ b/core/java/com/android/internal/util/Protocol.java
@@ -52,6 +52,7 @@ public class Protocol {
public static final int BASE_WIFI_RTT_SERVICE = 0x00027300;
public static final int BASE_WIFI_PASSPOINT_MANAGER = 0x00028000;
public static final int BASE_WIFI_PASSPOINT_SERVICE = 0x00028100;
+ public static final int BASE_WIFI_LOGGER = 0x00028300;
public static final int BASE_DHCP = 0x00030000;
public static final int BASE_DATA_CONNECTION = 0x00040000;
public static final int BASE_DATA_CONNECTION_AC = 0x00041000;
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
new file mode 100644
index 0000000..be9945d
--- /dev/null
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -0,0 +1,596 @@
+/*
+ * 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.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.PopupWindow;
+
+import com.android.internal.R;
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A floating toolbar for showing contextual menu items.
+ * This view shows as many menu item buttons as can fit in the horizontal toolbar and the
+ * the remaining menu items in a vertical overflow view when the overflow button is clicked.
+ * The horizontal toolbar morphs into the vertical overflow view.
+ */
+public final class FloatingToolbar {
+
+ private static final MenuItem.OnMenuItemClickListener NO_OP_MENUITEM_CLICK_LISTENER =
+ new MenuItem.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ return false;
+ }
+ };
+
+ private final Context mContext;
+ private final FloatingToolbarPopup mPopup;
+ private final ViewGroup mMenuItemButtonsContainer;
+ private final View.OnClickListener mMenuItemButtonOnClickListener =
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (v.getTag() instanceof MenuItem) {
+ mMenuItemClickListener.onMenuItemClick((MenuItem) v.getTag());
+ mPopup.dismiss();
+ }
+ }
+ };
+
+ private final Rect mContentRect = new Rect();
+ private final Point mCoordinates = new Point();
+
+ private Menu mMenu;
+ private List<CharSequence> mShowingTitles = new ArrayList<CharSequence>();
+ private MenuItem.OnMenuItemClickListener mMenuItemClickListener = NO_OP_MENUITEM_CLICK_LISTENER;
+ private View mOpenOverflowButton;
+
+ private int mSuggestedWidth;
+
+ /**
+ * Initializes a floating toolbar.
+ */
+ public FloatingToolbar(Context context, Window window) {
+ mContext = Preconditions.checkNotNull(context);
+ mPopup = new FloatingToolbarPopup(Preconditions.checkNotNull(window.getDecorView()));
+ mMenuItemButtonsContainer = createMenuButtonsContainer(context);
+ }
+
+ /**
+ * Sets the menu to be shown in this floating toolbar.
+ * NOTE: Call {@link #updateLayout()} or {@link #show()} to effect visual changes to the
+ * toolbar.
+ */
+ public FloatingToolbar setMenu(Menu menu) {
+ mMenu = Preconditions.checkNotNull(menu);
+ return this;
+ }
+
+ /**
+ * Sets the custom listener for invocation of menu items in this floating
+ * toolbar.
+ */
+ public FloatingToolbar setOnMenuItemClickListener(
+ MenuItem.OnMenuItemClickListener menuItemClickListener) {
+ if (menuItemClickListener != null) {
+ mMenuItemClickListener = menuItemClickListener;
+ } else {
+ mMenuItemClickListener = NO_OP_MENUITEM_CLICK_LISTENER;
+ }
+ return this;
+ }
+
+ /**
+ * Sets the content rectangle. This is the area of the interesting content that this toolbar
+ * should avoid obstructing.
+ * NOTE: Call {@link #updateLayout()} or {@link #show()} to effect visual changes to the
+ * toolbar.
+ */
+ public FloatingToolbar setContentRect(Rect rect) {
+ mContentRect.set(Preconditions.checkNotNull(rect));
+ return this;
+ }
+
+ /**
+ * Sets the suggested width of this floating toolbar.
+ * The actual width will be about this size but there are no guarantees that it will be exactly
+ * the suggested width.
+ * NOTE: Call {@link #updateLayout()} or {@link #show()} to effect visual changes to the
+ * toolbar.
+ */
+ public FloatingToolbar setSuggestedWidth(int suggestedWidth) {
+ mSuggestedWidth = suggestedWidth;
+ return this;
+ }
+
+ /**
+ * Shows this floating toolbar.
+ */
+ public FloatingToolbar show() {
+ List<MenuItem> menuItems = getVisibleAndEnabledMenuItems(mMenu);
+ if (hasContentChanged(menuItems) || hasWidthChanged()) {
+ mPopup.dismiss();
+ layoutMenuItemButtons(menuItems);
+ mShowingTitles = getMenuItemTitles(menuItems);
+ }
+ refreshCoordinates();
+ mPopup.updateCoordinates(mCoordinates.x, mCoordinates.y);
+ if (!mPopup.isShowing()) {
+ mPopup.show(mCoordinates.x, mCoordinates.y);
+ }
+ return this;
+ }
+
+ /**
+ * Updates this floating toolbar to reflect recent position and view updates.
+ * NOTE: This method is a no-op if the toolbar isn't showing.
+ */
+ public FloatingToolbar updateLayout() {
+ if (mPopup.isShowing()) {
+ // show() performs all the logic we need here.
+ show();
+ }
+ return this;
+ }
+
+ /**
+ * Dismisses this floating toolbar.
+ */
+ public void dismiss() {
+ mPopup.dismiss();
+ }
+
+ /**
+ * Returns {@code true} if this popup is currently showing. {@code false} otherwise.
+ */
+ public boolean isShowing() {
+ return mPopup.isShowing();
+ }
+
+ /**
+ * Refreshes {@link #mCoordinates} with values based on {@link #mContentRect}.
+ */
+ private void refreshCoordinates() {
+ int popupWidth = mPopup.getWidth();
+ int popupHeight = mPopup.getHeight();
+ if (!mPopup.isShowing()) {
+ // Popup isn't yet shown, get estimated size from the menu item buttons container.
+ mMenuItemButtonsContainer.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ popupWidth = mMenuItemButtonsContainer.getMeasuredWidth();
+ popupHeight = mMenuItemButtonsContainer.getMeasuredHeight();
+ }
+ int x = mContentRect.centerX() - popupWidth / 2;
+ int y;
+ if (shouldDisplayAtTopOfContent()) {
+ y = mContentRect.top - popupHeight;
+ } else {
+ y = mContentRect.bottom;
+ }
+ mCoordinates.set(x, y);
+ }
+
+ /**
+ * Returns true if this floating toolbar's menu items have been reordered or changed.
+ */
+ private boolean hasContentChanged(List<MenuItem> menuItems) {
+ return !mShowingTitles.equals(getMenuItemTitles(menuItems));
+ }
+
+ /**
+ * Returns true if there is a significant change in width of the toolbar.
+ */
+ private boolean hasWidthChanged() {
+ int actualWidth = mPopup.getWidth();
+ int difference = Math.abs(actualWidth - mSuggestedWidth);
+ return difference > (actualWidth * 0.2);
+ }
+
+ /**
+ * Returns true if the preferred positioning of the toolbar is above the content rect.
+ */
+ private boolean shouldDisplayAtTopOfContent() {
+ return mContentRect.top - getMinimumOverflowHeight(mContext) > 0;
+ }
+
+ /**
+ * Returns the visible and enabled menu items in the specified menu.
+ * This method is recursive.
+ */
+ private List<MenuItem> getVisibleAndEnabledMenuItems(Menu menu) {
+ List<MenuItem> menuItems = new ArrayList<MenuItem>();
+ for (int i = 0; (menu != null) && (i < menu.size()); i++) {
+ MenuItem menuItem = menu.getItem(i);
+ if (menuItem.isVisible() && menuItem.isEnabled()) {
+ Menu subMenu = menuItem.getSubMenu();
+ if (subMenu != null) {
+ menuItems.addAll(getVisibleAndEnabledMenuItems(subMenu));
+ } else {
+ menuItems.add(menuItem);
+ }
+ }
+ }
+ return menuItems;
+ }
+
+ private List<CharSequence> getMenuItemTitles(List<MenuItem> menuItems) {
+ List<CharSequence> titles = new ArrayList<CharSequence>();
+ for (MenuItem menuItem : menuItems) {
+ titles.add(menuItem.getTitle());
+ }
+ return titles;
+ }
+
+ private void layoutMenuItemButtons(List<MenuItem> menuItems) {
+ final int toolbarWidth = getAdjustedToolbarWidth(mContext, mSuggestedWidth)
+ // Reserve space for the "open overflow" button.
+ - getEstimatedOpenOverflowButtonWidth(mContext);
+
+ int availableWidth = toolbarWidth;
+ LinkedList<MenuItem> remainingMenuItems = new LinkedList<MenuItem>(menuItems);
+
+ mMenuItemButtonsContainer.removeAllViews();
+
+ boolean isFirstItem = true;
+ while (!remainingMenuItems.isEmpty()) {
+ final MenuItem menuItem = remainingMenuItems.peek();
+ Button menuItemButton = createMenuItemButton(mContext, menuItem);
+
+ // Adding additional left padding for the first button to even out button spacing.
+ if (isFirstItem) {
+ menuItemButton.setPadding(
+ 2 * menuItemButton.getPaddingLeft(),
+ menuItemButton.getPaddingTop(),
+ menuItemButton.getPaddingRight(),
+ menuItemButton.getPaddingBottom());
+ isFirstItem = false;
+ }
+
+ // Adding additional right padding for the last button to even out button spacing.
+ if (remainingMenuItems.size() == 1) {
+ menuItemButton.setPadding(
+ menuItemButton.getPaddingLeft(),
+ menuItemButton.getPaddingTop(),
+ 2 * menuItemButton.getPaddingRight(),
+ menuItemButton.getPaddingBottom());
+ }
+
+ menuItemButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ int menuItemButtonWidth = Math.min(menuItemButton.getMeasuredWidth(), toolbarWidth);
+ if (menuItemButtonWidth <= availableWidth) {
+ menuItemButton.setTag(menuItem);
+ menuItemButton.setOnClickListener(mMenuItemButtonOnClickListener);
+ mMenuItemButtonsContainer.addView(menuItemButton);
+ menuItemButton.getLayoutParams().width = menuItemButtonWidth;
+ availableWidth -= menuItemButtonWidth;
+ remainingMenuItems.pop();
+ } else {
+ // The "open overflow" button launches the vertical overflow from the
+ // floating toolbar.
+ createOpenOverflowButtonIfNotExists();
+ mMenuItemButtonsContainer.addView(mOpenOverflowButton);
+ break;
+ }
+ }
+ mPopup.setContentView(mMenuItemButtonsContainer);
+ }
+
+ /**
+ * Creates and returns the button that opens the vertical overflow.
+ */
+ private void createOpenOverflowButtonIfNotExists() {
+ mOpenOverflowButton = (ImageButton) LayoutInflater.from(mContext)
+ .inflate(R.layout.floating_popup_open_overflow_button, null);
+ mOpenOverflowButton.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Open the overflow.
+ }
+ });
+ }
+
+ /**
+ * Creates and returns a floating toolbar menu buttons container.
+ */
+ private static ViewGroup createMenuButtonsContainer(Context context) {
+ return (ViewGroup) LayoutInflater.from(context)
+ .inflate(R.layout.floating_popup_container, null);
+ }
+
+ /**
+ * Creates and returns a menu button for the specified menu item.
+ */
+ private static Button createMenuItemButton(Context context, MenuItem menuItem) {
+ Button menuItemButton = (Button) LayoutInflater.from(context)
+ .inflate(R.layout.floating_popup_menu_button, null);
+ menuItemButton.setText(menuItem.getTitle());
+ menuItemButton.setContentDescription(menuItem.getTitle());
+ return menuItemButton;
+ }
+
+ private static int getMinimumOverflowHeight(Context context) {
+ return context.getResources().
+ getDimensionPixelSize(R.dimen.floating_toolbar_minimum_overflow_height);
+ }
+
+ private static int getEstimatedOpenOverflowButtonWidth(Context context) {
+ return context.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_minimum_width);
+ }
+
+ private static int getAdjustedToolbarWidth(Context context, int width) {
+ if (width <= 0 || width > getScreenWidth(context)) {
+ width = context.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_default_width);
+ }
+ return width;
+ }
+
+ /**
+ * Returns the device's screen width.
+ */
+ public static int getScreenWidth(Context context) {
+ return context.getResources().getDisplayMetrics().widthPixels;
+ }
+
+ /**
+ * Returns the device's screen height.
+ */
+ public static int getScreenHeight(Context context) {
+ return context.getResources().getDisplayMetrics().heightPixels;
+ }
+
+
+ /**
+ * A popup window used by the floating toolbar.
+ */
+ private static final class FloatingToolbarPopup {
+
+ private final View mParent;
+ private final PopupWindow mPopupWindow;
+ private final ViewGroup mContentContainer;
+ private final Animator.AnimatorListener mOnDismissEnd =
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mPopupWindow.dismiss();
+ mDismissAnimating = false;
+ }
+ };
+ private final AnimatorSet mGrowFadeInFromBottomAnimation;
+ private final AnimatorSet mShrinkFadeOutFromBottomAnimation;
+
+ private boolean mDismissAnimating;
+
+ /**
+ * Initializes a new floating bar popup.
+ *
+ * @param parent A parent view to get the {@link View#getWindowToken()} token from.
+ */
+ public FloatingToolbarPopup(View parent) {
+ mParent = Preconditions.checkNotNull(parent);
+ mContentContainer = createContentContainer(parent.getContext());
+ mPopupWindow = createPopupWindow(mContentContainer);
+ mGrowFadeInFromBottomAnimation = createGrowFadeInFromBottom(mContentContainer);
+ mShrinkFadeOutFromBottomAnimation =
+ createShrinkFadeOutFromBottomAnimation(mContentContainer, mOnDismissEnd);
+ }
+
+ /**
+ * Shows this popup at the specified coordinates.
+ * The specified coordinates may be adjusted to make sure the popup is entirely on-screen.
+ * If this popup is already showing, this will be a no-op.
+ */
+ public void show(int x, int y) {
+ if (isShowing()) {
+ updateCoordinates(x, y);
+ return;
+ }
+
+ mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, 0, 0);
+ positionOnScreen(x, y);
+ growFadeInFromBottom();
+
+ mDismissAnimating = false;
+ }
+
+ /**
+ * Gets rid of this popup. If the popup isn't currently showing, this will be a no-op.
+ */
+ public void dismiss() {
+ if (!isShowing()) {
+ return;
+ }
+
+ if (mDismissAnimating) {
+ // This window is already dismissing. Don't restart the animation.
+ return;
+ }
+ mDismissAnimating = true;
+ shrinkFadeOutFromBottom();
+ }
+
+ /**
+ * Returns {@code true} if this popup is currently showing. {@code false} otherwise.
+ */
+ public boolean isShowing() {
+ return mPopupWindow.isShowing() && !mDismissAnimating;
+ }
+
+ /**
+ * Updates the coordinates of this popup.
+ * The specified coordinates may be adjusted to make sure the popup is entirely on-screen.
+ */
+ public void updateCoordinates(int x, int y) {
+ if (isShowing()) {
+ positionOnScreen(x, y);
+ }
+ }
+
+ /**
+ * Sets the content of this popup.
+ */
+ public void setContentView(View view) {
+ Preconditions.checkNotNull(view);
+ mContentContainer.removeAllViews();
+ mContentContainer.addView(view);
+ }
+
+ /**
+ * Returns the width of this popup.
+ */
+ public int getWidth() {
+ return mContentContainer.getWidth();
+ }
+
+ /**
+ * Returns the height of this popup.
+ */
+ public int getHeight() {
+ return mContentContainer.getHeight();
+ }
+
+ /**
+ * Returns the context this popup is running in.
+ */
+ public Context getContext() {
+ return mContentContainer.getContext();
+ }
+
+ private void positionOnScreen(int x, int y) {
+ if (getWidth() == 0) {
+ // content size is yet to be measured.
+ mContentContainer.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ }
+ x = clamp(x, 0, getScreenWidth(getContext()) - getWidth());
+ y = clamp(y, 0, getScreenHeight(getContext()) - getHeight());
+
+ // Position the view w.r.t. the window.
+ mContentContainer.setX(x);
+ mContentContainer.setY(y);
+ }
+
+ /**
+ * Performs the "grow and fade in from the bottom" animation on the floating popup.
+ */
+ private void growFadeInFromBottom() {
+ setPivot();
+ mGrowFadeInFromBottomAnimation.start();
+ }
+
+ /**
+ * Performs the "shrink and fade out from bottom" animation on the floating popup.
+ */
+ private void shrinkFadeOutFromBottom() {
+ setPivot();
+ mShrinkFadeOutFromBottomAnimation.start();
+ }
+
+ /**
+ * Sets the popup content container's pivot.
+ */
+ private void setPivot() {
+ mContentContainer.setPivotX(mContentContainer.getMeasuredWidth() / 2);
+ mContentContainer.setPivotY(mContentContainer.getMeasuredHeight());
+ }
+
+ private static ViewGroup createContentContainer(Context context) {
+ return (ViewGroup) LayoutInflater.from(context)
+ .inflate(R.layout.floating_popup_container, null);
+ }
+
+ private static PopupWindow createPopupWindow(View content) {
+ ViewGroup popupContentHolder = new LinearLayout(content.getContext());
+ PopupWindow popupWindow = new PopupWindow(popupContentHolder);
+ popupWindow.setAnimationStyle(0);
+ popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ popupWindow.setWidth(getScreenWidth(content.getContext()));
+ popupWindow.setHeight(getScreenHeight(content.getContext()));
+ content.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+ popupContentHolder.addView(content);
+ return popupWindow;
+ }
+
+ /**
+ * Creates a "grow and fade in from the bottom" animation for the specified view.
+ *
+ * @param view The view to animate
+ */
+ private static AnimatorSet createGrowFadeInFromBottom(View view) {
+ AnimatorSet growFadeInFromBottomAnimation = new AnimatorSet();
+ growFadeInFromBottomAnimation.playTogether(
+ ObjectAnimator.ofFloat(view, View.SCALE_X, 0.5f, 1).setDuration(125),
+ ObjectAnimator.ofFloat(view, View.SCALE_Y, 0.5f, 1).setDuration(125),
+ ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(75));
+ return growFadeInFromBottomAnimation;
+ }
+
+ /**
+ * Creates a "shrink and fade out from bottom" animation for the specified view.
+ *
+ * @param view The view to animate
+ * @param listener The animation listener
+ */
+ private static AnimatorSet createShrinkFadeOutFromBottomAnimation(
+ View view, Animator.AnimatorListener listener) {
+ AnimatorSet shrinkFadeOutFromBottomAnimation = new AnimatorSet();
+ shrinkFadeOutFromBottomAnimation.playTogether(
+ ObjectAnimator.ofFloat(view, View.SCALE_Y, 1, 0.5f).setDuration(125),
+ ObjectAnimator.ofFloat(view, View.ALPHA, 1, 0).setDuration(75));
+ shrinkFadeOutFromBottomAnimation.setStartDelay(150);
+ shrinkFadeOutFromBottomAnimation.addListener(listener);
+ return shrinkFadeOutFromBottomAnimation;
+ }
+
+ /**
+ * Returns value, restricted to the range min->max (inclusive).
+ * If maximum is less than minimum, the result is undefined.
+ *
+ * @param value The value to clamp.
+ * @param minimum The minimum value in the range.
+ * @param maximum The maximum value in the range. Must not be less than minimum.
+ */
+ private static int clamp(int value, int minimum, int maximum) {
+ return Math.max(minimum, Math.min(value, maximum));
+ }
+ }
+}
diff --git a/core/jni/android/graphics/MinikinUtils.cpp b/core/jni/android/graphics/MinikinUtils.cpp
index 8139c24..8bdbff4 100644
--- a/core/jni/android/graphics/MinikinUtils.cpp
+++ b/core/jni/android/graphics/MinikinUtils.cpp
@@ -26,10 +26,10 @@
namespace android {
-void MinikinUtils::doLayout(Layout* layout, const Paint* paint, int bidiFlags, TypefaceImpl* typeface,
- const uint16_t* buf, size_t start, size_t count, size_t bufSize) {
- TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
- layout->setFontCollection(resolvedFace->fFontCollection);
+FontStyle MinikinUtils::prepareMinikinPaint(MinikinPaint* minikinPaint, FontCollection** pFont,
+ const Paint* paint, TypefaceImpl* typeface) {
+ const TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
+ *pFont = resolvedFace->fFontCollection;
FontStyle resolved = resolvedFace->fStyle;
/* Prepare minikin FontStyle */
@@ -40,15 +40,26 @@ void MinikinUtils::doLayout(Layout* layout, const Paint* paint, int bidiFlags, T
FontStyle minikinStyle(minikinLang, minikinVariant, resolved.getWeight(), resolved.getItalic());
/* Prepare minikin Paint */
- MinikinPaint minikinPaint;
- minikinPaint.size = (int)/*WHY?!*/paint->getTextSize();
- minikinPaint.scaleX = paint->getTextScaleX();
- minikinPaint.skewX = paint->getTextSkewX();
- minikinPaint.letterSpacing = paint->getLetterSpacing();
- minikinPaint.paintFlags = MinikinFontSkia::packPaintFlags(paint);
- minikinPaint.fontFeatureSettings = paint->getFontFeatureSettings();
- minikinPaint.hyphenEdit = HyphenEdit(paint->getHyphenEdit());
+ // Note: it would be nice to handle fractional size values (it would improve smooth zoom
+ // behavior), but historically size has been treated as an int.
+ // TODO: explore whether to enable fractional sizes, possibly when linear text flag is set.
+ minikinPaint->size = (int)paint->getTextSize();
+ minikinPaint->scaleX = paint->getTextScaleX();
+ minikinPaint->skewX = paint->getTextSkewX();
+ minikinPaint->letterSpacing = paint->getLetterSpacing();
+ minikinPaint->paintFlags = MinikinFontSkia::packPaintFlags(paint);
+ minikinPaint->fontFeatureSettings = paint->getFontFeatureSettings();
+ minikinPaint->hyphenEdit = HyphenEdit(paint->getHyphenEdit());
+ return minikinStyle;
+}
+void MinikinUtils::doLayout(Layout* layout, const Paint* paint, int bidiFlags,
+ TypefaceImpl* typeface, const uint16_t* buf, size_t start, size_t count,
+ size_t bufSize) {
+ FontCollection *font;
+ MinikinPaint minikinPaint;
+ FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, &font, paint, typeface);
+ layout->setFontCollection(font);
layout->doLayout(buf, start, count, bufSize, bidiFlags, minikinStyle, minikinPaint);
}
diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h
index 236f1fd..1ee6245 100644
--- a/core/jni/android/graphics/MinikinUtils.h
+++ b/core/jni/android/graphics/MinikinUtils.h
@@ -31,22 +31,14 @@
namespace android {
-// TODO: these should be defined in Minikin's Layout.h
-enum {
- kBidi_LTR = 0,
- kBidi_RTL = 1,
- kBidi_Default_LTR = 2,
- kBidi_Default_RTL = 3,
- kBidi_Force_LTR = 4,
- kBidi_Force_RTL = 5,
-
- kBidi_Mask = 0x7
-};
-
class MinikinUtils {
public:
- static void doLayout(Layout* layout, const Paint* paint, int bidiFlags, TypefaceImpl* typeface,
- const uint16_t* buf, size_t start, size_t count, size_t bufSize);
+ static FontStyle prepareMinikinPaint(MinikinPaint* minikinPaint, FontCollection** pFont,
+ const Paint* paint, TypefaceImpl* typeface);
+
+ static void doLayout(Layout* layout, const Paint* paint, int bidiFlags,
+ TypefaceImpl* typeface, const uint16_t* buf, size_t start, size_t count,
+ size_t bufSize);
static float xOffsetForTextAlign(Paint* paint, const Layout& layout);
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index f0131b4..4b43de3 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -101,6 +101,16 @@ public:
}
static jlong init(JNIEnv* env, jobject clazz) {
+ SK_COMPILE_ASSERT(1 << 0 == SkPaint::kAntiAlias_Flag, paint_flags_mismatch);
+ SK_COMPILE_ASSERT(1 << 2 == SkPaint::kDither_Flag, paint_flags_mismatch);
+ SK_COMPILE_ASSERT(1 << 3 == SkPaint::kUnderlineText_Flag, paint_flags_mismatch);
+ SK_COMPILE_ASSERT(1 << 4 == SkPaint::kStrikeThruText_Flag, paint_flags_mismatch);
+ SK_COMPILE_ASSERT(1 << 5 == SkPaint::kFakeBoldText_Flag, paint_flags_mismatch);
+ SK_COMPILE_ASSERT(1 << 6 == SkPaint::kLinearText_Flag, paint_flags_mismatch);
+ SK_COMPILE_ASSERT(1 << 7 == SkPaint::kSubpixelText_Flag, paint_flags_mismatch);
+ SK_COMPILE_ASSERT(1 << 8 == SkPaint::kDevKernText_Flag, paint_flags_mismatch);
+ SK_COMPILE_ASSERT(1 << 10 == SkPaint::kEmbeddedBitmapText_Flag, paint_flags_mismatch);
+
Paint* obj = new Paint();
defaultSettingsForAndroid(obj);
return reinterpret_cast<jlong>(obj);
diff --git a/core/jni/android/graphics/TypefaceImpl.h b/core/jni/android/graphics/TypefaceImpl.h
index d36f83a..4b14917 100644
--- a/core/jni/android/graphics/TypefaceImpl.h
+++ b/core/jni/android/graphics/TypefaceImpl.h
@@ -62,4 +62,4 @@ void TypefaceImpl_setDefault(TypefaceImpl* face);
}
-#endif // _ANDROID_GRAPHICS_TYPEFACE_IMPL_H_ \ No newline at end of file
+#endif // _ANDROID_GRAPHICS_TYPEFACE_IMPL_H_
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 0b737a7..7d12230 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -18,6 +18,8 @@
#include <map>
+#include <ScopedUtfChars.h>
+
#include <utils/Log.h>
#include <utils/Looper.h>
@@ -99,6 +101,9 @@ public:
if (string1 == NULL) {
return string2 != NULL;
}
+ if (string2 == NULL) {
+ return false;
+ }
return string1->compare(*string2) < 0;
}
};
@@ -264,9 +269,12 @@ private:
}
};
-static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQ, jobject msgQ, jfloatArray scratch) {
+static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQ, jobject msgQ,
+ jfloatArray scratch, jstring packageName) {
SensorManager& mgr(SensorManager::getInstance());
- sp<SensorEventQueue> queue(mgr.createEventQueue());
+ ScopedUtfChars packageUtf(env, packageName);
+ String8 clientName(packageUtf.c_str());
+ sp<SensorEventQueue> queue(mgr.createEventQueue(clientName));
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
if (messageQueue == NULL) {
@@ -280,10 +288,11 @@ static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject event
}
static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
- jint maxBatchReportLatency, jint reservedFlags) {
+ jint maxBatchReportLatency) {
sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
+
return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
- reservedFlags);
+ 0);
}
static jint nativeDisableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle) {
@@ -316,11 +325,11 @@ static JNINativeMethod gSystemSensorManagerMethods[] = {
static JNINativeMethod gBaseEventQueueMethods[] = {
{"nativeInitBaseEventQueue",
- "(Landroid/hardware/SystemSensorManager$BaseEventQueue;Landroid/os/MessageQueue;[F)J",
- (void*)nativeInitSensorEventQueue },
+ "(Landroid/hardware/SystemSensorManager$BaseEventQueue;Landroid/os/MessageQueue;[FLjava/lang/String;)J",
+ (void*)nativeInitSensorEventQueue },
{"nativeEnableSensor",
- "(JIIII)I",
+ "(JIII)I",
(void*)nativeEnableSensor },
{"nativeDisableSensor",
diff --git a/core/jni/android_server_FingerprintManager.cpp b/core/jni/android_server_FingerprintManager.cpp
index 853425c..5d59234 100644
--- a/core/jni/android_server_FingerprintManager.cpp
+++ b/core/jni/android_server_FingerprintManager.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "Fingerprint-JNI"
#include "JNIHelp.h"
+#include <inttypes.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
@@ -47,14 +48,15 @@ static jobject gCallback;
class CallbackHandler : public MessageHandler {
int type;
- int arg1, arg2;
+ int arg1, arg2, arg3;
public:
- CallbackHandler(int type, int arg1, int arg2) : type(type), arg1(arg1), arg2(arg2) { }
+ CallbackHandler(int type, int arg1, int arg2, int arg3)
+ : type(type), arg1(arg1), arg2(arg2), arg3(arg3) { }
virtual void handleMessage(const Message& message) {
//ALOG(LOG_VERBOSE, LOG_TAG, "hal_notify(msg=%d, arg1=%d, arg2=%d)\n", msg.type, arg1, arg2);
JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(gCallback, gFingerprintServiceClassInfo.notify, type, arg1, arg2);
+ env->CallVoidMethod(gCallback, gFingerprintServiceClassInfo.notify, type, arg1, arg2, arg3);
}
};
@@ -62,6 +64,7 @@ public:
static void hal_notify_callback(fingerprint_msg_t msg) {
uint32_t arg1 = 0;
uint32_t arg2 = 0;
+ uint32_t arg3 = 0;
switch (msg.type) {
case FINGERPRINT_ERROR:
arg1 = msg.data.error;
@@ -71,13 +74,16 @@ static void hal_notify_callback(fingerprint_msg_t msg) {
break;
case FINGERPRINT_PROCESSED:
arg1 = msg.data.processed.finger.fid;
+ arg2 = msg.data.processed.finger.gid;
break;
case FINGERPRINT_TEMPLATE_ENROLLING:
arg1 = msg.data.enroll.finger.fid;
- arg2 = msg.data.enroll.samples_remaining;
+ arg2 = msg.data.enroll.finger.gid;
+ arg3 = msg.data.enroll.samples_remaining;
break;
case FINGERPRINT_TEMPLATE_REMOVED:
arg1 = msg.data.removed.finger.fid;
+ arg2 = msg.data.removed.finger.gid;
break;
default:
ALOGE("fingerprint: invalid msg: %d", msg.type);
@@ -86,7 +92,7 @@ static void hal_notify_callback(fingerprint_msg_t msg) {
// This call potentially comes in on a thread not owned by us. Hand it off to our
// looper so it runs on our thread when calling back to FingerprintService.
// CallbackHandler object is reference-counted, so no cleanup necessary.
- gLooper->sendMessage(new CallbackHandler(msg.type, arg1, arg2), Message());
+ gLooper->sendMessage(new CallbackHandler(msg.type, arg1, arg2, arg3), Message());
}
static void nativeInit(JNIEnv *env, jobject clazz, jobject mQueue, jobject callbackObj) {
@@ -95,9 +101,15 @@ static void nativeInit(JNIEnv *env, jobject clazz, jobject mQueue, jobject callb
gLooper = android_os_MessageQueue_getMessageQueue(env, mQueue)->getLooper();
}
-static jint nativeEnroll(JNIEnv* env, jobject clazz, jint timeout) {
- ALOG(LOG_VERBOSE, LOG_TAG, "nativeEnroll()\n");
- int ret = gContext.device->enroll(gContext.device, 0, timeout);
+static jint nativeEnroll(JNIEnv* env, jobject clazz, jint timeout, jint groupId) {
+ ALOG(LOG_VERBOSE, LOG_TAG, "nativeEnroll(gid=%d, timeout=%d)\n", groupId, timeout);
+ int ret = gContext.device->enroll(gContext.device, groupId, timeout);
+ return reinterpret_cast<jint>(ret);
+}
+
+static jint nativeAuthenticate(JNIEnv* env, jobject clazz, jlong sessionId, jint groupId) {
+ ALOG(LOG_VERBOSE, LOG_TAG, "nativeAuthenticate(sid=%" PRId64 ", gid=%d)\n", sessionId, groupId);
+ int ret = gContext.device->authenticate(gContext.device, sessionId, groupId);
return reinterpret_cast<jint>(ret);
}
@@ -107,11 +119,11 @@ static jint nativeEnrollCancel(JNIEnv* env, jobject clazz) {
return reinterpret_cast<jint>(ret);
}
-static jint nativeRemove(JNIEnv* env, jobject clazz, jint fingerprintId) {
- ALOG(LOG_VERBOSE, LOG_TAG, "nativeRemove(%d)\n", fingerprintId);
+static jint nativeRemove(JNIEnv* env, jobject clazz, jint fingerId, jint groupId) {
+ ALOG(LOG_VERBOSE, LOG_TAG, "nativeRemove(fid=%d, gid=%d)\n", fingerId, groupId);
fingerprint_finger_id_t finger;
- finger.gid = 0;
- finger.fid = fingerprintId;
+ finger.fid = fingerId;
+ finger.gid = groupId;
int ret = gContext.device->remove(gContext.device, finger);
return reinterpret_cast<jint>(ret);
}
@@ -172,9 +184,10 @@ static jint nativeCloseHal(JNIEnv* env, jobject clazz) {
// TODO: clean up void methods
static const JNINativeMethod g_methods[] = {
- { "nativeEnroll", "(I)I", (void*)nativeEnroll },
+ { "nativeAuthenticate", "(JI)I", (void*)nativeAuthenticate },
+ { "nativeEnroll", "(II)I", (void*)nativeEnroll },
{ "nativeEnrollCancel", "()I", (void*)nativeEnrollCancel },
- { "nativeRemove", "(I)I", (void*)nativeRemove },
+ { "nativeRemove", "(II)I", (void*)nativeRemove },
{ "nativeOpenHal", "()I", (void*)nativeOpenHal },
{ "nativeCloseHal", "()I", (void*)nativeCloseHal },
{ "nativeInit","(Landroid/os/MessageQueue;"
@@ -185,7 +198,7 @@ int register_android_server_fingerprint_FingerprintService(JNIEnv* env) {
jclass clazz = FindClassOrDie(env, FINGERPRINT_SERVICE);
gFingerprintServiceClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
gFingerprintServiceClassInfo.notify =
- GetMethodIDOrDie(env, gFingerprintServiceClassInfo.clazz,"notify", "(III)V");
+ GetMethodIDOrDie(env, gFingerprintServiceClassInfo.clazz,"notify", "(IIII)V");
int result = RegisterMethodsOrDie(env, FINGERPRINT_SERVICE, g_methods, NELEM(g_methods));
ALOG(LOG_VERBOSE, LOG_TAG, "FingerprintManager JNI ready.\n");
return result;
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index 8800f0b..6cc1f68 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -34,6 +34,7 @@
#include "MinikinSkia.h"
#include "MinikinUtils.h"
#include "Paint.h"
+#include "minikin/LineBreaker.h"
namespace android {
@@ -46,636 +47,116 @@ struct JLineBreaksID {
static jclass gLineBreaks_class;
static JLineBreaksID gLineBreaks_fieldID;
-class Builder {
- public:
- ~Builder() {
- utext_close(&mUText);
- delete mBreakIterator;
- }
-
- void setLocale(const icu::Locale& locale) {
- delete mBreakIterator;
- UErrorCode status = U_ZERO_ERROR;
- mBreakIterator = icu::BreakIterator::createLineInstance(locale, status);
- // TODO: check status
- }
-
- void resize(size_t size) {
- mTextBuf.resize(size);
- mWidthBuf.resize(size);
- }
-
- size_t size() const {
- return mTextBuf.size();
- }
-
- uint16_t* buffer() {
- return mTextBuf.data();
- }
-
- float* widths() {
- return mWidthBuf.data();
- }
-
- // set text to current contents of buffer
- void setText() {
- UErrorCode status = U_ZERO_ERROR;
- utext_openUChars(&mUText, mTextBuf.data(), mTextBuf.size(), &status);
- mBreakIterator->setText(&mUText, status);
- }
-
- void finish() {
- if (mTextBuf.size() > MAX_TEXT_BUF_RETAIN) {
- mTextBuf.clear();
- mTextBuf.shrink_to_fit();
- mWidthBuf.clear();
- mWidthBuf.shrink_to_fit();
- }
- }
-
- icu::BreakIterator* breakIterator() const {
- return mBreakIterator;
- }
-
- float measureStyleRun(Paint* paint, TypefaceImpl* typeface, size_t start, size_t end,
- bool isRtl);
-
- void addReplacement(size_t start, size_t end, float width);
-
- private:
- const size_t MAX_TEXT_BUF_RETAIN = 32678;
- icu::BreakIterator* mBreakIterator = nullptr;
- UText mUText = UTEXT_INITIALIZER;
- std::vector<uint16_t>mTextBuf;
- std::vector<float>mWidthBuf;
-};
-
static const int CHAR_SPACE = 0x20;
static const int CHAR_TAB = 0x09;
static const int CHAR_NEWLINE = 0x0a;
static const int CHAR_ZWSP = 0x200b;
-class TabStops {
- public:
- // specified stops must be a sorted array (allowed to be null)
- TabStops(JNIEnv* env, jintArray stops, jint defaultTabWidth) :
- mStops(env), mTabWidth(defaultTabWidth) {
- if (stops != nullptr) {
- mStops.reset(stops);
- mNumStops = mStops.size();
- } else {
- mNumStops = 0;
- }
- }
- float width(float widthSoFar) const {
- const jint* mStopsArray = mStops.get();
- for (int i = 0; i < mNumStops; i++) {
- if (mStopsArray[i] > widthSoFar) {
- return mStopsArray[i];
- }
- }
- // find the next tabstop after widthSoFar
- return static_cast<int>((widthSoFar + mTabWidth) / mTabWidth) * mTabWidth;
- }
- private:
- ScopedIntArrayRO mStops;
- const int mTabWidth;
- int mNumStops;
-
- // disable copying and assignment
- TabStops(const TabStops&);
- void operator=(const TabStops&);
-};
-
-enum PrimitiveType {
- kPrimitiveType_Box,
- kPrimitiveType_Glue,
- kPrimitiveType_Penalty,
- kPrimitiveType_Variable,
- kPrimitiveType_Wordbreak
-};
-
-static const float PENALTY_INFINITY = 1e7; // forced non-break, negative infinity is forced break
-
-struct Primitive {
- PrimitiveType type;
- int location;
- // 'Box' has width
- // 'Glue' has width
- // 'Penalty' has width and penalty
- // 'Variable' has tabStop
- // 'Wordbreak' has penalty
- union {
- struct {
- float width;
- float penalty;
- };
- const TabStops* tabStop;
- };
-};
-
-class LineWidth {
- public:
- LineWidth(float firstWidth, int firstWidthLineCount, float restWidth) :
- mFirstWidth(firstWidth), mFirstWidthLineCount(firstWidthLineCount),
- mRestWidth(restWidth) {}
- float getLineWidth(int line) const {
- return (line < mFirstWidthLineCount) ? mFirstWidth : mRestWidth;
- }
- private:
- const float mFirstWidth;
- const int mFirstWidthLineCount;
- const float mRestWidth;
-};
-
-class LineBreaker {
- public:
- LineBreaker(const std::vector<Primitive>& primitives,
- const LineWidth& lineWidth) :
- mPrimitives(primitives), mLineWidth(lineWidth) {}
- virtual ~LineBreaker() {}
- virtual void computeBreaks(std::vector<int>* breaks, std::vector<float>* widths,
- std::vector<unsigned char>* flags) const = 0;
- protected:
- const std::vector<Primitive>& mPrimitives;
- const LineWidth& mLineWidth;
-};
-
-class OptimizingLineBreaker : public LineBreaker {
- public:
- OptimizingLineBreaker(const std::vector<Primitive>& primitives, const LineWidth& lineWidth) :
- LineBreaker(primitives, lineWidth) {}
- void computeBreaks(std::vector<int>* breaks, std::vector<float>* widths,
- std::vector<unsigned char>* flags) const {
- int numBreaks = mPrimitives.size();
- Node* opt = new Node[numBreaks];
- opt[0].prev = -1;
- opt[0].prevCount = 0;
- opt[0].width = 0;
- opt[0].demerits = 0;
- opt[0].flags = false;
- opt[numBreaks - 1].prev = -1;
- opt[numBreaks - 1].prevCount = 0;
-
- std::list<int> active;
- active.push_back(0);
- int lastBreak = 0;
- for (int i = 0; i < numBreaks; i++) {
- const Primitive& p = mPrimitives[i];
- if (p.type == kPrimitiveType_Penalty) {
- const bool finalBreak = (i + 1 == numBreaks);
- bool breakFound = false;
- Node bestBreak;
- for (std::list<int>::iterator it = active.begin(); it != active.end(); /* incrementing done in loop */) {
- const int pos = *it;
- bool flags;
- float width, printedWidth;
- const int lines = opt[pos].prevCount;
- const float maxWidth = mLineWidth.getLineWidth(lines);
- // we have to compute metrics every time --
- // we can't really precompute this stuff and just deal with breaks
- // because of the way tab characters work, this makes it computationally
- // harder, but this way, we can still optimize while treating tab characters
- // correctly
- computeMetrics(pos, i, &width, &printedWidth, &flags);
- if (printedWidth <= maxWidth) {
- float demerits = computeDemerits(maxWidth, printedWidth,
- finalBreak, p.penalty) + opt[pos].demerits;
- if (!breakFound || demerits < bestBreak.demerits) {
- bestBreak.prev = pos;
- bestBreak.prevCount = opt[pos].prevCount + 1;
- bestBreak.demerits = demerits;
- bestBreak.width = printedWidth;
- bestBreak.flags = flags;
- breakFound = true;
- }
- ++it;
- } else {
- active.erase(it++); // safe to delete like this
- }
- }
- if (p.penalty == -PENALTY_INFINITY) {
- active.clear();
- }
- if (breakFound) {
- opt[i] = bestBreak;
- active.push_back(i);
- lastBreak = i;
- }
- if (active.empty()) {
- // we can't give up!
- float width, printedWidth;
- bool flags;
- const int lines = opt[lastBreak].prevCount;
- const float maxWidth = mLineWidth.getLineWidth(lines);
- const int breakIndex = desperateBreak(lastBreak, numBreaks, maxWidth, &width, &printedWidth, &flags);
-
- opt[breakIndex].prev = lastBreak;
- opt[breakIndex].prevCount = lines + 1;
- opt[breakIndex].demerits = 0; // doesn't matter, it's the only one
- opt[breakIndex].width = width;
- opt[breakIndex].flags = flags;
-
- active.push_back(breakIndex);
- lastBreak = breakIndex;
- i = breakIndex; // incremented by i++
- }
- }
- }
-
- int idx = numBreaks - 1;
- int count = opt[idx].prevCount;
- breaks->resize(count);
- widths->resize(count);
- flags->resize(count);
- while (opt[idx].prev != -1) {
- --count;
-
- (*breaks)[count] = mPrimitives[idx].location;
- (*widths)[count] = opt[idx].width;
- (*flags)[count] = opt[idx].flags;
-
- idx = opt[idx].prev;
- }
- delete[] opt;
- }
- private:
- inline void computeMetrics(int start, int end, float* width, float* printedWidth, bool* flags) const {
- bool f = false;
- float w = 0, pw = 0;
- for (int i = start; i < end; i++) {
- const Primitive& p = mPrimitives[i];
- if (p.type == kPrimitiveType_Box || p.type == kPrimitiveType_Glue) {
- w += p.width;
- if (p.type == kPrimitiveType_Box) {
- pw = w;
- }
- } else if (p.type == kPrimitiveType_Variable) {
- w = p.tabStop->width(w);
- f = true;
- }
- }
- *width = w;
- *printedWidth = pw;
- *flags = f;
- }
-
- inline float computeDemerits(float maxWidth, float width, bool finalBreak, float penalty) const {
- float deviation = finalBreak ? 0 : maxWidth - width;
- return (deviation * deviation) + penalty;
- }
-
- // returns end pos (chosen break), -1 if fail
- inline int desperateBreak(int start, int limit, float maxWidth, float* width, float* printedWidth, bool* flags) const {
- float w = 0, pw = 0;
- bool breakFound = false;
- int breakIndex = 0, firstTabIndex = INT_MAX;
- for (int i = start; i < limit; i++) {
- const Primitive& p = mPrimitives[i];
-
- if (p.type == kPrimitiveType_Box || p.type == kPrimitiveType_Glue) {
- w += p.width;
- if (p.type == kPrimitiveType_Box) {
- pw = w;
- }
- } else if (p.type == kPrimitiveType_Variable) {
- w = p.tabStop->width(w);
- firstTabIndex = std::min(firstTabIndex, i);
- }
-
- if (pw > maxWidth) {
- if (breakFound) {
- break;
- } else {
- // no choice, keep going
- }
- }
-
- // must make progress
- if (i > start && (p.type == kPrimitiveType_Penalty || p.type == kPrimitiveType_Wordbreak)) {
- breakFound = true;
- breakIndex = i;
- }
- }
-
- if (breakFound) {
- *width = w;
- *printedWidth = pw;
- *flags = (start <= firstTabIndex && firstTabIndex < breakIndex);
- return breakIndex;
- } else {
- return -1;
- }
- }
-
- struct Node {
- int prev; // set to sentinel value (-1) for initial node
- int prevCount; // number of breaks so far
- float demerits;
- float width;
- bool flags;
- };
-};
-
-class GreedyLineBreaker : public LineBreaker {
- public:
- GreedyLineBreaker(const std::vector<Primitive>& primitives, const LineWidth& lineWidth) :
- LineBreaker(primitives, lineWidth) {}
- void computeBreaks(std::vector<int>* breaks, std::vector<float>* widths,
- std::vector<unsigned char>* flags) const {
- int lineNum = 0;
- float width = 0, printedWidth = 0;
- bool breakFound = false, goodBreakFound = false;
- int breakIndex = 0, goodBreakIndex = 0;
- float breakWidth = 0, goodBreakWidth = 0;
- int firstTabIndex = INT_MAX;
-
- float maxWidth = mLineWidth.getLineWidth(lineNum);
-
- const int numPrimitives = mPrimitives.size();
- // greedily fit as many characters as possible on each line
- // loop over all primitives, and choose the best break point
- // (if possible, a break point without splitting a word)
- // after going over the maximum length
- for (int i = 0; i < numPrimitives; i++) {
- const Primitive& p = mPrimitives[i];
-
- // update the current line width
- if (p.type == kPrimitiveType_Box || p.type == kPrimitiveType_Glue) {
- width += p.width;
- if (p.type == kPrimitiveType_Box) {
- printedWidth = width;
- }
- } else if (p.type == kPrimitiveType_Variable) {
- width = p.tabStop->width(width);
- // keep track of first tab character in the region we are examining
- // so we can determine whether or not a line contains a tab
- firstTabIndex = std::min(firstTabIndex, i);
- }
-
- // find the best break point for the characters examined so far
- if (printedWidth > maxWidth) {
- if (breakFound || goodBreakFound) {
- if (goodBreakFound) {
- // a true line break opportunity existed in the characters examined so far,
- // so there is no need to split a word
- i = goodBreakIndex; // no +1 because of i++
- lineNum++;
- maxWidth = mLineWidth.getLineWidth(lineNum);
- breaks->push_back(mPrimitives[goodBreakIndex].location);
- widths->push_back(goodBreakWidth);
- flags->push_back(firstTabIndex < goodBreakIndex);
- firstTabIndex = INT_MAX;
- } else {
- // must split a word because there is no other option
- i = breakIndex; // no +1 because of i++
- lineNum++;
- maxWidth = mLineWidth.getLineWidth(lineNum);
- breaks->push_back(mPrimitives[breakIndex].location);
- widths->push_back(breakWidth);
- flags->push_back(firstTabIndex < breakIndex);
- firstTabIndex = INT_MAX;
- }
- printedWidth = width = 0;
- goodBreakFound = breakFound = false;
- goodBreakWidth = breakWidth = 0;
- continue;
- } else {
- // no choice, keep going... must make progress by putting at least one
- // character on a line, even if part of that character is cut off --
- // there is no other option
- }
- }
-
- // update possible break points
- if (p.type == kPrimitiveType_Penalty && p.penalty < PENALTY_INFINITY) {
- // this does not handle penalties with width
-
- // handle forced line break
- if (p.penalty == -PENALTY_INFINITY) {
- lineNum++;
- maxWidth = mLineWidth.getLineWidth(lineNum);
- breaks->push_back(p.location);
- widths->push_back(printedWidth);
- flags->push_back(firstTabIndex < i);
- firstTabIndex = INT_MAX;
- printedWidth = width = 0;
- goodBreakFound = breakFound = false;
- goodBreakWidth = breakWidth = 0;
- continue;
- }
- if (i > breakIndex && (printedWidth <= maxWidth || breakFound == false)) {
- breakFound = true;
- breakIndex = i;
- breakWidth = printedWidth;
- }
- if (i > goodBreakIndex && printedWidth <= maxWidth) {
- goodBreakFound = true;
- goodBreakIndex = i;
- goodBreakWidth = printedWidth;
- }
- } else if (p.type == kPrimitiveType_Wordbreak) {
- // only do this if necessary -- we don't want to break words
- // when possible, but sometimes it is unavoidable
- if (i > breakIndex && (printedWidth <= maxWidth || breakFound == false)) {
- breakFound = true;
- breakIndex = i;
- breakWidth = printedWidth;
- }
- }
- }
-
- if (breakFound || goodBreakFound) {
- // output last break if there are more characters to output
- if (goodBreakFound) {
- breaks->push_back(mPrimitives[goodBreakIndex].location);
- widths->push_back(goodBreakWidth);
- flags->push_back(firstTabIndex < goodBreakIndex);
- } else {
- breaks->push_back(mPrimitives[breakIndex].location);
- widths->push_back(breakWidth);
- flags->push_back(firstTabIndex < breakIndex);
- }
- }
- }
-};
+// set text and set a number of parameters for creating a layout (width, tabstops, strategy)
+static void nSetupParagraph(JNIEnv* env, jclass, jlong nativePtr, jcharArray text, jint length,
+ jfloat firstWidth, jint firstWidthLineLimit, jfloat restWidth,
+ jintArray variableTabStops, jint defaultTabStop, jint strategy) {
+ LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr);
+ b->resize(length);
+ env->GetCharArrayRegion(text, 0, length, b->buffer());
+ b->setText();
+ b->setLineWidths(firstWidth, firstWidthLineLimit, restWidth);
+ if (variableTabStops == nullptr) {
+ b->setTabStops(nullptr, 0, defaultTabStop);
+ } else {
+ ScopedIntArrayRO stops(env, variableTabStops);
+ b->setTabStops(stops.get(), stops.size(), defaultTabStop);
+ }
+ b->setStrategy(static_cast<BreakStrategy>(strategy));
+}
-static jint recycleCopy(JNIEnv* env, jobject recycle, jintArray recycleBreaks,
+static void recycleCopy(JNIEnv* env, jobject recycle, jintArray recycleBreaks,
jfloatArray recycleWidths, jbooleanArray recycleFlags,
- jint recycleLength, const std::vector<jint>& breaks,
- const std::vector<jfloat>& widths, const std::vector<jboolean>& flags) {
- int bufferLength = breaks.size();
- if (recycleLength < bufferLength) {
+ jint recycleLength, size_t nBreaks, const jint* breaks,
+ const jfloat* widths, const jboolean* flags) {
+ if ((size_t)recycleLength < nBreaks) {
// have to reallocate buffers
- recycleBreaks = env->NewIntArray(bufferLength);
- recycleWidths = env->NewFloatArray(bufferLength);
- recycleFlags = env->NewBooleanArray(bufferLength);
+ recycleBreaks = env->NewIntArray(nBreaks);
+ recycleWidths = env->NewFloatArray(nBreaks);
+ recycleFlags = env->NewBooleanArray(nBreaks);
env->SetObjectField(recycle, gLineBreaks_fieldID.breaks, recycleBreaks);
env->SetObjectField(recycle, gLineBreaks_fieldID.widths, recycleWidths);
env->SetObjectField(recycle, gLineBreaks_fieldID.flags, recycleFlags);
}
// copy data
- env->SetIntArrayRegion(recycleBreaks, 0, breaks.size(), &breaks.front());
- env->SetFloatArrayRegion(recycleWidths, 0, widths.size(), &widths.front());
- env->SetBooleanArrayRegion(recycleFlags, 0, flags.size(), &flags.front());
-
- return bufferLength;
-}
-
-void computePrimitives(const jchar* textArr, const jfloat* widthsArr, jint length, const std::vector<int>& breaks,
- const TabStops& tabStopCalculator, std::vector<Primitive>* primitives) {
- int breaksSize = breaks.size();
- int breakIndex = 0;
- Primitive p;
- for (int i = 0; i < length; i++) {
- p.location = i;
- jchar c = textArr[i];
- if (c == CHAR_SPACE || c == CHAR_ZWSP) {
- p.type = kPrimitiveType_Glue;
- p.width = widthsArr[i];
- primitives->push_back(p);
- } else if (c == CHAR_TAB) {
- p.type = kPrimitiveType_Variable;
- p.tabStop = &tabStopCalculator; // shared between all variable primitives
- primitives->push_back(p);
- } else if (c != CHAR_NEWLINE) {
- while (breakIndex < breaksSize && breaks[breakIndex] < i) breakIndex++;
- p.width = 0;
- if (breakIndex < breaksSize && breaks[breakIndex] == i) {
- p.type = kPrimitiveType_Penalty;
- p.penalty = 0;
- } else {
- p.type = kPrimitiveType_Wordbreak;
- }
- if (widthsArr[i] != 0) {
- primitives->push_back(p);
- }
-
- p.type = kPrimitiveType_Box;
- p.width = widthsArr[i];
- primitives->push_back(p);
- }
- }
- // final break at end of everything
- p.location = length;
- p.type = kPrimitiveType_Penalty;
- p.width = 0;
- p.penalty = -PENALTY_INFINITY;
- primitives->push_back(p);
-}
-
-// sets the text on the builder
-static void nSetText(JNIEnv* env, jclass, jlong nativePtr, jcharArray text, int length) {
- Builder* b = reinterpret_cast<Builder*>(nativePtr);
- b->resize(length);
- env->GetCharArrayRegion(text, 0, length, b->buffer());
- b->setText();
+ env->SetIntArrayRegion(recycleBreaks, 0, nBreaks, breaks);
+ env->SetFloatArrayRegion(recycleWidths, 0, nBreaks, widths);
+ env->SetBooleanArrayRegion(recycleFlags, 0, nBreaks, flags);
}
static jint nComputeLineBreaks(JNIEnv* env, jclass, jlong nativePtr,
- jint length,
- jfloat firstWidth, jint firstWidthLineLimit, jfloat restWidth,
- jintArray variableTabStops, jint defaultTabStop, jboolean optimize,
jobject recycle, jintArray recycleBreaks,
jfloatArray recycleWidths, jbooleanArray recycleFlags,
jint recycleLength) {
- Builder* b = reinterpret_cast<Builder*>(nativePtr);
+ LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr);
- std::vector<int> breaks;
+ size_t nBreaks = b->computeBreaks();
- icu::BreakIterator* breakIterator = b->breakIterator();
- int loc = breakIterator->first();
- while ((loc = breakIterator->next()) != icu::BreakIterator::DONE) {
- breaks.push_back(loc);
- }
-
- // TODO: all these allocations can be moved into the builder
- std::vector<Primitive> primitives;
- TabStops tabStops(env, variableTabStops, defaultTabStop);
- computePrimitives(b->buffer(), b->widths(), length, breaks, tabStops, &primitives);
-
- LineWidth lineWidth(firstWidth, firstWidthLineLimit, restWidth);
- std::vector<int> computedBreaks;
- std::vector<float> computedWidths;
- std::vector<unsigned char> computedFlags;
+ recycleCopy(env, recycle, recycleBreaks, recycleWidths, recycleFlags, recycleLength,
+ nBreaks, b->getBreaks(), b->getWidths(), b->getFlags());
- if (optimize) {
- OptimizingLineBreaker breaker(primitives, lineWidth);
- breaker.computeBreaks(&computedBreaks, &computedWidths, &computedFlags);
- } else {
- GreedyLineBreaker breaker(primitives, lineWidth);
- breaker.computeBreaks(&computedBreaks, &computedWidths, &computedFlags);
- }
b->finish();
- return recycleCopy(env, recycle, recycleBreaks, recycleWidths, recycleFlags, recycleLength,
- computedBreaks, computedWidths, computedFlags);
+ return static_cast<jint>(nBreaks);
}
static jlong nNewBuilder(JNIEnv*, jclass) {
- return reinterpret_cast<jlong>(new Builder);
+ return reinterpret_cast<jlong>(new LineBreaker);
}
static void nFreeBuilder(JNIEnv*, jclass, jlong nativePtr) {
- delete reinterpret_cast<Builder*>(nativePtr);
+ delete reinterpret_cast<LineBreaker*>(nativePtr);
}
static void nFinishBuilder(JNIEnv*, jclass, jlong nativePtr) {
- Builder* b = reinterpret_cast<Builder*>(nativePtr);
+ LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr);
b->finish();
}
static void nSetLocale(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleName) {
ScopedIcuLocale icuLocale(env, javaLocaleName);
- Builder* b = reinterpret_cast<Builder*>(nativePtr);
+ LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr);
if (icuLocale.valid()) {
b->setLocale(icuLocale.locale());
}
}
-float Builder::measureStyleRun(Paint* paint, TypefaceImpl* typeface, size_t start, size_t end,
- bool isRtl) {
- Layout layout;
- int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
- // TODO: should we provide more context?
- MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, mTextBuf.data() + start, 0,
- end - start, end - start);
- layout.getAdvances(mWidthBuf.data() + start);
- return layout.getAdvance();
-}
-
-void Builder::addReplacement(size_t start, size_t end, float width) {
- mWidthBuf[start] = width;
- std::fill(&mWidthBuf[start + 1], &mWidthBuf[end], 0.0f);
-}
-
// Basically similar to Paint.getTextRunAdvances but with C++ interface
static jfloat nAddStyleRun(JNIEnv* env, jclass, jlong nativePtr,
jlong nativePaint, jlong nativeTypeface, jint start, jint end, jboolean isRtl) {
- Builder* b = reinterpret_cast<Builder*>(nativePtr);
+ LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr);
Paint* paint = reinterpret_cast<Paint*>(nativePaint);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(nativeTypeface);
- return b->measureStyleRun(paint, typeface, start, end, isRtl);
+ FontCollection *font;
+ MinikinPaint minikinPaint;
+ FontStyle style = MinikinUtils::prepareMinikinPaint(&minikinPaint, &font, paint, typeface);
+ return b->addStyleRun(&minikinPaint, font, style, start, end, isRtl);
}
// Accept width measurements for the run, passed in from Java
static void nAddMeasuredRun(JNIEnv* env, jclass, jlong nativePtr,
jint start, jint end, jfloatArray widths) {
- Builder* b = reinterpret_cast<Builder*>(nativePtr);
- env->GetFloatArrayRegion(widths, start, end - start, b->widths() + start);
+ LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr);
+ env->GetFloatArrayRegion(widths, start, end - start, b->charWidths() + start);
+ b->addStyleRun(nullptr, nullptr, FontStyle{}, start, end, false);
}
static void nAddReplacementRun(JNIEnv* env, jclass, jlong nativePtr,
jint start, jint end, jfloat width) {
- Builder* b = reinterpret_cast<Builder*>(nativePtr);
+ LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr);
b->addReplacement(start, end, width);
}
static void nGetWidths(JNIEnv* env, jclass, jlong nativePtr, jfloatArray widths) {
- Builder* b = reinterpret_cast<Builder*>(nativePtr);
- env->SetFloatArrayRegion(widths, 0, b->size(), b->widths());
+ LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr);
+ env->SetFloatArrayRegion(widths, 0, b->size(), b->charWidths());
}
static JNINativeMethod gMethods[] = {
@@ -684,12 +165,12 @@ static JNINativeMethod gMethods[] = {
{"nFreeBuilder", "(J)V", (void*) nFreeBuilder},
{"nFinishBuilder", "(J)V", (void*) nFinishBuilder},
{"nSetLocale", "(JLjava/lang/String;)V", (void*) nSetLocale},
- {"nSetText", "(J[CI)V", (void*) nSetText},
+ {"nSetupParagraph", "(J[CIFIF[III)V", (void*) nSetupParagraph},
{"nAddStyleRun", "(JJJIIZ)F", (void*) nAddStyleRun},
{"nAddMeasuredRun", "(JII[F)V", (void*) nAddMeasuredRun},
{"nAddReplacementRun", "(JIIF)V", (void*) nAddReplacementRun},
{"nGetWidths", "(J[F)V", (void*) nGetWidths},
- {"nComputeLineBreaks", "(JIFIF[IIZLandroid/text/StaticLayout$LineBreaks;[I[F[ZI)I",
+ {"nComputeLineBreaks", "(JLandroid/text/StaticLayout$LineBreaks;[I[F[ZI)I",
(void*) nComputeLineBreaks}
};
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4d6b5f6..851c4bf 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -77,6 +77,8 @@
<protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" />
<protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGING" />
+ <protected-broadcast android:name="android.os.action.SCREEN_BRIGHTNESS_BOOST_CHANGED" />
+
<protected-broadcast android:name="android.app.action.ENTER_CAR_MODE" />
<protected-broadcast android:name="android.app.action.EXIT_CAR_MODE" />
<protected-broadcast android:name="android.app.action.ENTER_DESK_MODE" />
@@ -2607,7 +2609,8 @@
android:protectionLevel="signature|system" />
<!-- @SystemApi Allows an application to collect component usage
- statistics @hide -->
+ statistics
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.PACKAGE_USAGE_STATS"
android:label="@string/permlab_pkgUsageStats"
android:description="@string/permdesc_pkgUsageStats"
diff --git a/core/res/res/anim/ic_checkbox_checked_box_inner_merged_animation.xml b/core/res/res/anim/ic_checkbox_checked_box_inner_merged_animation.xml
new file mode 100644
index 0000000..7be32af
--- /dev/null
+++ b/core/res/res/anim/ic_checkbox_checked_box_inner_merged_animation.xml
@@ -0,0 +1,52 @@
+<?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.
+-->
+
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0,-1.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:valueTo="M 0.0,-1.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0,-1.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:valueTo="M -7.0,-7.0 l 14.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,14.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -14.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-14.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_0" />
+ </set>
+</set>
diff --git a/core/res/res/anim/ic_checkbox_checked_check_path_merged_animation.xml b/core/res/res/anim/ic_checkbox_checked_check_path_merged_animation.xml
new file mode 100644
index 0000000..fcba2c8
--- /dev/null
+++ b/core/res/res/anim/ic_checkbox_checked_check_path_merged_animation.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M -2.0,5.00001525879 c 0.0,0.0 -5.0,-5.00001525879 -5.0,-5.00001525879 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 3.58590698242,3.58601379395 3.58590698242,3.58601379395 c 0.0,0.0 7.58590698242,-7.58601379395 7.58590698242,-7.58601379395 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -9.0,9.00001525879 -9.0,9.00001525879 Z"
+ android:valueTo="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M 0.0,1.42500305176 c 0.0,0.0 -1.4234161377,-1.40159606934 -1.4234161377,-1.40159606934 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 0.00932312011719,-0.0124053955078 0.00932312011719,-0.0124053955078 c 0.0,0.0 0.0234069824219,-0.0235137939453 0.0234069824219,-0.0235137939453 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -1.4375,1.43751525879 -1.4375,1.43751525879 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_0" />
+ </set>
+</set>
diff --git a/core/res/res/anim/ic_checkbox_checked_icon_null_animation.xml b/core/res/res/anim/ic_checkbox_checked_icon_null_animation.xml
new file mode 100644
index 0000000..312003f
--- /dev/null
+++ b/core/res/res/anim/ic_checkbox_checked_icon_null_animation.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="scaleX"
+ android:valueFrom="0.2"
+ android:valueTo="0.18"
+ android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleX"
+ android:valueFrom="0.18"
+ android:valueTo="0.2"
+ android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="scaleY"
+ android:valueFrom="0.2"
+ android:valueTo="0.18"
+ android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleY"
+ android:valueFrom="0.18"
+ android:valueTo="0.2"
+ android:interpolator="@interpolator/ic_checkbox_checked_animation_interpolator_1" />
+ </set>
+</set>
diff --git a/core/res/res/anim/ic_checkbox_unchecked_box_inner_merged_animation.xml b/core/res/res/anim/ic_checkbox_unchecked_box_inner_merged_animation.xml
new file mode 100644
index 0000000..b5ad5e9d
--- /dev/null
+++ b/core/res/res/anim/ic_checkbox_unchecked_box_inner_merged_animation.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="pathData"
+ android:valueFrom="M -7.0,-7.0 l 14.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,14.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -14.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-14.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:valueTo="M 0.0,-0.05 l 0.0,0.0 c 0.02761423749,0.0 0.05,0.02238576251 0.05,0.05 l 0.0,0.0 c 0.0,0.02761423749 -0.02238576251,0.05 -0.05,0.05 l 0.0,0.0 c -0.02761423749,0.0 -0.05,-0.02238576251 -0.05,-0.05 l 0.0,0.0 c 0.0,-0.02761423749 0.02238576251,-0.05 0.05,-0.05 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="fillAlpha"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_0" />
+ </set>
+</set>
diff --git a/core/res/res/anim/ic_checkbox_unchecked_box_outer_merged_animation.xml b/core/res/res/anim/ic_checkbox_unchecked_box_outer_merged_animation.xml
new file mode 100644
index 0000000..066971a
--- /dev/null
+++ b/core/res/res/anim/ic_checkbox_unchecked_box_outer_merged_animation.xml
@@ -0,0 +1,52 @@
+<?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.
+-->
+
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M -2.0,5.00001525879 c 0.0,0.0 -1.4234161377,-1.40159606934 -1.4234161377,-1.40159606934 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 0.00932312011719,-0.0124053955078 0.00932312011719,-0.0124053955078 c 0.0,0.0 0.0234069824219,-0.0235137939453 0.0234069824219,-0.0235137939453 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -1.4375,1.43751525879 -1.4375,1.43751525879 Z"
+ android:valueTo="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M -2.0,5.00001525879 c 0.0,0.0 -1.4234161377,-1.40159606934 -1.4234161377,-1.40159606934 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 0.00932312011719,-0.0124053955078 0.00932312011719,-0.0124053955078 c 0.0,0.0 0.0234069824219,-0.0235137939453 0.0234069824219,-0.0235137939453 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -1.4375,1.43751525879 -1.4375,1.43751525879 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="300"
+ android:propertyName="pathData"
+ android:valueFrom="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M -2.0,5.00001525879 c 0.0,0.0 -1.4234161377,-1.40159606934 -1.4234161377,-1.40159606934 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 0.00932312011719,-0.0124053955078 0.00932312011719,-0.0124053955078 c 0.0,0.0 0.0234069824219,-0.0235137939453 0.0234069824219,-0.0235137939453 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -1.4375,1.43751525879 -1.4375,1.43751525879 Z"
+ android:valueTo="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M -2.0,5.00001525879 c 0.0,0.0 -5.0,-5.00001525879 -5.0,-5.00001525879 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 3.58590698242,3.58601379395 3.58590698242,3.58601379395 c 0.0,0.0 7.58590698242,-7.58601379395 7.58590698242,-7.58601379395 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -9.0,9.00001525879 -9.0,9.00001525879 Z"
+ android:valueType="pathType"
+ android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="33"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_0" />
+ </set>
+</set>
diff --git a/core/res/res/anim/ic_checkbox_unchecked_icon_null_animation.xml b/core/res/res/anim/ic_checkbox_unchecked_icon_null_animation.xml
new file mode 100644
index 0000000..fc40d47
--- /dev/null
+++ b/core/res/res/anim/ic_checkbox_unchecked_icon_null_animation.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleX"
+ android:valueFrom="0.2"
+ android:valueTo="0.18"
+ android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+ <objectAnimator
+ android:duration="300"
+ android:propertyName="scaleX"
+ android:valueFrom="0.18"
+ android:valueTo="0.2"
+ android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="200"
+ android:propertyName="scaleY"
+ android:valueFrom="0.2"
+ android:valueTo="0.18"
+ android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+ <objectAnimator
+ android:duration="300"
+ android:propertyName="scaleY"
+ android:valueFrom="0.18"
+ android:valueTo="0.2"
+ android:interpolator="@interpolator/ic_checkbox_unchecked_animation_interpolator_1" />
+ </set>
+</set>
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_000.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_000.png
deleted file mode 100644
index 3cb4073..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_001.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_001.png
deleted file mode 100644
index 8fd1480..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_002.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_002.png
deleted file mode 100644
index d35b579..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_003.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_003.png
deleted file mode 100644
index 543c6bc..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_004.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_004.png
deleted file mode 100644
index 4fc3c40..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_005.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_005.png
deleted file mode 100644
index c184535..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_006.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_006.png
deleted file mode 100644
index 9f9dd43..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_007.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_007.png
deleted file mode 100644
index 8c629ce..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_008.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_008.png
deleted file mode 100644
index 81134b5..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_009.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_009.png
deleted file mode 100644
index baa5860..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_010.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_010.png
deleted file mode 100644
index d7e28366..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_011.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_011.png
deleted file mode 100644
index 6f24795..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_012.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_012.png
deleted file mode 100644
index 22f997d..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_013.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_013.png
deleted file mode 100644
index 85f4471..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_014.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_014.png
deleted file mode 100644
index ad483c9..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_015.png b/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_015.png
deleted file mode 100644
index f24c2fb..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_off_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_000.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_000.png
deleted file mode 100644
index 7a9e9bd..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_001.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_001.png
deleted file mode 100644
index af04902..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_002.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_002.png
deleted file mode 100644
index 32a6e94..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_003.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_003.png
deleted file mode 100644
index c1b4b37..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_004.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_004.png
deleted file mode 100644
index 34d3ade..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_005.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_005.png
deleted file mode 100644
index 3d5db53..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_006.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_006.png
deleted file mode 100644
index ea35437..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_007.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_007.png
deleted file mode 100644
index 48744f8..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_008.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_008.png
deleted file mode 100644
index f654517..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_009.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_009.png
deleted file mode 100644
index 16f959a..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_010.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_010.png
deleted file mode 100644
index 98c754b..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_011.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_011.png
deleted file mode 100644
index 5827dc2..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_012.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_012.png
deleted file mode 100644
index 9850d74..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_013.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_013.png
deleted file mode 100644
index 03ab06b..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_014.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_014.png
deleted file mode 100644
index 11cdd88..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_015.png b/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_015.png
deleted file mode 100644
index 874edbf..0000000
--- a/core/res/res/drawable-hdpi/btn_check_to_on_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_000.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_000.png
deleted file mode 100644
index 9759818..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_001.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_001.png
deleted file mode 100644
index 4eb2c4f..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_002.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_002.png
deleted file mode 100644
index e6d6b42..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_003.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_003.png
deleted file mode 100644
index 03cb23a..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_004.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_004.png
deleted file mode 100644
index bfe3c3d..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_005.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_005.png
deleted file mode 100644
index 65bdf42..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_006.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_006.png
deleted file mode 100644
index 44f9614b..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_007.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_007.png
deleted file mode 100644
index cf8ec38..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_008.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_008.png
deleted file mode 100644
index 4d624b3..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_009.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_009.png
deleted file mode 100644
index 7c4eb7f..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_010.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_010.png
deleted file mode 100644
index e90dd31..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_011.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_011.png
deleted file mode 100644
index 831c0e8..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_012.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_012.png
deleted file mode 100644
index 7355dfd..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_013.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_013.png
deleted file mode 100644
index be71a69..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_014.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_014.png
deleted file mode 100644
index a4a185b..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_015.png b/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_015.png
deleted file mode 100644
index 8d0386f..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_off_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_000.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_000.png
deleted file mode 100644
index 70793c4..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_001.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_001.png
deleted file mode 100644
index 632082b..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_002.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_002.png
deleted file mode 100644
index e7fc5fb..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_003.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_003.png
deleted file mode 100644
index 91a0a33..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_004.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_004.png
deleted file mode 100644
index 3bd90d6..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_005.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_005.png
deleted file mode 100644
index 5ac39ec..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_006.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_006.png
deleted file mode 100644
index 4181983..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_007.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_007.png
deleted file mode 100644
index c8b04df..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_008.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_008.png
deleted file mode 100644
index b7b3a9f..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_009.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_009.png
deleted file mode 100644
index 62bc4ed..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_010.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_010.png
deleted file mode 100644
index ac463ad..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_011.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_011.png
deleted file mode 100644
index 12b605d..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_012.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_012.png
deleted file mode 100644
index 63a3c6a..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_013.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_013.png
deleted file mode 100644
index 17660c4..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_014.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_014.png
deleted file mode 100644
index 7d9de3d..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_015.png b/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_015.png
deleted file mode 100644
index 8aa1be2..0000000
--- a/core/res/res/drawable-mdpi/btn_check_to_on_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_000.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_000.png
deleted file mode 100644
index 2347643..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_001.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_001.png
deleted file mode 100644
index 70aaa01..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_002.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_002.png
deleted file mode 100644
index 01e498a..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_003.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_003.png
deleted file mode 100644
index 71d1cf7..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_004.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_004.png
deleted file mode 100644
index d1e7b1d..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_005.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_005.png
deleted file mode 100644
index 7db7d06..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_006.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_006.png
deleted file mode 100644
index dadb62e..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_007.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_007.png
deleted file mode 100644
index f87f744..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_008.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_008.png
deleted file mode 100644
index be99d87..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_009.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_009.png
deleted file mode 100644
index f83bc05..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_010.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_010.png
deleted file mode 100644
index 870071d..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_011.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_011.png
deleted file mode 100644
index 3a18414..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_012.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_012.png
deleted file mode 100644
index f3d1187..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_013.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_013.png
deleted file mode 100644
index 4078cca..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_014.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_014.png
deleted file mode 100644
index d4849b5..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_015.png b/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_015.png
deleted file mode 100644
index 6e2af72..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_off_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_000.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_000.png
deleted file mode 100644
index 9244174..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_001.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_001.png
deleted file mode 100644
index 8c7fe95..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_002.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_002.png
deleted file mode 100644
index 71eb1d0..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_003.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_003.png
deleted file mode 100644
index 613f38a..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_004.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_004.png
deleted file mode 100644
index 2d20ccc..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_005.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_005.png
deleted file mode 100644
index 407f78d..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_006.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_006.png
deleted file mode 100644
index 1bf24b0..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_007.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_007.png
deleted file mode 100644
index a450bd0..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_008.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_008.png
deleted file mode 100644
index 63ba593..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_009.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_009.png
deleted file mode 100644
index 6d05e5a..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_010.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_010.png
deleted file mode 100644
index 1c8cd8f..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_011.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_011.png
deleted file mode 100644
index b8bc564..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_012.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_012.png
deleted file mode 100644
index 3d80128..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_013.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_013.png
deleted file mode 100644
index c21dfba..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_014.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_014.png
deleted file mode 100644
index 2dfe90d..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_015.png b/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_015.png
deleted file mode 100644
index 5f40d73..0000000
--- a/core/res/res/drawable-xhdpi/btn_check_to_on_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_000.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_000.png
deleted file mode 100644
index b754381..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_001.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_001.png
deleted file mode 100644
index 517d7a7..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_002.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_002.png
deleted file mode 100644
index 2c1d5b6..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_003.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_003.png
deleted file mode 100644
index 0c6ff7e..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_004.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_004.png
deleted file mode 100644
index 0796601..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_005.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_005.png
deleted file mode 100644
index 9b4e0f8..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_006.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_006.png
deleted file mode 100644
index 25767eb..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_007.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_007.png
deleted file mode 100644
index cd0951f..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_008.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_008.png
deleted file mode 100644
index 9ae8165..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_009.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_009.png
deleted file mode 100644
index efd9bc6..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_010.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_010.png
deleted file mode 100644
index fccbc9d..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_011.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_011.png
deleted file mode 100644
index dddafca..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_012.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_012.png
deleted file mode 100644
index 7e37433..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_013.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_013.png
deleted file mode 100644
index 9bc22de..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_014.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_014.png
deleted file mode 100644
index 507ed10..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_015.png b/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_015.png
deleted file mode 100644
index 6a21c7f..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_off_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_000.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_000.png
deleted file mode 100644
index 0d544d9..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_001.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_001.png
deleted file mode 100644
index 39da0ac..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_002.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_002.png
deleted file mode 100644
index d5ada12..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_003.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_003.png
deleted file mode 100644
index d4e096c..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_004.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_004.png
deleted file mode 100644
index 468a9b4..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_005.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_005.png
deleted file mode 100644
index ea3cd2e..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_006.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_006.png
deleted file mode 100644
index 0652cb0..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_007.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_007.png
deleted file mode 100644
index 768d2b0..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_008.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_008.png
deleted file mode 100644
index 1d06a90..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_009.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_009.png
deleted file mode 100644
index 8a70a80..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_010.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_010.png
deleted file mode 100644
index bf9ec7f..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_011.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_011.png
deleted file mode 100644
index cff07b9..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_012.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_012.png
deleted file mode 100644
index 40f997e..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_013.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_013.png
deleted file mode 100644
index 6ba84ec..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_014.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_014.png
deleted file mode 100644
index 766610e..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_015.png b/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_015.png
deleted file mode 100644
index 810a029..0000000
--- a/core/res/res/drawable-xxhdpi/btn_check_to_on_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_000.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_000.png
deleted file mode 100644
index f0ff1a7..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_001.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_001.png
deleted file mode 100644
index b382df3..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_002.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_002.png
deleted file mode 100644
index 8cb4ce2..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_003.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_003.png
deleted file mode 100644
index 4db2b01..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_004.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_004.png
deleted file mode 100644
index 8c4709b..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_005.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_005.png
deleted file mode 100644
index 1ad960a..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_006.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_006.png
deleted file mode 100644
index e47cc20..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_007.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_007.png
deleted file mode 100644
index c4d0d51..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_008.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_008.png
deleted file mode 100644
index 915d56a..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_009.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_009.png
deleted file mode 100644
index 85795cb..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_010.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_010.png
deleted file mode 100644
index 157fd91..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_011.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_011.png
deleted file mode 100644
index 9d446de..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_012.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_012.png
deleted file mode 100644
index dfac1f0..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_013.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_013.png
deleted file mode 100644
index aed6c08..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_014.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_014.png
deleted file mode 100644
index 1b8bd6b..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_015.png b/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_015.png
deleted file mode 100644
index 5dd0e5b..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_off_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_000.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_000.png
deleted file mode 100644
index 5dd0e5b..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_000.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_001.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_001.png
deleted file mode 100644
index 1a31ad9..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_001.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_002.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_002.png
deleted file mode 100644
index 63c7f12..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_002.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_003.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_003.png
deleted file mode 100644
index 847dd08..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_003.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_004.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_004.png
deleted file mode 100644
index b93f3cc..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_004.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_005.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_005.png
deleted file mode 100644
index 1e3dea7..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_005.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_006.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_006.png
deleted file mode 100644
index 5a85238..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_006.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_007.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_007.png
deleted file mode 100644
index 35960ca..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_007.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_008.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_008.png
deleted file mode 100644
index 6db5555..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_008.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_009.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_009.png
deleted file mode 100644
index a9c5851..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_009.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_010.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_010.png
deleted file mode 100644
index 38465bd..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_010.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_011.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_011.png
deleted file mode 100644
index 15942dc..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_011.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_012.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_012.png
deleted file mode 100644
index 67d0d64..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_012.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_013.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_013.png
deleted file mode 100644
index 69b5c1b..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_013.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_014.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_014.png
deleted file mode 100644
index 0e5d331..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_014.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_015.png b/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_015.png
deleted file mode 100644
index f0ff1a7..0000000
--- a/core/res/res/drawable-xxxhdpi/btn_check_to_on_mtrl_015.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/btn_check_material_anim.xml b/core/res/res/drawable/btn_check_material_anim.xml
index 24df879..41caa4e 100644
--- a/core/res/res/drawable/btn_check_material_anim.xml
+++ b/core/res/res/drawable/btn_check_material_anim.xml
@@ -15,159 +15,15 @@
-->
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false" android:state_checked="true">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_015"
- android:tint="?attr/colorControlNormal"
- android:alpha="?attr/disabledAlpha" />
- </item>
- <item android:state_enabled="false">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_000"
- android:tint="?attr/colorControlNormal"
- android:alpha="?attr/disabledAlpha" />
- </item>
- <item android:state_checked="true" android:id="@+id/on">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_015"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:id="@+id/off">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_000"
- android:tint="?attr/colorControlNormal" />
- </item>
- <transition android:fromId="@+id/off" android:toId="@+id/on">
- <animation-list>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_000"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_001"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_002"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_003"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_004"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_005"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_006"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_007"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_008"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_009"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_010"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_011"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_012"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_013"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_014"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_on_mtrl_015"
- android:tint="?attr/colorControlActivated" />
- </item>
- </animation-list>
- </transition>
- <transition android:fromId="@+id/on" android:toId="@+id/off">
- <animation-list>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_000"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_001"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_002"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_003"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_004"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_005"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_006"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_007"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_008"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_009"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_010"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_011"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_012"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_013"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_014"
- android:tint="?attr/colorControlNormal" />
- </item>
- <item android:duration="15">
- <bitmap android:src="@drawable/btn_check_to_off_mtrl_015"
- android:tint="?attr/colorControlNormal" />
- </item>
- </animation-list>
- </transition>
+ <item android:state_checked="true" android:id="@+id/on"
+ android:drawable="@drawable/ic_checkbox_checked" />
+ <item android:id="@+id/off"
+ android:drawable="@drawable/ic_checkbox_unchecked" />
+
+ <transition android:fromId="@+id/off" android:toId="@+id/on"
+ android:drawable="@drawable/ic_checkbox_unchecked_animation" />
+
+ <transition android:fromId="@+id/on" android:toId="@+id/off"
+ android:drawable="@drawable/ic_checkbox_checked_animation" />
</animated-selector>
diff --git a/core/res/res/drawable/ic_checkbox_checked.xml b/core/res/res/drawable/ic_checkbox_checked.xml
new file mode 100644
index 0000000..4764115
--- /dev/null
+++ b/core/res/res/drawable/ic_checkbox_checked.xml
@@ -0,0 +1,52 @@
+<?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.
+-->
+
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="ic_checkbox_checked"
+ android:width="32dp"
+ android:viewportWidth="48"
+ android:height="32dp"
+ android:viewportHeight="48"
+ android:tint="?attr/colorControlNormal" >
+ <group
+ android:name="icon_null"
+ android:translateX="24"
+ android:translateY="24"
+ android:scaleX="0.2"
+ android:scaleY="0.2" >
+ <group
+ android:name="check"
+ android:scaleX="7.5"
+ android:scaleY="7.5" >
+ <path
+ android:name="check_path_merged"
+ android:pathData="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M -2.0,5.00001525879 c 0.0,0.0 -5.0,-5.00001525879 -5.0,-5.00001525879 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 3.58590698242,3.58601379395 3.58590698242,3.58601379395 c 0.0,0.0 7.58590698242,-7.58601379395 7.58590698242,-7.58601379395 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -9.0,9.00001525879 -9.0,9.00001525879 Z"
+ android:fillColor="#FF000000" />
+ </group>
+ <group
+ android:name="box_dilate"
+ android:scaleX="7.5"
+ android:scaleY="7.5" >
+ <path
+ android:name="box_inner_merged"
+ android:pathData="M 0.0,-1.0 l 0.0,0.0 c 0.5522847498,0.0 1.0,0.4477152502 1.0,1.0 l 0.0,0.0 c 0.0,0.5522847498 -0.4477152502,1.0 -1.0,1.0 l 0.0,0.0 c -0.5522847498,0.0 -1.0,-0.4477152502 -1.0,-1.0 l 0.0,0.0 c 0.0,-0.5522847498 0.4477152502,-1.0 1.0,-1.0 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:fillColor="#FF000000"
+ android:fillAlpha="0" />
+ </group>
+ </group>
+</vector>
diff --git a/core/res/res/drawable/ic_checkbox_checked_animation.xml b/core/res/res/drawable/ic_checkbox_checked_animation.xml
new file mode 100644
index 0000000..af5eeee
--- /dev/null
+++ b/core/res/res/drawable/ic_checkbox_checked_animation.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_checkbox_checked" >
+ <target
+ android:name="icon_null"
+ android:animation="@anim/ic_checkbox_checked_icon_null_animation" />
+ <target
+ android:name="check_path_merged"
+ android:animation="@anim/ic_checkbox_checked_check_path_merged_animation" />
+ <target
+ android:name="box_inner_merged"
+ android:animation="@anim/ic_checkbox_checked_box_inner_merged_animation" />
+</animated-vector>
diff --git a/core/res/res/drawable/ic_checkbox_unchecked.xml b/core/res/res/drawable/ic_checkbox_unchecked.xml
new file mode 100644
index 0000000..410f0bc
--- /dev/null
+++ b/core/res/res/drawable/ic_checkbox_unchecked.xml
@@ -0,0 +1,52 @@
+<?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.
+-->
+
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="ic_checkbox_unchecked"
+ android:width="32dp"
+ android:viewportWidth="48"
+ android:height="32dp"
+ android:viewportHeight="48"
+ android:tint="?attr/colorControlNormal" >
+ <group
+ android:name="icon_null"
+ android:translateX="24"
+ android:translateY="24"
+ android:scaleX="0.2"
+ android:scaleY="0.2" >
+ <group
+ android:name="check"
+ android:scaleX="7.5"
+ android:scaleY="7.5" >
+ <path
+ android:name="box_outer_merged"
+ android:pathData="M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M -2.0,5.00001525879 c 0.0,0.0 -1.4234161377,-1.40159606934 -1.4234161377,-1.40159606934 c 0.0,0.0 1.41409301758,-1.41409301758 1.41409301758,-1.41409301758 c 0.0,0.0 0.00932312011719,-0.0124053955078 0.00932312011719,-0.0124053955078 c 0.0,0.0 0.0234069824219,-0.0235137939453 0.0234069824219,-0.0235137939453 c 0.0,0.0 1.41409301758,1.41409301758 1.41409301758,1.41409301758 c 0.0,0.0 -1.4375,1.43751525879 -1.4375,1.43751525879 Z"
+ android:fillColor="#FF000000"
+ android:fillAlpha="0" />
+ </group>
+ <group
+ android:name="box_dilate"
+ android:scaleX="7.5"
+ android:scaleY="7.5" >
+ <path
+ android:name="box_inner_merged"
+ android:pathData="M -7.0,-7.0 l 14.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,14.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -14.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-14.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z M 7.0,-9.0 c 0.0,0.0 -14.0,0.0 -14.0,0.0 c -1.1044921875,0.0 -2.0,0.8955078125 -2.0,2.0 c 0.0,0.0 0.0,14.0 0.0,14.0 c 0.0,1.1044921875 0.8955078125,2.0 2.0,2.0 c 0.0,0.0 14.0,0.0 14.0,0.0 c 1.1044921875,0.0 2.0,-0.8955078125 2.0,-2.0 c 0.0,0.0 0.0,-14.0 0.0,-14.0 c 0.0,-1.1044921875 -0.8955078125,-2.0 -2.0,-2.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z"
+ android:fillColor="#FF000000" />
+ </group>
+ </group>
+</vector>
diff --git a/core/res/res/drawable/ic_checkbox_unchecked_animation.xml b/core/res/res/drawable/ic_checkbox_unchecked_animation.xml
new file mode 100644
index 0000000..605fce1
--- /dev/null
+++ b/core/res/res/drawable/ic_checkbox_unchecked_animation.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_checkbox_unchecked" >
+ <target
+ android:name="icon_null"
+ android:animation="@anim/ic_checkbox_unchecked_icon_null_animation" />
+ <target
+ android:name="box_outer_merged"
+ android:animation="@anim/ic_checkbox_unchecked_box_outer_merged_animation" />
+ <target
+ android:name="box_inner_merged"
+ android:animation="@anim/ic_checkbox_unchecked_box_inner_merged_animation" />
+</animated-vector>
diff --git a/core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_0.xml b/core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_0.xml
new file mode 100644
index 0000000..ceac663
--- /dev/null
+++ b/core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_0.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 l 1.0,0.0 l 0.0,1.0" />
diff --git a/core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_1.xml b/core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_1.xml
new file mode 100644
index 0000000..26bc8ad
--- /dev/null
+++ b/core/res/res/interpolator/ic_checkbox_checked_animation_interpolator_1.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.33333333,0.0 0.0,1.0 1.0,1.0" />
diff --git a/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_0.xml b/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_0.xml
new file mode 100644
index 0000000..ceac663
--- /dev/null
+++ b/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_0.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 l 1.0,0.0 l 0.0,1.0" />
diff --git a/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_1.xml b/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_1.xml
new file mode 100644
index 0000000..26bc8ad
--- /dev/null
+++ b/core/res/res/interpolator/ic_checkbox_unchecked_animation_interpolator_1.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.33333333,0.0 0.0,1.0 1.0,1.0" />
diff --git a/core/res/res/layout/floating_popup_container.xml b/core/res/res/layout/floating_popup_container.xml
new file mode 100644
index 0000000..f247919
--- /dev/null
+++ b/core/res/res/layout/floating_popup_container.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/floating_toolbar_height"
+ android:elevation="2dp"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:background="@android:color/background_light" />
diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml
new file mode 100644
index 0000000..9fa13bd
--- /dev/null
+++ b/core/res/res/layout/floating_popup_menu_button.xml
@@ -0,0 +1,31 @@
+<?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.
+*/
+-->
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="@dimen/floating_toolbar_menu_button_side_padding"
+ android:paddingLeft="@dimen/floating_toolbar_menu_button_side_padding"
+ android:paddingRight="@dimen/floating_toolbar_menu_button_side_padding"
+ android:paddingTop="0dp"
+ android:paddingBottom="0dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:fontFamily="sans-serif"
+ android:textSize="@dimen/floating_toolbar_text_size"
+ android:textAllCaps="true"
+ android:background="?attr/selectableItemBackground" /> \ No newline at end of file
diff --git a/core/res/res/layout/floating_popup_open_overflow_button.xml b/core/res/res/layout/floating_popup_open_overflow_button.xml
new file mode 100644
index 0000000..4c1176c
--- /dev/null
+++ b/core/res/res/layout/floating_popup_open_overflow_button.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="@dimen/floating_toolbar_menu_button_minimum_width"
+ android:layout_height="match_parent"
+ android:minWidth="@dimen/floating_toolbar_menu_button_minimum_width"
+ android:minHeight="@dimen/floating_toolbar_height"
+ android:src="@drawable/ic_menu_moreoverflow_material"
+ android:contentDescription="@string/action_menu_overflow_description"
+ android:background="?attr/selectableItemBackgroundBorderless" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0c61591..aed69ba 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Minute se sirkelglyer"</string>
<string name="select_hours" msgid="6043079511766008245">"Kies ure"</string>
<string name="select_minutes" msgid="3974345615920336087">"Kies minute"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Maandrooster van dae"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Jaarlys"</string>
<string name="select_day" msgid="7774759604701773332">"Kies maand en dag"</string>
<string name="select_year" msgid="7952052866994196170">"Kies jaar"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> gekies"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index b639b4f..f6b38ad 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"የደቂቃዎች ክብ ተንሸራታች"</string>
<string name="select_hours" msgid="6043079511766008245">"ሰዓታትን ይምረጡ"</string>
<string name="select_minutes" msgid="3974345615920336087">"ደቂቃዎችን ይምረጡ"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"የቀናት የወር ፍርግርግ"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"የዓመት ዝርዝር"</string>
<string name="select_day" msgid="7774759604701773332">"ወር እና ቀን ይምረጡ"</string>
<string name="select_year" msgid="7952052866994196170">"ዓመት ይምረጡ"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ተመርጧል"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 42bf57d..ddb0e4d 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1830,8 +1830,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"شريط التمرير الدائري للدقائق"</string>
<string name="select_hours" msgid="6043079511766008245">"تحديد الساعات"</string>
<string name="select_minutes" msgid="3974345615920336087">"تحديد الدقائق"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"شبكة الشهر مكونة من الأيام"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"قائمة الأعوام"</string>
<string name="select_day" msgid="7774759604701773332">"تحديد الشهر واليوم"</string>
<string name="select_year" msgid="7952052866994196170">"تحديد العام"</string>
<string name="item_is_selected" msgid="949687401682476608">"تم تحديد <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index ecfa7bd..efae80e 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Кръгов плъзгач за минутите"</string>
<string name="select_hours" msgid="6043079511766008245">"Избиране на часове"</string>
<string name="select_minutes" msgid="3974345615920336087">"Избиране на минути"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Месечна таблица на дните"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Списък с години"</string>
<string name="select_day" msgid="7774759604701773332">"Избиране на месец и ден"</string>
<string name="select_year" msgid="7952052866994196170">"Избиране на година"</string>
<string name="item_is_selected" msgid="949687401682476608">"Избрахте <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index f20e21f..c47a502 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"বৃত্তাকার মিনিট নির্বাচকের স্লাইডার"</string>
<string name="select_hours" msgid="6043079511766008245">"ঘন্টা নির্বাচন করুন"</string>
<string name="select_minutes" msgid="3974345615920336087">"মিনিট নির্বাচন করুন"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"দিন দিয়ে সংগঠিত মাসের গ্রিড"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"বছরের তালিকা"</string>
<string name="select_day" msgid="7774759604701773332">"মাস এবং দিন নির্বাচন করুন"</string>
<string name="select_year" msgid="7952052866994196170">"বছর নির্বাচন করুন"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> নির্বাচন করা হয়েছে"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index aebebf2..ed964e9 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Control circular dels minuts"</string>
<string name="select_hours" msgid="6043079511766008245">"Selecciona les hores"</string>
<string name="select_minutes" msgid="3974345615920336087">"Selecciona els minuts"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Graella mensual de dies"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Llista anual"</string>
<string name="select_day" msgid="7774759604701773332">"Selecciona un mes i un dia"</string>
<string name="select_year" msgid="7952052866994196170">"Selecciona un any"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionat"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 988818b..d7e86a5 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1812,8 +1812,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Kruhový posuvník minut"</string>
<string name="select_hours" msgid="6043079511766008245">"Zvolte hodiny"</string>
<string name="select_minutes" msgid="3974345615920336087">"Zvolte minuty"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Dny uspořádané po měsících"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Seznam roků"</string>
<string name="select_day" msgid="7774759604701773332">"Vyberte měsíc a den"</string>
<string name="select_year" msgid="7952052866994196170">"Vyberte rok"</string>
<string name="item_is_selected" msgid="949687401682476608">"Vybrána položka <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 20b7ad2..b97720d 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Cirkulær minutvælger"</string>
<string name="select_hours" msgid="6043079511766008245">"Vælg timer"</string>
<string name="select_minutes" msgid="3974345615920336087">"Vælg minutter"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Månedsgitter med dage"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Liste over år"</string>
<string name="select_day" msgid="7774759604701773332">"Vælg måned og dag"</string>
<string name="select_year" msgid="7952052866994196170">"Vælg år"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> er valgt"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 07153fe..227e20c 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -203,7 +203,7 @@
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flugmodus ist AN."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flugmodus ist AUS."</string>
<string name="global_action_settings" msgid="1756531602592545966">"Einstellungen"</string>
- <string name="global_action_assist" msgid="3892832961594295030">"Geräteassistent"</string>
+ <string name="global_action_assist" msgid="3892832961594295030">"Assistent"</string>
<string name="global_action_voice_assist" msgid="7751191495200504480">"Sprachassistent"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Jetzt sperren"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Kreisförmiger Schieberegler für Minuten"</string>
<string name="select_hours" msgid="6043079511766008245">"Stunden auswählen"</string>
<string name="select_minutes" msgid="3974345615920336087">"Minuten auswählen"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Monatsraster mit einzelnen Tagen"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Jahresliste"</string>
<string name="select_day" msgid="7774759604701773332">"Monat und Tag auswählen"</string>
<string name="select_year" msgid="7952052866994196170">"Jahr auswählen"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ausgewählt"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index e0a6f88..c3e1bb7 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Κυκλικό ρυθμιστικό λεπτών"</string>
<string name="select_hours" msgid="6043079511766008245">"Επιλογή ωρών"</string>
<string name="select_minutes" msgid="3974345615920336087">"Επιλογή λεπτών"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Πλέγμα ημερών του μήνα"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Λίστα ετών"</string>
<string name="select_day" msgid="7774759604701773332">"Επιλογή μήνα και ημέρας"</string>
<string name="select_year" msgid="7952052866994196170">"Επιλογή έτους"</string>
<string name="item_is_selected" msgid="949687401682476608">"Επιλέχτηκε το στοιχείο <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index f52daf6..bfcb90c 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Minutes circular slider"</string>
<string name="select_hours" msgid="6043079511766008245">"Select hours"</string>
<string name="select_minutes" msgid="3974345615920336087">"Select minutes"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Month grid of days"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Year list"</string>
<string name="select_day" msgid="7774759604701773332">"Select month and day"</string>
<string name="select_year" msgid="7952052866994196170">"Select year"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selected"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index f52daf6..bfcb90c 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Minutes circular slider"</string>
<string name="select_hours" msgid="6043079511766008245">"Select hours"</string>
<string name="select_minutes" msgid="3974345615920336087">"Select minutes"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Month grid of days"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Year list"</string>
<string name="select_day" msgid="7774759604701773332">"Select month and day"</string>
<string name="select_year" msgid="7952052866994196170">"Select year"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selected"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index f52daf6..bfcb90c 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Minutes circular slider"</string>
<string name="select_hours" msgid="6043079511766008245">"Select hours"</string>
<string name="select_minutes" msgid="3974345615920336087">"Select minutes"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Month grid of days"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Year list"</string>
<string name="select_day" msgid="7774759604701773332">"Select month and day"</string>
<string name="select_year" msgid="7952052866994196170">"Select year"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selected"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index ce419dc..78cc227 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Control deslizante circular de minutos"</string>
<string name="select_hours" msgid="6043079511766008245">"Seleccionar horas"</string>
<string name="select_minutes" msgid="3974345615920336087">"Seleccionar minutos"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Cuadrícula mensual de días"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Lista de años"</string>
<string name="select_day" msgid="7774759604701773332">"Seleccionar mes y día"</string>
<string name="select_year" msgid="7952052866994196170">"Seleccionar año"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionado"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index e22ea21..969881c 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Control deslizante circular de minutos"</string>
<string name="select_hours" msgid="6043079511766008245">"Seleccionar horas"</string>
<string name="select_minutes" msgid="3974345615920336087">"Seleccionar minutos"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Cuadrícula mensual de días"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Lista de años"</string>
<string name="select_day" msgid="7774759604701773332">"Seleccionar mes y día"</string>
<string name="select_year" msgid="7952052866994196170">"Seleccionar año"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionado"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 85b5c3c..72b13da 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Ringikujuline minutiliugur"</string>
<string name="select_hours" msgid="6043079511766008245">"Tundide valimine"</string>
<string name="select_minutes" msgid="3974345615920336087">"Minutite valimine"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Päevad kuu ruudustikus"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Aastate loend"</string>
<string name="select_day" msgid="7774759604701773332">"Kuu ja päeva valimine"</string>
<string name="select_year" msgid="7952052866994196170">"Aasta valimine"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> on valitud"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 02d8dd3..da96ec3 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Minutuak aukeratzeko ikuspegi zirkularra"</string>
<string name="select_hours" msgid="6043079511766008245">"Hautatu orduak"</string>
<string name="select_minutes" msgid="3974345615920336087">"Hautatu minutuak"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Hilabete-ikuspegiko eguna aukeratzeko sareta"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Urteen zerrenda"</string>
<string name="select_day" msgid="7774759604701773332">"Hautatu hilabetea eta eguna"</string>
<string name="select_year" msgid="7952052866994196170">"Hautatu urtea"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> hautatu da"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 2073b5e..1aa1cc8 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"لغزنده دایره‌ای دقیقه"</string>
<string name="select_hours" msgid="6043079511766008245">"انتخاب ساعت"</string>
<string name="select_minutes" msgid="3974345615920336087">"انتخاب دقیقه"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"جدول روزها براساس ماه"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"لیست سال‌ها"</string>
<string name="select_day" msgid="7774759604701773332">"انتخاب ماه و روز"</string>
<string name="select_year" msgid="7952052866994196170">"انتخاب سال"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> انتخاب شد"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index a2f1ccf..39860e3 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Minuuttien ympyränmuotoinen liukusäädin"</string>
<string name="select_hours" msgid="6043079511766008245">"Valitse tunnit"</string>
<string name="select_minutes" msgid="3974345615920336087">"Valitse minuutit"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Päiväruudukko kuukausittain"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Vuosiluettelo"</string>
<string name="select_day" msgid="7774759604701773332">"Valitse kuukausi ja päivä"</string>
<string name="select_year" msgid="7952052866994196170">"Valitse vuosi"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> on valittu"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 837b58a..4a3e4a1 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Curseur circulaire des minutes"</string>
<string name="select_hours" msgid="6043079511766008245">"Sélectionnez les heures"</string>
<string name="select_minutes" msgid="3974345615920336087">"Sélectionnez les minutes"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Calendrier mensuel sous forme de grille"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Liste des années"</string>
<string name="select_day" msgid="7774759604701773332">"Sélectionnez un mois et un jour"</string>
<string name="select_year" msgid="7952052866994196170">"Sélectionnez une année"</string>
<string name="item_is_selected" msgid="949687401682476608">"« <xliff:g id="ITEM">%1$s</xliff:g> » a été sélectionné"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index c6e1387..1713dd8 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Curseur circulaire des minutes"</string>
<string name="select_hours" msgid="6043079511766008245">"Sélectionner une heure"</string>
<string name="select_minutes" msgid="3974345615920336087">"Sélectionner des minutes"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Calendrier mensuel sous forme de grille"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Liste des années"</string>
<string name="select_day" msgid="7774759604701773332">"Sélectionner un mois et un jour"</string>
<string name="select_year" msgid="7952052866994196170">"Sélectionner une année"</string>
<string name="item_is_selected" msgid="949687401682476608">"\"<xliff:g id="ITEM">%1$s</xliff:g>\" sélectionné"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 5218ed5..e35d654 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Control de desprazamento circular dos minutos"</string>
<string name="select_hours" msgid="6043079511766008245">"Seleccionar horas"</string>
<string name="select_minutes" msgid="3974345615920336087">"Seleccionar minutos"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Grade mensual de días"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Lista de anos"</string>
<string name="select_day" msgid="7774759604701773332">"Seleccionar mes e día"</string>
<string name="select_year" msgid="7952052866994196170">"Seleccionar ano"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionado"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 6463cc5..53c395d 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1211,9 +1211,9 @@
<string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> चल रहा है"</string>
<string name="app_running_notification_text" msgid="4653586947747330058">"अधिक जानकारी के लिए या ऐप्स रोकने के लिए स्पर्श करें."</string>
<string name="ok" msgid="5970060430562524910">"ठीक है"</string>
- <string name="cancel" msgid="6442560571259935130">"रहने दें"</string>
+ <string name="cancel" msgid="6442560571259935130">"अभी नहीं"</string>
<string name="yes" msgid="5362982303337969312">"ठीक है"</string>
- <string name="no" msgid="5141531044935541497">"रहने दें"</string>
+ <string name="no" msgid="5141531044935541497">"अभी नहीं"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"ध्यान दें"</string>
<string name="loading" msgid="7933681260296021180">"लोड हो रहे हैं..."</string>
<string name="capital_on" msgid="1544682755514494298">"चालू"</string>
@@ -1335,7 +1335,7 @@
<string name="sms_short_code_details" msgid="5873295990846059400">"इससे आपके मोबाइल खाते पर "<b>"शुल्क लग सकता है"</b>"."</string>
<string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"इससे आपके मोबाइल खाते पर शुल्क लगेगा."</b></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"भेजें"</string>
- <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"रहने दें"</string>
+ <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"अभी नहीं"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"मेरी पसंद को याद रखें"</string>
<string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"आप इसे बाद में सेटिंग &gt; ऐप्स में बदल सकते हैं"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"हमेशा अनुमति दें"</string>
@@ -1545,7 +1545,7 @@
<string name="date_picker_increment_year_button" msgid="6318697384310808899">"वर्ष बढ़ाएं"</string>
<string name="date_picker_decrement_year_button" msgid="4482021813491121717">"वर्ष कम करें"</string>
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
- <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"रहने दें"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"अभी नहीं"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"हटाएं"</string>
<string name="keyboardview_keycode_done" msgid="1992571118466679775">"पूर्ण"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mode change"</string>
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"मिनटों का चक्राकार स्लाइडर"</string>
<string name="select_hours" msgid="6043079511766008245">"घंटे चुनें"</string>
<string name="select_minutes" msgid="3974345615920336087">"मिनट चुनें"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"दिनों की माह ग्रिड"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"वर्ष की सूची"</string>
<string name="select_day" msgid="7774759604701773332">"माह और दिन चुनें"</string>
<string name="select_year" msgid="7952052866994196170">"वर्ष चुनें"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> चयनित"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 0f39d7c..7d39eb8 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1803,8 +1803,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Kružni klizač minuta"</string>
<string name="select_hours" msgid="6043079511766008245">"Odaberite sate"</string>
<string name="select_minutes" msgid="3974345615920336087">"Odaberite minute"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Mreža dana u mjesecu"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Popis godina"</string>
<string name="select_day" msgid="7774759604701773332">"Odaberite mjesec i dan"</string>
<string name="select_year" msgid="7952052866994196170">"Odaberite godinu"</string>
<string name="item_is_selected" msgid="949687401682476608">"Odabrana je stavka <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index adada44..9a9bfb3 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Perc kör alakú csúszkája"</string>
<string name="select_hours" msgid="6043079511766008245">"Óra kiválasztása"</string>
<string name="select_minutes" msgid="3974345615920336087">"Perc kiválasztása"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Napok havi leosztásban"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Évek listája"</string>
<string name="select_day" msgid="7774759604701773332">"Válassza ki a hónapot és a napot"</string>
<string name="select_year" msgid="7952052866994196170">"Válassza ki az évet"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> kiválasztva"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 65bacf7..1b5dfaa 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Րոպեների ընտրություն թվատախտակից"</string>
<string name="select_hours" msgid="6043079511766008245">"Ընտրեք ժամը"</string>
<string name="select_minutes" msgid="3974345615920336087">"Ընտրեք րոպեն"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Ամսաթվի ընտրության պատուհան"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Տարիների ցանկ"</string>
<string name="select_day" msgid="7774759604701773332">"Ընտրեք ամիսն ու օրը"</string>
<string name="select_year" msgid="7952052866994196170">"Ընտրեք տարին"</string>
<string name="item_is_selected" msgid="949687401682476608">"Ընտրված է <xliff:g id="ITEM">%1$s</xliff:g> տարրը"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 2f7cb25..b0deed2 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Penggeser putar menit"</string>
<string name="select_hours" msgid="6043079511766008245">"Pilih jam"</string>
<string name="select_minutes" msgid="3974345615920336087">"Pilih menit"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Kisi hari pada bulan"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Daftar tahun"</string>
<string name="select_day" msgid="7774759604701773332">"Pilih bulan dan hari"</string>
<string name="select_year" msgid="7952052866994196170">"Pilih tahun"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> dipilih"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index a926d3d..5538c00 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Valskífa fyrir mínútur"</string>
<string name="select_hours" msgid="6043079511766008245">"Veldu klukkustundir"</string>
<string name="select_minutes" msgid="3974345615920336087">"Veldu mínútur"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Mánaðartafla með dögum"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Áralisti"</string>
<string name="select_day" msgid="7774759604701773332">"Veldu mánuð og dag"</string>
<string name="select_year" msgid="7952052866994196170">"Veldu ár"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> valið"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 74ad5f7..d8dd2ea 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Dispositivo di scorrimento circolare per i minuti"</string>
<string name="select_hours" msgid="6043079511766008245">"Seleziona le ore"</string>
<string name="select_minutes" msgid="3974345615920336087">"Seleziona i minuti"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Griglia di giorni per mese"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Elenco degli anni"</string>
<string name="select_day" msgid="7774759604701773332">"Seleziona mese e giorno"</string>
<string name="select_year" msgid="7952052866994196170">"Seleziona anno"</string>
<string name="item_is_selected" msgid="949687401682476608">"Elemento selezionato: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 1e8d680..1839b45 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1812,8 +1812,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"מחוון דקות מעגלי"</string>
<string name="select_hours" msgid="6043079511766008245">"בחר שעות"</string>
<string name="select_minutes" msgid="3974345615920336087">"בחר דקות"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"בחירת ימים בחודש בתצוגת רשת"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"רשימת שנים"</string>
<string name="select_day" msgid="7774759604701773332">"בחר חודש ויום"</string>
<string name="select_year" msgid="7952052866994196170">"בחר שנה"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> נבחר"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 5598018..613a2f1 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"円形スライダー(分)"</string>
<string name="select_hours" msgid="6043079511766008245">"時間を選択"</string>
<string name="select_minutes" msgid="3974345615920336087">"分を選択"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"日グリッド(月別)"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"年リスト"</string>
<string name="select_day" msgid="7774759604701773332">"月と日を選択"</string>
<string name="select_year" msgid="7952052866994196170">"年を選択"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g>を選択しました"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index d179c28..befe9e7 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"წუთების წრიული სლაიდერი"</string>
<string name="select_hours" msgid="6043079511766008245">"აირჩიეთ საათები"</string>
<string name="select_minutes" msgid="3974345615920336087">"აირჩიეთ წუთები"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"დღეების ბადე თვეზე"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"წლის სია"</string>
<string name="select_day" msgid="7774759604701773332">"აირჩიეთ თვე და რიცხვი"</string>
<string name="select_year" msgid="7952052866994196170">"აირჩიეთ წელი"</string>
<string name="item_is_selected" msgid="949687401682476608">"არჩეულია <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index caa12d2..8b19127 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Минут айналымын қозғалтқыш"</string>
<string name="select_hours" msgid="6043079511766008245">"Сағат таңдау"</string>
<string name="select_minutes" msgid="3974345615920336087">"Минут таңдау"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Күндердің айлық торлары"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Жыл тізімі"</string>
<string name="select_day" msgid="7774759604701773332">"Ай мен күнді таңдау"</string>
<string name="select_year" msgid="7952052866994196170">"Жыл таңдау"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> таңдалды"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 3326462..12c9661 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -1796,8 +1796,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"គ្រាប់​រំកិល​រង្វង់​នាទី"</string>
<string name="select_hours" msgid="6043079511766008245">"ជ្រើស​ម៉ោង"</string>
<string name="select_minutes" msgid="3974345615920336087">"ជ្រើស​នាទី"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"ក្រឡា​​​ខែ​នៃ​ថ្ងៃ"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"បញ្ជី​ឆ្នាំ"</string>
<string name="select_day" msgid="7774759604701773332">"ជ្រើស​ខែ និង​ថ្ងៃ"</string>
<string name="select_year" msgid="7952052866994196170">"ជ្រើស​ឆ្នាំ"</string>
<string name="item_is_selected" msgid="949687401682476608">"បាន​ជ្រើស <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 2bd45d4..2f967ea 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"ನಿಮಿಷಗಳ ವೃತ್ತಾಕಾರ ಸ್ಲೈಡರ್"</string>
<string name="select_hours" msgid="6043079511766008245">"ಗಂಟೆಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="select_minutes" msgid="3974345615920336087">"ನಿಮಿಷಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"ದಿನಗಳ ತಿಂಗಳಿನ ಗ್ರಿಡ್"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"ವರ್ಷದ ಪಟ್ಟಿ"</string>
<string name="select_day" msgid="7774759604701773332">"ತಿಂಗಳು ಮತ್ತು ದಿನವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="select_year" msgid="7952052866994196170">"ವರ್ಷವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ಆಯ್ಕೆ ಮಾಡಲಾಗಿದೆ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 463f84d..654fffb 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"분 원형 슬라이더"</string>
<string name="select_hours" msgid="6043079511766008245">"시간 선택"</string>
<string name="select_minutes" msgid="3974345615920336087">"분 선택"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"월별 바둑판식 날짜 표시"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"년"</string>
<string name="select_day" msgid="7774759604701773332">"월/일 선택"</string>
<string name="select_year" msgid="7952052866994196170">"연도 선택"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g>이(가) 선택됨"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index fdfc442..5905240 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -2309,8 +2309,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Мүнөт жебеси"</string>
<string name="select_hours" msgid="6043079511766008245">"Саатты тандаңыз"</string>
<string name="select_minutes" msgid="3974345615920336087">"Мүнөттөрдү тандаңыз"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Айдын күндөрү"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Жыл тизмеги"</string>
<string name="select_day" msgid="7774759604701773332">"Ай жана күндү тандаңыз"</string>
<string name="select_year" msgid="7952052866994196170">"Жылды тандаңыз"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> тандалды"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index e565c00..c932d2d 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"ໂຕໝຸນປັບນາທີ"</string>
<string name="select_hours" msgid="6043079511766008245">"ເລືອກ​ຊົ່ວ​ໂມງ"</string>
<string name="select_minutes" msgid="3974345615920336087">"ເລືອກນາ​ທີ"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"ຕາຕາລາງວັນທີເດືອນປີ"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"ລາຍການປີ"</string>
<string name="select_day" msgid="7774759604701773332">"ເລືອກເດືອນ ແລະ ວັນ"</string>
<string name="select_year" msgid="7952052866994196170">"ເລືອກ​ປີ"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ຖືກເລືອກແລ້ວ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 099593c..42b7770 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1812,8 +1812,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Apskritas minučių slankiklis"</string>
<string name="select_hours" msgid="6043079511766008245">"Pasirinkite valandas"</string>
<string name="select_minutes" msgid="3974345615920336087">"Pasirinkite minutes"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Mėnesio dienų tinklelis"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Metų sąrašas"</string>
<string name="select_day" msgid="7774759604701773332">"Pasirinkite mėnesį ir dieną"</string>
<string name="select_year" msgid="7952052866994196170">"Pasirinkite metus"</string>
<string name="item_is_selected" msgid="949687401682476608">"Pasirinkta: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 9ab2772..1be0eeb 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1803,8 +1803,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Minūšu apļveida slīdnis"</string>
<string name="select_hours" msgid="6043079511766008245">"Atlasiet stundas."</string>
<string name="select_minutes" msgid="3974345615920336087">"Atlasiet minūtes."</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Režģis ar mēneša dienām"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Gadu saraksts"</string>
<string name="select_day" msgid="7774759604701773332">"Atlasiet mēnesi un dienu."</string>
<string name="select_year" msgid="7952052866994196170">"Atlasiet gadu."</string>
<string name="item_is_selected" msgid="949687401682476608">"Atlasīts: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-mcc310-mnc260/strings.xml b/core/res/res/values-mcc310-mnc260/strings.xml
index 5cadc2a..75b1b53 100644
--- a/core/res/res/values-mcc310-mnc260/strings.xml
+++ b/core/res/res/values-mcc310-mnc260/strings.xml
@@ -29,4 +29,6 @@
<string-array name="wfcOperatorErrorMessages">
<item>Wi-Fi Calling isn\&apos;t available. Contact your carrier to enable Wi-Fi Calling.</item>
</string-array>
+ <!-- Template for showing cellular network operator name while WFC is active -->
+ <string name="wfcSpnFormat">%s Wi-Fi Calling</string>
</resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 2080d50..387238e 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -1796,8 +1796,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Приказ на минути во кружно движење"</string>
<string name="select_hours" msgid="6043079511766008245">"Избери часови"</string>
<string name="select_minutes" msgid="3974345615920336087">"Избери минути"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Рамка на месец со денови"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Список по години"</string>
<string name="select_day" msgid="7774759604701773332">"Избери месец и ден"</string>
<string name="select_year" msgid="7952052866994196170">"Избери година"</string>
<string name="item_is_selected" msgid="949687401682476608">"Избрано <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 2ae1177..68fd869 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"ചാക്രികമായി മിനിറ്റുകൾ ദൃശ്യമാകുന്ന സ്ലൈഡർ"</string>
<string name="select_hours" msgid="6043079511766008245">"മണിക്കൂർ തിരഞ്ഞെടുക്കുക"</string>
<string name="select_minutes" msgid="3974345615920336087">"മിനിറ്റ് തിരഞ്ഞെടുക്കുക"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"മാസപ്രകാരമുള്ള ദിവസ ഗ്രിഡ്"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"വർഷങ്ങളുടെ ലിസ്റ്റ്"</string>
<string name="select_day" msgid="7774759604701773332">"മാസവും ദിവസവും തിരഞ്ഞെടുക്കുക"</string>
<string name="select_year" msgid="7952052866994196170">"വർഷം തിരഞ്ഞെടുക്കുക"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> തിരഞ്ഞെടുത്തു"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 4a8b5b9..07fb9a9 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Минут гүйлгэгч"</string>
<string name="select_hours" msgid="6043079511766008245">"Цаг сонгоно уу"</string>
<string name="select_minutes" msgid="3974345615920336087">"Минут сонгоно уу"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Өдрүүдийг сараар"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Жилийн жагсаалт"</string>
<string name="select_day" msgid="7774759604701773332">"Сар болон өдрийг сонгоно уу"</string>
<string name="select_year" msgid="7952052866994196170">"Жилийг сонгоно уу"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> сонгогдсон"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 3fc5663..737154e 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"मिनिटे परिपत्रक स्लायडर"</string>
<string name="select_hours" msgid="6043079511766008245">"तास निवडा"</string>
<string name="select_minutes" msgid="3974345615920336087">"मिनिटे निवडा"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"दिवसांची महिना ग्रिड"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"वर्ष सूची"</string>
<string name="select_day" msgid="7774759604701773332">"महिना आणि दिवस निवडा"</string>
<string name="select_year" msgid="7952052866994196170">"वर्ष निवडा"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> निवडले"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index d849680..10d5d5f 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Penggelangsar bulatan minit"</string>
<string name="select_hours" msgid="6043079511766008245">"Pilih jam"</string>
<string name="select_minutes" msgid="3974345615920336087">"Pilih minit"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Grid hari bulanan"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Senarai tahun"</string>
<string name="select_day" msgid="7774759604701773332">"Pilih bulan dan hari"</string>
<string name="select_year" msgid="7952052866994196170">"Pilih tahun"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> dipilih"</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 36a6cde..f97c576 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"မိနစ်လှည့်သော ရွေ့လျားတန်"</string>
<string name="select_hours" msgid="6043079511766008245">"နာရီများ ရွေးပါ"</string>
<string name="select_minutes" msgid="3974345615920336087">"မိနစ်များ ရွေးပါ"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"လအလိုက် ရွေးနိုင်သော ရက်များ"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"ခုနှစ် အစဉ်"</string>
<string name="select_day" msgid="7774759604701773332">"လ နှင့် ရက် ရွေးပါ"</string>
<string name="select_year" msgid="7952052866994196170">"ခုနှစ်ကို ရွေးပါ"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ခုရွေးချယ်ထားပြီး"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 022bb16..3b45940 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Sirkulær glidebryter for minutter"</string>
<string name="select_hours" msgid="6043079511766008245">"Angi timer"</string>
<string name="select_minutes" msgid="3974345615920336087">"Angi minutter"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Månedsrutenett med dager"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Årsliste"</string>
<string name="select_day" msgid="7774759604701773332">"Velg måneden og dagen"</string>
<string name="select_year" msgid="7952052866994196170">"Velg året"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> er valgt"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 54fe0e5..907047f 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -1800,8 +1800,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"मिनेट गोलाकार स्लाइडर"</string>
<string name="select_hours" msgid="6043079511766008245">"घण्टा चयन गर्नुहोस्"</string>
<string name="select_minutes" msgid="3974345615920336087">"मिनेट चयन गर्नुहोस्"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"दिनहरुको महिना ग्रिड"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"वर्ष सूची"</string>
<string name="select_day" msgid="7774759604701773332">"महिना र दिन चयन गर्नुहोस्"</string>
<string name="select_year" msgid="7952052866994196170">"वर्ष चयन गर्नुहोस्"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> चयन गरियो"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 3318bff..d6c02f5 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Ronde schuifregelaar voor minuten"</string>
<string name="select_hours" msgid="6043079511766008245">"Uren selecteren"</string>
<string name="select_minutes" msgid="3974345615920336087">"Minuten selecteren"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Maandraster van dagen"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Jaarlijst"</string>
<string name="select_day" msgid="7774759604701773332">"Maand en dag selecteren"</string>
<string name="select_year" msgid="7952052866994196170">"Jaar selecteren"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> geselecteerd"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 4e56e90..8e31053 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1812,8 +1812,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Kołowy suwak minut"</string>
<string name="select_hours" msgid="6043079511766008245">"Wybierz godziny"</string>
<string name="select_minutes" msgid="3974345615920336087">"Wybierz minuty"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Siatka miesięczna z dniami"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Lista lat"</string>
<string name="select_day" msgid="7774759604701773332">"Wybierz miesiąc i dzień"</string>
<string name="select_year" msgid="7952052866994196170">"Wybierz rok"</string>
<string name="item_is_selected" msgid="949687401682476608">"Wybrałeś <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 1ddef71..7a0985c 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Controlo de deslize circular dos minutos"</string>
<string name="select_hours" msgid="6043079511766008245">"Selecionar horas"</string>
<string name="select_minutes" msgid="3974345615920336087">"Selecionar minutos"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Grelha de dias do mês"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Lista de anos"</string>
<string name="select_day" msgid="7774759604701773332">"Selecionar mês e dia"</string>
<string name="select_year" msgid="7952052866994196170">"Selecionar ano"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selecionado"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 35ae345..8f86b40 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Controle deslizante circular dos minutos"</string>
<string name="select_hours" msgid="6043079511766008245">"Selecione as horas"</string>
<string name="select_minutes" msgid="3974345615920336087">"Selecione os minutos"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Grade mensal de dias"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Lista de anos"</string>
<string name="select_day" msgid="7774759604701773332">"Selecione o mês e o dia"</string>
<string name="select_year" msgid="7952052866994196170">"Selecione o ano"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selecionado"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 360b966..6246941 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1803,8 +1803,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Selector circular pentru minute"</string>
<string name="select_hours" msgid="6043079511766008245">"Selectați orele"</string>
<string name="select_minutes" msgid="3974345615920336087">"Selectați minutele"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Afișare pe luni"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Listă de ani"</string>
<string name="select_day" msgid="7774759604701773332">"Selectați luna și ziua"</string>
<string name="select_year" msgid="7952052866994196170">"Selectați anul"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selectat"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 5aa3b39..21cc5b7 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1812,8 +1812,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Выбор минут на циферблате"</string>
<string name="select_hours" msgid="6043079511766008245">"Выберите часы"</string>
<string name="select_minutes" msgid="3974345615920336087">"Выберите минуты"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Окно выбора даты"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Меню выбора года"</string>
<string name="select_day" msgid="7774759604701773332">"Выберите месяц и число"</string>
<string name="select_year" msgid="7952052866994196170">"Выберите год"</string>
<string name="item_is_selected" msgid="949687401682476608">"Выбран элемент <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 8a83db9..1b9b317 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -1796,8 +1796,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"මිනිත්තු කවාකාර සර්පනය"</string>
<string name="select_hours" msgid="6043079511766008245">"පැය තෝරන්න"</string>
<string name="select_minutes" msgid="3974345615920336087">"මිනිත්තු තෝරන්න"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"දින ජාලයකින් මාසය"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"වසර ලැයිස්තුව"</string>
<string name="select_day" msgid="7774759604701773332">"මාසය සහ දිනය තෝරන්න"</string>
<string name="select_year" msgid="7952052866994196170">"වසර තෝරන්න"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> තෝරාගෙන ඇත"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 676ffe2..c46fc93 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1812,8 +1812,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Kruhový posúvač minút"</string>
<string name="select_hours" msgid="6043079511766008245">"Vyberte hodiny"</string>
<string name="select_minutes" msgid="3974345615920336087">"Vyberte minúty"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Tabuľka dní v mesiaci"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Zoznam rokov"</string>
<string name="select_day" msgid="7774759604701773332">"Vyberte mesiac a deň"</string>
<string name="select_year" msgid="7952052866994196170">"Vyberte rok"</string>
<string name="item_is_selected" msgid="949687401682476608">"Bola vybratá položka <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 07d4bb7..a42b022 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1812,8 +1812,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Okrogli drsnik za minute"</string>
<string name="select_hours" msgid="6043079511766008245">"Izberite ure"</string>
<string name="select_minutes" msgid="3974345615920336087">"Izberite minute"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Mesečna mreža dni"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Seznam let"</string>
<string name="select_day" msgid="7774759604701773332">"Izberite mesec in dan"</string>
<string name="select_year" msgid="7952052866994196170">"Izberite leto"</string>
<string name="item_is_selected" msgid="949687401682476608">"Izbrano: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 54da9a4..7e2f18e 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1803,8 +1803,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Кружни клизач за минуте"</string>
<string name="select_hours" msgid="6043079511766008245">"Изаберите сате"</string>
<string name="select_minutes" msgid="3974345615920336087">"Изаберите минуте"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Приказ дана у месецу у виду мреже"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Листа година"</string>
<string name="select_day" msgid="7774759604701773332">"Изаберите месец и дан"</string>
<string name="select_year" msgid="7952052866994196170">"Изаберите годину"</string>
<string name="item_is_selected" msgid="949687401682476608">"Изабрали сте <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index dd8a883..326842c 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Cirkelreglage för minuter"</string>
<string name="select_hours" msgid="6043079511766008245">"Välj timmar"</string>
<string name="select_minutes" msgid="3974345615920336087">"Välj minuter"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Rutnät för månad"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Lista över år"</string>
<string name="select_day" msgid="7774759604701773332">"Välj månad och dag"</string>
<string name="select_year" msgid="7952052866994196170">"Välj år"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> har markerats"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index cfa56de..d681855 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Kitelezi cha mviringo wa dakika"</string>
<string name="select_hours" msgid="6043079511766008245">"Chagua saa"</string>
<string name="select_minutes" msgid="3974345615920336087">"Chagua dakika"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Gridi ya mwezi ya siku"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Orodha ya miaka"</string>
<string name="select_day" msgid="7774759604701773332">"Chagua mwezi na siku"</string>
<string name="select_year" msgid="7952052866994196170">"Chagua mwaka"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> kimechaguliwa"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 0e5bf3c..086fe6a 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"நிமிடங்களுக்கான வட்டவடிவ ஸ்லைடர்"</string>
<string name="select_hours" msgid="6043079511766008245">"மணிநேரத்தைத் தேர்ந்தெடுக்கவும்"</string>
<string name="select_minutes" msgid="3974345615920336087">"நிமிடத்தைத் தேர்ந்தெடுக்கவும்"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"நாட்களின் மாதக் கட்டம்"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"ஆண்டு பட்டியல்"</string>
<string name="select_day" msgid="7774759604701773332">"மாதம் மற்றும் தேதியைத் தேர்ந்தெடுக்கவும்"</string>
<string name="select_year" msgid="7952052866994196170">"ஆண்டைத் தேர்ந்தெடுக்கவும்"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> தேர்ந்தெடுக்கப்பட்டது"</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 4684adf..5f59597 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"నిమిషాల వృత్తాకార స్లయిడర్"</string>
<string name="select_hours" msgid="6043079511766008245">"గంటలను ఎంచుకోండి"</string>
<string name="select_minutes" msgid="3974345615920336087">"నిమిషాలను ఎంచుకోండి"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"రోజుల యొక్క నెల గ్రిడ్"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"సంవత్సర జాబితా"</string>
<string name="select_day" msgid="7774759604701773332">"నెల మరియు రోజును ఎంచుకోండి"</string>
<string name="select_year" msgid="7952052866994196170">"సంవత్సరాన్ని ఎంచుకోండి"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ఎంచుకోబడింది"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 39be8c7..df4ff52 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"ตัวเลื่อนหมุนระบุนาที"</string>
<string name="select_hours" msgid="6043079511766008245">"เลือกชั่วโมง"</string>
<string name="select_minutes" msgid="3974345615920336087">"เลือกนาที"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"ตารางเดือนของวัน"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"รายการปี"</string>
<string name="select_day" msgid="7774759604701773332">"เลือกเดือนและวัน"</string>
<string name="select_year" msgid="7952052866994196170">"เลือกปี"</string>
<string name="item_is_selected" msgid="949687401682476608">"เลือก <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 95a1480..41480ed 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Pabilog na slider ng mga minuto"</string>
<string name="select_hours" msgid="6043079511766008245">"Pumili ng mga oras"</string>
<string name="select_minutes" msgid="3974345615920336087">"Pumili ng mga minuto"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Grid ng mga araw ayon sa buwan"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Listahan ng taon"</string>
<string name="select_day" msgid="7774759604701773332">"Pumili ng buwan at araw"</string>
<string name="select_year" msgid="7952052866994196170">"Pumili ng taon"</string>
<string name="item_is_selected" msgid="949687401682476608">"Napili ang <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 373ef66..f254b5c 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Dakika kaydırma çemberi"</string>
<string name="select_hours" msgid="6043079511766008245">"Saati seçin"</string>
<string name="select_minutes" msgid="3974345615920336087">"Dakikayı seçin"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Ayın günleri tablosu"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Yıl listesi"</string>
<string name="select_day" msgid="7774759604701773332">"Ayı ve günü seçin"</string>
<string name="select_year" msgid="7952052866994196170">"Yılı seçin"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seçildi"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index c3cfe6d..78beaf5 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1812,8 +1812,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Вибір хвилин на циферблаті"</string>
<string name="select_hours" msgid="6043079511766008245">"Виберіть години"</string>
<string name="select_minutes" msgid="3974345615920336087">"Виберіть хвилини"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Вікно вибору дати"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Меню вибору року"</string>
<string name="select_day" msgid="7774759604701773332">"Виберіть місяць і день"</string>
<string name="select_year" msgid="7952052866994196170">"Виберіть рік"</string>
<string name="item_is_selected" msgid="949687401682476608">"Вибрано: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index f315112..4f604aa 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"منٹس سرکلر سلائیڈر"</string>
<string name="select_hours" msgid="6043079511766008245">"گھنٹے منتخب کریں"</string>
<string name="select_minutes" msgid="3974345615920336087">"منٹ منتخب کریں"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"دنوں کا ماہ کا گرڈ"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"سال کی فہرست"</string>
<string name="select_day" msgid="7774759604701773332">"ماہ اور دن منتخب کریں"</string>
<string name="select_year" msgid="7952052866994196170">"سال منتخب کریں"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> کو منتخب کیا گیا"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 78bad61..dc90c25 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Doiradan daqiqani tanlang"</string>
<string name="select_hours" msgid="6043079511766008245">"Soatlarni tanlash"</string>
<string name="select_minutes" msgid="3974345615920336087">"Daqiqalarni tanlash"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Oy kunlari (jadval ko‘rinishida)"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Yil ro‘yxati"</string>
<string name="select_day" msgid="7774759604701773332">"Oy va kunni tanlash"</string>
<string name="select_year" msgid="7952052866994196170">"Yilni tanlash"</string>
<string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> tanlandi"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index a2ebfd4..5031e85 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Thanh trượt phút hình tròn"</string>
<string name="select_hours" msgid="6043079511766008245">"Chọn giờ"</string>
<string name="select_minutes" msgid="3974345615920336087">"Chọn phút"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Lưới ngày theo tháng"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Danh sách năm"</string>
<string name="select_day" msgid="7774759604701773332">"Chọn tháng và ngày"</string>
<string name="select_year" msgid="7952052866994196170">"Chọn năm"</string>
<string name="item_is_selected" msgid="949687401682476608">"Đã chọn <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index e7c6bee..d8631a6 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"分钟转盘"</string>
<string name="select_hours" msgid="6043079511766008245">"选择小时"</string>
<string name="select_minutes" msgid="3974345615920336087">"选择分钟"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"按月份划分的日期网格"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"年份列表"</string>
<string name="select_day" msgid="7774759604701773332">"选择月份和日期"</string>
<string name="select_year" msgid="7952052866994196170">"选择年份"</string>
<string name="item_is_selected" msgid="949687401682476608">"已选择<xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index a62cf11..9b9e945 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"分鐘環形滑桿"</string>
<string name="select_hours" msgid="6043079511766008245">"選取小時"</string>
<string name="select_minutes" msgid="3974345615920336087">"選取分鐘"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"顯示每日的月曆方格"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"年份清單"</string>
<string name="select_day" msgid="7774759604701773332">"選取月份和日期"</string>
<string name="select_year" msgid="7952052866994196170">"選取年份"</string>
<string name="item_is_selected" msgid="949687401682476608">"已選取<xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 5d1821a..323ccc3 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"分鐘數環狀滑桿"</string>
<string name="select_hours" msgid="6043079511766008245">"選取小時數"</string>
<string name="select_minutes" msgid="3974345615920336087">"選取分鐘數"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"日期網格 (按月顯示)"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"年份清單"</string>
<string name="select_day" msgid="7774759604701773332">"選取月份和日期"</string>
<string name="select_year" msgid="7952052866994196170">"選取年份"</string>
<string name="item_is_selected" msgid="949687401682476608">"已選取 <xliff:g id="ITEM">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 4c3a400..ec68b17 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1794,8 +1794,6 @@
<string name="minute_picker_description" msgid="8606010966873791190">"Amaminithi weslayidi esiyindingilizi"</string>
<string name="select_hours" msgid="6043079511766008245">"Khetha amahora"</string>
<string name="select_minutes" msgid="3974345615920336087">"Khetha amaminithi"</string>
- <string name="day_picker_description" msgid="8990847925961297968">"Igridi yenyanga yezinsuku"</string>
- <string name="year_picker_description" msgid="5524331207436052403">"Uhlu lonyaka"</string>
<string name="select_day" msgid="7774759604701773332">"Khetha inyanga nosuku"</string>
<string name="select_year" msgid="7952052866994196170">"Khetha unyaka"</string>
<string name="item_is_selected" msgid="949687401682476608">"I-<xliff:g id="ITEM">%1$s</xliff:g> ekhethiwe"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index b5576c5..79a6bde 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2633,6 +2633,70 @@
<enum name="paddedBounds" value="3" />
</attr>
+ <!-- Defines the drawable to draw over the content. This can be used as an overlay.
+ The foreground drawable participates in the padding of the content if the gravity
+ is set to fill. -->
+ <attr name="foreground" format="reference|color" />
+ <!-- Defines the gravity to apply to the foreground drawable. The gravity defaults
+ to fill. -->
+ <attr name="foregroundGravity">
+ <!-- Push object to the top of its container, not changing its size. -->
+ <flag name="top" value="0x30" />
+ <!-- Push object to the bottom of its container, not changing its size. -->
+ <flag name="bottom" value="0x50" />
+ <!-- Push object to the left of its container, not changing its size. -->
+ <flag name="left" value="0x03" />
+ <!-- Push object to the right of its container, not changing its size. -->
+ <flag name="right" value="0x05" />
+ <!-- Place object in the vertical center of its container, not changing its size. -->
+ <flag name="center_vertical" value="0x10" />
+ <!-- Grow the vertical size of the object if needed so it completely fills its container. -->
+ <flag name="fill_vertical" value="0x70" />
+ <!-- Place object in the horizontal center of its container, not changing its size. -->
+ <flag name="center_horizontal" value="0x01" />
+ <!-- Grow the horizontal size of the object if needed so it completely fills its container. -->
+ <flag name="fill_horizontal" value="0x07" />
+ <!-- Place the object in the center of its container in both the vertical and horizontal axis, not changing its size. -->
+ <flag name="center" value="0x11" />
+ <!-- Grow the horizontal and vertical size of the object if needed so it completely fills its container. -->
+ <flag name="fill" value="0x77" />
+ <!-- Additional option that can be set to have the top and/or bottom edges of
+ the child clipped to its container's bounds.
+ The clip will be based on the vertical gravity: a top gravity will clip the bottom
+ edge, a bottom gravity will clip the top edge, and neither will clip both edges. -->
+ <flag name="clip_vertical" value="0x80" />
+ <!-- Additional option that can be set to have the left and/or right edges of
+ the child clipped to its container's bounds.
+ The clip will be based on the horizontal gravity: a left gravity will clip the right
+ edge, a right gravity will clip the left edge, and neither will clip both edges. -->
+ <flag name="clip_horizontal" value="0x08" />
+ </attr>
+ <!-- Defines whether the foreground drawable should be drawn inside the padding.
+ This property is turned on by default. -->
+ <attr name="foregroundInsidePadding" format="boolean" />
+ <!-- Tint to apply to the foreground. -->
+ <attr name="foregroundTint" format="color" />
+ <!-- Blending mode used to apply the foreground tint. -->
+ <attr name="foregroundTintMode">
+ <!-- The tint is drawn on top of the drawable.
+ [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+ <enum name="src_over" value="3" />
+ <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+ color channels are thrown out. [Sa * Da, Sc * Da] -->
+ <enum name="src_in" value="5" />
+ <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+ channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+ <enum name="src_atop" value="9" />
+ <!-- Multiplies the color and alpha channels of the drawable with those of
+ the tint. [Sa * Da, Sc * Dc] -->
+ <enum name="multiply" value="14" />
+ <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+ <enum name="screen" value="15" />
+ <!-- Combines the tint and drawable color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
+ </attr>
+
</declare-styleable>
<!-- Attributes that can be assigned to a tag for a particular View. -->
@@ -3366,72 +3430,9 @@
<attr name="padding" />
</declare-styleable>
<declare-styleable name="FrameLayout">
- <!-- Defines the drawable to draw over the content. This can be used as an overlay.
- The foreground drawable participates in the padding of the content if the gravity
- is set to fill. -->
- <attr name="foreground" format="reference|color" />
- <!-- Defines the gravity to apply to the foreground drawable. The gravity defaults
- to fill. -->
- <attr name="foregroundGravity">
- <!-- Push object to the top of its container, not changing its size. -->
- <flag name="top" value="0x30" />
- <!-- Push object to the bottom of its container, not changing its size. -->
- <flag name="bottom" value="0x50" />
- <!-- Push object to the left of its container, not changing its size. -->
- <flag name="left" value="0x03" />
- <!-- Push object to the right of its container, not changing its size. -->
- <flag name="right" value="0x05" />
- <!-- Place object in the vertical center of its container, not changing its size. -->
- <flag name="center_vertical" value="0x10" />
- <!-- Grow the vertical size of the object if needed so it completely fills its container. -->
- <flag name="fill_vertical" value="0x70" />
- <!-- Place object in the horizontal center of its container, not changing its size. -->
- <flag name="center_horizontal" value="0x01" />
- <!-- Grow the horizontal size of the object if needed so it completely fills its container. -->
- <flag name="fill_horizontal" value="0x07" />
- <!-- Place the object in the center of its container in both the vertical and horizontal axis, not changing its size. -->
- <flag name="center" value="0x11" />
- <!-- Grow the horizontal and vertical size of the object if needed so it completely fills its container. -->
- <flag name="fill" value="0x77" />
- <!-- Additional option that can be set to have the top and/or bottom edges of
- the child clipped to its container's bounds.
- The clip will be based on the vertical gravity: a top gravity will clip the bottom
- edge, a bottom gravity will clip the top edge, and neither will clip both edges. -->
- <flag name="clip_vertical" value="0x80" />
- <!-- Additional option that can be set to have the left and/or right edges of
- the child clipped to its container's bounds.
- The clip will be based on the horizontal gravity: a left gravity will clip the right
- edge, a right gravity will clip the left edge, and neither will clip both edges. -->
- <flag name="clip_horizontal" value="0x08" />
- </attr>
- <!-- Defines whether the foreground drawable should be drawn inside the padding.
- This property is turned on by default. -->
- <attr name="foregroundInsidePadding" format="boolean" />
<!-- Determines whether to measure all children or just those in
the VISIBLE or INVISIBLE state when measuring. Defaults to false. -->
<attr name="measureAllChildren" format="boolean" />
- <!-- Tint to apply to the foreground. -->
- <attr name="foregroundTint" format="color" />
- <!-- Blending mode used to apply the foreground tint. -->
- <attr name="foregroundTintMode">
- <!-- The tint is drawn on top of the drawable.
- [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
- <enum name="src_over" value="3" />
- <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
- color channels are thrown out. [Sa * Da, Sc * Da] -->
- <enum name="src_in" value="5" />
- <!-- The tint is drawn above the drawable, but with the drawable’s alpha
- channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
- <enum name="src_atop" value="9" />
- <!-- Multiplies the color and alpha channels of the drawable with those of
- the tint. [Sa * Da, Sc * Dc] -->
- <enum name="multiply" value="14" />
- <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
- <enum name="screen" value="15" />
- <!-- Combines the tint and drawable color and alpha channels, clamping the
- result to valid color values. Saturate(S + D) -->
- <enum name="add" value="16" />
- </attr>
</declare-styleable>
<declare-styleable name="ExpandableListView">
<!-- Indicator shown beside the group View. This can be a stateful Drawable. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index aefb67c..283c237 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -389,13 +389,12 @@
with the same {@link android.R.attr#taskAffinity} as it has. -->
<attr name="allowTaskReparenting" format="boolean" />
- <!-- Declare that this application may use cleartext traffic (e.g., HTTP rather than HTTPS;
- WebSockets rather than WebSockets Secure; XMPP, IMAP, STMP without STARTTLS or TLS).
- Defaults to true. If set to false {@code false}, the app declares that it does not
- intend to use cleartext network traffic, in which case platform components (e.g.,
- HTTP stacks, {@code WebView}, {@code MediaPlayer}) will refuse app's requests to use
- cleartext traffic. Third-party libraries are encouraged to honor this flag as well.
- @hide -->
+ <!-- Declare that this application may use cleartext traffic, such as HTTP rather than HTTPS;
+ WebSockets rather than WebSockets Secure; XMPP, IMAP, STMP without STARTTLS or TLS.
+ Defaults to true. If set to false {@code false}, the application declares that it does not
+ intend to use cleartext network traffic, in which case platform components (e.g. HTTP
+ stacks, {@code WebView}, {@code MediaPlayer}) will refuse applications's requests to use
+ cleartext traffic. Third-party libraries are encouraged to honor this flag as well. -->
<attr name="usesCleartextTraffic" format="boolean" />
<!-- Declare that code from this application will need to be loaded into other
@@ -1164,13 +1163,13 @@
"com.google". -->
<attr name="requiredAccountType" format="string"/>
<attr name="isGame" />
- <!-- Declare that this application may use cleartext traffic (e.g., HTTP rather than HTTPS;
- WebSockets rather than WebSockets Secure; XMPP, IMAP, STMP without STARTTLS or TLS).
- Defaults to true. If set to false {@code false}, the app declares that it does not
- intend to use cleartext network traffic, in which case platform components (e.g.,
- HTTP stacks, {@code WebView}, {@code MediaPlayer}) will refuse app's requests to use
- cleartext traffic. Third-party libraries are encouraged to honor this flag as well.
- @hide -->
+ <!-- Declare that this application may use cleartext traffic, such as HTTP rather than
+ HTTPS; WebSockets rather than WebSockets Secure; XMPP, IMAP, STMP without STARTTLS or
+ TLS). Defaults to true. If set to false {@code false}, the application declares that it
+ does not intend to use cleartext network traffic, in which case platform components
+ (e.g. HTTP stacks, {@code WebView}, {@code MediaPlayer}) will refuse applications's
+ requests to use cleartext traffic. Third-party libraries are encouraged to honor this
+ flag as well. -->
<attr name="usesCleartextTraffic" />
<attr name="multiArch" />
<attr name="extractNativeLibs" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 37c9598..1b2e952 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1112,6 +1112,18 @@
device does not support multiple advertisement-->
<integer translatable="false" name="config_bluetooth_max_advertisers">0</integer>
+ <!-- Idle current for bluetooth controller. 0 by default-->
+ <integer translatable="false" name="config_bluetooth_idle_cur_ma">1</integer>
+
+ <!-- Rx current for bluetooth controller. 0 by default-->
+ <integer translatable="false" name="config_bluetooth_rx_cur_ma">2</integer>
+
+ <!-- Tx current for bluetooth controller. 0 by default-->
+ <integer translatable="false" name="config_bluetooth_tx_cur_ma">3</integer>
+
+ <!-- Operating volatage for bluetooth controller. 0 by default-->
+ <integer translatable="false" name="config_bluetooth_operating_voltage_mv">4</integer>
+
<!-- The default data-use polling period. -->
<integer name="config_datause_polling_period_sec">600</integer>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 6c6d2cc..3431f35 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -386,4 +386,11 @@
<item type="dimen" format="float" name="ambient_shadow_alpha">0.075</item>
<item type="dimen" format="float" name="spot_shadow_alpha">0.15</item>
+ <!-- Floating toolbar dimensions -->
+ <dimen name="floating_toolbar_height">48dp</dimen>
+ <dimen name="floating_toolbar_menu_button_side_padding">8dp</dimen>
+ <dimen name="floating_toolbar_text_size">14sp</dimen>
+ <dimen name="floating_toolbar_menu_button_minimum_width">48dp</dimen>
+ <dimen name="floating_toolbar_default_width">250dp</dimen>
+ <dimen name="floating_toolbar_minimum_overflow_height">192dp</dimen>
</resources>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 6108b27..7e963954 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -93,4 +93,5 @@
<item type="id" name="undo" />
<item type="id" name="redo" />
<item type="id" name="replaceText" />
+ <item type="id" name="accessibility_action_show_on_screen" />
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 5e4b039..ef7bfaf 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2652,4 +2652,5 @@
<public type="attr" name="colorBackgroundFloating" />
<public type="attr" name="extractNativeLibs" />
+ <public type="attr" name="usesCleartextTraffic" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7672e93..88225bd 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -251,6 +251,8 @@
<string-array name="wfcOperatorErrorCodes" translatable="false" />
<!-- WFC Operator Error Messages -->
<string-array name="wfcOperatorErrorMessages" />
+ <!-- Template for showing cellular network operator name while WFC is active -->
+ <string name="wfcSpnFormat">%s</string>
<!--
{0} is one of "bearerServiceCode*"
@@ -2226,6 +2228,36 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_useFingerprint">Allows the app to use fingerprint hardware for authentication</string>
+ <!-- Message shown during fingerprint acquisision when the fingerprint cannot be recognized -->
+ <string name="fingerprint_acquired_partial">Partial fingerprint detected. Please try again.</string>
+ <!-- Message shown during fingerprint acquisision when the fingerprint cannot be recognized -->
+ <string name="fingerprint_acquired_insufficient">Couldn\'t process fingerprint. Please try again.</string>
+ <!-- Message shown during fingerprint acquisision when the fingerprint sensor needs cleaning -->
+ <string name="fingerprint_acquired_imager_dirty">Fingerprint sensor is dirty. Please clean and try again.</string>
+ <!-- Message shown during fingerprint acquisision when the user removes their finger from the sensor too quickly -->
+ <string name="fingerprint_acquired_too_fast">Finger moved to fast. Please try again.</string>
+ <!-- Message shown during fingerprint acquisision when the user moves their finger too slowly -->
+ <string name="fingerprint_acquired_too_slow">Finger moved to slow. Please try again.</string>
+ <!-- Array containing custom messages shown during fingerprint acquisision from vendor. Vendor is expected to add and translate these strings -->
+ <string-array name="fingerprint_acquired_vendor">
+ <item>Vendor-specific acquisition error message 0</item>
+ </string-array>
+
+ <!-- Generic error message shown when the fingerprint hardware can't recognize the fingerprint -->
+ <string name="fingerprint_error_unable_to_process">Unable to process. Try again.</string>
+ <!-- Error message shown when the fingerprint hardware can't be accessed -->
+ <string name="fingerprint_error_hw_not_available">Hardware not available.</string>
+ <!-- Error message shown when the fingerprint hardware has run out of room for storing fingerprints -->
+ <string name="fingerprint_error_no_space">Fingerprint can\'t be stored. Please remove an existing fingerprint.</string>
+ <!-- Error message shown when the fingerprint hardware timer has expired and the user needs to restart the operation. -->
+ <string name="fingerprint_error_timeout">Fingerprint time out reached. Try again.</string>
+ <!-- Error message shown when the fingerprint hardware timer has expired and the user needs to restart the operation. -->
+ <string name="fingerprint_error_vendor">Fingerprint time out reached. Try again.</string>
+ <!-- Array containing custom error messages from vendor. Vendor is expected to add and translate these strings -->
+ <string-array name="fingerprint_error_vendor">
+ <item>Vendor-specifc error message.</item>
+ </string-array>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readSyncSettings">read sync settings</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c4e9e8e..67d5472 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -349,6 +349,10 @@
<java-symbol type="integer" name="config_burnInProtectionMinVerticalOffset" />
<java-symbol type="integer" name="config_burnInProtectionMaxVerticalOffset" />
<java-symbol type="integer" name="config_burnInProtectionMaxRadius" />
+ <java-symbol type="integer" name="config_bluetooth_idle_cur_ma" />
+ <java-symbol type="integer" name="config_bluetooth_rx_cur_ma" />
+ <java-symbol type="integer" name="config_bluetooth_tx_cur_ma" />
+ <java-symbol type="integer" name="config_bluetooth_operating_voltage_mv" />
<java-symbol type="integer" name="config_cursorWindowSize" />
<java-symbol type="integer" name="config_drawLockTimeoutMillis" />
<java-symbol type="integer" name="config_doublePressOnPowerBehavior" />
@@ -756,6 +760,7 @@
<java-symbol type="string" name="wfcRegErrorTitle" />
<java-symbol type="array" name="wfcOperatorErrorCodes" />
<java-symbol type="array" name="wfcOperatorErrorMessages" />
+ <java-symbol type="string" name="wfcSpnFormat" />
<java-symbol type="string" name="policydesc_disableCamera" />
<java-symbol type="string" name="policydesc_encryptedStorage" />
<java-symbol type="string" name="policydesc_expirePassword" />
@@ -2061,6 +2066,19 @@
<!-- From KeyguardServiceDelegate -->
<java-symbol type="string" name="config_keyguardComponent" />
+ <!-- Fingerprint messages -->
+ <java-symbol type="string" name="fingerprint_error_unable_to_process" />
+ <java-symbol type="string" name="fingerprint_error_hw_not_available" />
+ <java-symbol type="string" name="fingerprint_error_no_space" />
+ <java-symbol type="string" name="fingerprint_error_timeout" />
+ <java-symbol type="array" name="fingerprint_error_vendor" />
+ <java-symbol type="string" name="fingerprint_acquired_partial" />
+ <java-symbol type="string" name="fingerprint_acquired_insufficient" />
+ <java-symbol type="string" name="fingerprint_acquired_imager_dirty" />
+ <java-symbol type="string" name="fingerprint_acquired_too_slow" />
+ <java-symbol type="string" name="fingerprint_acquired_too_fast" />
+ <java-symbol type="array" name="fingerprint_acquired_vendor" />
+
<!-- From various Material changes -->
<java-symbol type="attr" name="titleTextAppearance" />
<java-symbol type="attr" name="subtitleTextAppearance" />
@@ -2174,4 +2192,17 @@
<java-symbol type="style" name="TextAppearance.Material.Widget.Calendar.Day" />
<java-symbol type="dimen" name="day_picker_padding_top"/>
<java-symbol type="dimen" name="date_picker_day_of_week_height"/>
+
+ <java-symbol type="id" name="accessibility_action_show_on_screen" />
+
+ <!-- Floating toolbar -->
+ <java-symbol type="layout" name="floating_popup_container" />
+ <java-symbol type="layout" name="floating_popup_menu_button" />
+ <java-symbol type="layout" name="floating_popup_open_overflow_button" />
+ <java-symbol type="dimen" name="floating_toolbar_height" />
+ <java-symbol type="dimen" name="floating_toolbar_menu_button_side_padding" />
+ <java-symbol type="dimen" name="floating_toolbar_text_size" />
+ <java-symbol type="dimen" name="floating_toolbar_menu_button_minimum_width" />
+ <java-symbol type="dimen" name="floating_toolbar_default_width" />
+ <java-symbol type="dimen" name="floating_toolbar_minimum_overflow_height" />
</resources>
diff --git a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
new file mode 100644
index 0000000..1a50432
--- /dev/null
+++ b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
@@ -0,0 +1,82 @@
+/*
+ * 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.net;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+public class NetworkStatsBenchmark extends SimpleBenchmark {
+ private static final String UNDERLYING_IFACE = "wlan0";
+ private static final String TUN_IFACE = "tun0";
+ private static final int TUN_UID = 999999999;
+
+ @Param({"100", "1000"})
+ private int mSize;
+ private NetworkStats mNetworkStats;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mNetworkStats = new NetworkStats(0, mSize + 2);
+ int uid = 0;
+ NetworkStats.Entry recycle = new NetworkStats.Entry();
+ for (int i = 0; i < mSize; i++) {
+ recycle.iface = (i < mSize / 2) ? TUN_IFACE : UNDERLYING_IFACE;
+ recycle.uid = uid;
+ recycle.set = i % 2;
+ recycle.tag = NetworkStats.TAG_NONE;
+ recycle.rxBytes = 60000;
+ recycle.rxPackets = 60;
+ recycle.txBytes = 150000;
+ recycle.txPackets = 1500;
+ recycle.operations = 0;
+ mNetworkStats.addValues(recycle);
+ if (recycle.set == 1) {
+ uid++;
+ }
+ }
+ recycle.iface = UNDERLYING_IFACE;
+ recycle.uid = TUN_UID;
+ recycle.set = NetworkStats.SET_FOREGROUND;
+ recycle.tag = NetworkStats.TAG_NONE;
+ recycle.rxBytes = 90000 * mSize;
+ recycle.rxPackets = 40 * mSize;
+ recycle.txBytes = 180000 * mSize;
+ recycle.txPackets = 1200 * mSize;
+ recycle.operations = 0;
+ mNetworkStats.addValues(recycle);
+ }
+
+ public void timeMigrateTun(int reps) {
+ for (int i = 0; i < reps; i++) {
+ NetworkStats stats = mNetworkStats.clone();
+ stats.migrateTun(TUN_UID, TUN_IFACE, UNDERLYING_IFACE);
+ }
+ }
+
+ /**
+ * Since timeMigrateTun() includes a clone() call on the NetworkStats object,
+ * we need to measure the cost of the clone() call itself in order to get more
+ * accurate measurement on the migrateTun() method.
+ */
+ public void timeClone(int reps) {
+ for (int i = 0; i < reps; i++) {
+ NetworkStats stats = mNetworkStats.clone();
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index fd922a2..a470de1 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -18,6 +18,8 @@ package android.net;
import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.SET_FOREGROUND;
+import static android.net.NetworkStats.SET_DBG_VPN_IN;
+import static android.net.NetworkStats.SET_DBG_VPN_OUT;
import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.TAG_NONE;
@@ -346,7 +348,7 @@ public class NetworkStatsTest extends TestCase {
.addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface));
- assertEquals(17, delta.size());
+ assertEquals(21, delta.size());
// tunIface and TEST_IFACE entries are not changed.
assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE,
@@ -377,14 +379,33 @@ public class NetworkStatsTest extends TestCase {
0L, 0L, 0L, 0L, 0L);
// New entries are added for new application's underlying Iface traffic
- assertValues(delta, 13, underlyingIface, 10120, SET_DEFAULT, TAG_NONE,
+ assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE,
72667L, 197L, 41872l, 219L, 0L);
- assertValues(delta, 14, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE,
+ assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE,
9297L, 17L, 3936, 19L, 0L);
- assertValues(delta, 15, underlyingIface, 10120, SET_DEFAULT, testTag1,
+ assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1,
21691L, 41L, 13179L, 46L, 0L);
- assertValues(delta, 16, underlyingIface, 10120, SET_FOREGROUND, testTag1,
+ assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1,
1281L, 2L, 634L, 1L, 0L);
+
+ // New entries are added for debug purpose
+ assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE,
+ 39605L, 46L, 11690, 49, 0);
+ assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE,
+ 81964, 214, 45808, 238, 0);
+ assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_IN, TAG_NONE,
+ 4983, 10, 1717, 10, 0);
+ assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE,
+ 126552, 270, 59215, 297, 0);
+
+ }
+
+ private static void assertContains(NetworkStats stats, String iface, int uid, int set,
+ int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
+ int index = stats.findIndex(iface, uid, set, tag);
+ assertTrue(index != -1);
+ assertValues(stats, index, iface, uid, set, tag,
+ rxBytes, rxPackets, txBytes, txPackets, operations);
}
private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set,