Merge "Align AndroidKeyStore API with user auth API." into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 2bf91a4..1117623 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23,8 +23,10 @@
field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE";
field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
+ field public static final java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
+ field public static final java.lang.String BIND_INCALL_SERVICE = "android.permission.BIND_INCALL_SERVICE";
field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
field public static final java.lang.String BIND_MEDIA_ROUTE_SERVICE = "android.permission.BIND_MEDIA_ROUTE_SERVICE";
field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
@@ -278,7 +280,7 @@
field public static final int allowParallelSyncs = 16843570; // 0x1010332
field public static final int allowSingleTap = 16843353; // 0x1010259
field public static final int allowTaskReparenting = 16843268; // 0x1010204
- field public static final int allowUndo = 16844006; // 0x10104e6
+ field public static final int allowUndo = 16844005; // 0x10104e5
field public static final int alpha = 16843551; // 0x101031f
field public static final int alphabeticShortcut = 16843235; // 0x10101e3
field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef
@@ -299,7 +301,7 @@
field public static final int anyDensity = 16843372; // 0x101026c
field public static final int apduServiceBanner = 16843757; // 0x10103ed
field public static final int apiKey = 16843281; // 0x1010211
- field public static final int assistBlocked = 16844020; // 0x10104f4
+ field public static final int assistBlocked = 16844019; // 0x10104f3
field public static final int author = 16843444; // 0x10102b4
field public static final int authorities = 16842776; // 0x1010018
field public static final int autoAdvanceViewId = 16843535; // 0x101030f
@@ -310,7 +312,7 @@
field public static final int autoStart = 16843445; // 0x10102b5
field public static final deprecated int autoText = 16843114; // 0x101016a
field public static final int autoUrlDetect = 16843404; // 0x101028c
- field public static final int autoVerify = 16844010; // 0x10104ea
+ field public static final int autoVerify = 16844009; // 0x10104e9
field public static final int background = 16842964; // 0x10100d4
field public static final int backgroundDimAmount = 16842802; // 0x1010032
field public static final int backgroundDimEnabled = 16843295; // 0x101021f
@@ -334,7 +336,7 @@
field public static final int bottomRightRadius = 16843180; // 0x10101ac
field public static final int breadCrumbShortTitle = 16843524; // 0x1010304
field public static final int breadCrumbTitle = 16843523; // 0x1010303
- field public static final int breakStrategy = 16844011; // 0x10104eb
+ field public static final int breakStrategy = 16844010; // 0x10104ea
field public static final int bufferType = 16843086; // 0x101014e
field public static final int button = 16843015; // 0x1010107
field public static final int buttonBarButtonStyle = 16843567; // 0x101032f
@@ -396,7 +398,7 @@
field public static final int colorActivatedHighlight = 16843664; // 0x1010390
field public static final int colorBackground = 16842801; // 0x1010031
field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
- field public static final int colorBackgroundFloating = 16844007; // 0x10104e7
+ field public static final int colorBackgroundFloating = 16844006; // 0x10104e6
field public static final int colorButtonNormal = 16843819; // 0x101042b
field public static final int colorControlActivated = 16843818; // 0x101042a
field public static final int colorControlHighlight = 16843820; // 0x101042c
@@ -505,7 +507,7 @@
field public static final int dropDownWidth = 16843362; // 0x1010262
field public static final int duplicateParentState = 16842985; // 0x10100e9
field public static final int duration = 16843160; // 0x1010198
- field public static final int dynamicResources = 16844019; // 0x10104f3
+ field public static final int dynamicResources = 16844018; // 0x10104f2
field public static final int editTextBackground = 16843602; // 0x1010352
field public static final int editTextColor = 16843601; // 0x1010351
field public static final int editTextPreferenceStyle = 16842898; // 0x1010092
@@ -517,7 +519,7 @@
field public static final int ellipsize = 16842923; // 0x10100ab
field public static final int ems = 16843096; // 0x1010158
field public static final int enabled = 16842766; // 0x101000e
- field public static final int end = 16843997; // 0x10104dd
+ field public static final int end = 16843996; // 0x10104dc
field public static final int endColor = 16843166; // 0x101019e
field public static final deprecated int endYear = 16843133; // 0x101017d
field public static final int enterFadeDuration = 16843532; // 0x101030c
@@ -539,7 +541,7 @@
field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
field public static final int exported = 16842768; // 0x1010010
field public static final int extraTension = 16843371; // 0x101026b
- field public static final int extractNativeLibs = 16844008; // 0x10104e8
+ field public static final int extractNativeLibs = 16844007; // 0x10104e7
field public static final int factor = 16843219; // 0x10101d3
field public static final int fadeDuration = 16843384; // 0x1010278
field public static final int fadeEnabled = 16843390; // 0x101027e
@@ -653,8 +655,8 @@
field public static final int host = 16842792; // 0x1010028
field public static final int icon = 16842754; // 0x1010002
field public static final int iconPreview = 16843337; // 0x1010249
- field public static final int iconTint = 16844000; // 0x10104e0
- field public static final int iconTintMode = 16844001; // 0x10104e1
+ field public static final int iconTint = 16843999; // 0x10104df
+ field public static final int iconTintMode = 16844000; // 0x10104e0
field public static final int iconifiedByDefault = 16843514; // 0x10102fa
field public static final int id = 16842960; // 0x10100d0
field public static final int ignoreGravity = 16843263; // 0x10101ff
@@ -794,7 +796,7 @@
field public static final int layout_x = 16843135; // 0x101017f
field public static final int layout_y = 16843136; // 0x1010180
field public static final int left = 16843181; // 0x10101ad
- field public static final int leftIndents = 16844016; // 0x10104f0
+ field public static final int leftIndents = 16844015; // 0x10104ef
field public static final int letterSpacing = 16843958; // 0x10104b6
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
@@ -817,7 +819,7 @@
field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208
field public static final int listViewStyle = 16842868; // 0x1010074
field public static final int listViewWhiteStyle = 16842869; // 0x1010075
- field public static final int lockTaskMode = 16844015; // 0x10104ef
+ field public static final int lockTaskMode = 16844014; // 0x10104ee
field public static final int logo = 16843454; // 0x10102be
field public static final int longClickable = 16842982; // 0x10100e6
field public static final int loopViews = 16843527; // 0x1010307
@@ -866,8 +868,8 @@
field public static final int navigationContentDescription = 16843969; // 0x10104c1
field public static final int navigationIcon = 16843968; // 0x10104c0
field public static final int navigationMode = 16843471; // 0x10102cf
- field public static final int navigationTint = 16844004; // 0x10104e4
- field public static final int navigationTintMode = 16844005; // 0x10104e5
+ field public static final int navigationTint = 16844003; // 0x10104e3
+ field public static final int navigationTintMode = 16844004; // 0x10104e4
field public static final int negativeButtonText = 16843254; // 0x10101f6
field public static final int nestedScrollingEnabled = 16843830; // 0x1010436
field public static final int nextFocusDown = 16842980; // 0x10100e4
@@ -881,7 +883,7 @@
field public static final int numColumns = 16843032; // 0x1010118
field public static final int numStars = 16843076; // 0x1010144
field public static final int numbersBackgroundColor = 16843938; // 0x10104a2
- field public static final int numbersInnerTextColor = 16843999; // 0x10104df
+ field public static final int numbersInnerTextColor = 16843998; // 0x10104de
field public static final int numbersSelectorColor = 16843939; // 0x10104a3
field public static final int numbersTextColor = 16843937; // 0x10104a1
field public static final deprecated int numeric = 16843109; // 0x1010165
@@ -899,8 +901,8 @@
field public static final int overScrollFooter = 16843459; // 0x10102c3
field public static final int overScrollHeader = 16843458; // 0x10102c2
field public static final int overScrollMode = 16843457; // 0x10102c1
- field public static final int overflowTint = 16844002; // 0x10104e2
- field public static final int overflowTintMode = 16844003; // 0x10104e3
+ field public static final int overflowTint = 16844001; // 0x10104e1
+ field public static final int overflowTintMode = 16844002; // 0x10104e2
field public static final int overlapAnchor = 16843874; // 0x1010462
field public static final int overridesImplicitlyEnabledSubtype = 16843682; // 0x10103a2
field public static final int packageNames = 16843649; // 0x1010381
@@ -995,7 +997,7 @@
field public static final int readPermission = 16842759; // 0x1010007
field public static final int recognitionService = 16843932; // 0x101049c
field public static final int relinquishTaskIdentity = 16843894; // 0x1010476
- field public static final int removeBeforeMRelease = 16844014; // 0x10104ee
+ field public static final int removeBeforeMRelease = 16844013; // 0x10104ed
field public static final int reparent = 16843964; // 0x10104bc
field public static final int reparentWithOverlay = 16843965; // 0x10104bd
field public static final int repeatCount = 16843199; // 0x10101bf
@@ -1014,7 +1016,6 @@
field public static final int resizeClip = 16843983; // 0x10104cf
field public static final int resizeMode = 16843619; // 0x1010363
field public static final int resizeable = 16843405; // 0x101028d
- field public static final int resizeableActivity = 16843995; // 0x10104db
field public static final int resource = 16842789; // 0x1010025
field public static final int restoreAnyVersion = 16843450; // 0x10102ba
field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
@@ -1024,7 +1025,7 @@
field public static final int reversible = 16843851; // 0x101044b
field public static final int revisionCode = 16843989; // 0x10104d5
field public static final int right = 16843183; // 0x10101af
- field public static final int rightIndents = 16844017; // 0x10104f1
+ field public static final int rightIndents = 16844016; // 0x10104f0
field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
field public static final int ringtoneType = 16843257; // 0x10101f9
field public static final int rotation = 16843558; // 0x1010326
@@ -1100,7 +1101,7 @@
field public static final int showAsAction = 16843481; // 0x10102d9
field public static final int showDefault = 16843258; // 0x10101fa
field public static final int showDividers = 16843561; // 0x1010329
- field public static final int showForAllUsers = 16844018; // 0x10104f2
+ field public static final int showForAllUsers = 16844017; // 0x10104f1
field public static final deprecated int showOnLockScreen = 16843721; // 0x10103c9
field public static final int showSilent = 16843259; // 0x10101fb
field public static final int showText = 16843949; // 0x10104ad
@@ -1130,7 +1131,7 @@
field public static final int stackFromBottom = 16843005; // 0x10100fd
field public static final int stackViewStyle = 16843838; // 0x101043e
field public static final int starStyle = 16842882; // 0x1010082
- field public static final int start = 16843996; // 0x10104dc
+ field public static final int start = 16843995; // 0x10104db
field public static final int startColor = 16843165; // 0x101019d
field public static final int startDelay = 16843746; // 0x10103e2
field public static final int startOffset = 16843198; // 0x10101be
@@ -1186,7 +1187,7 @@
field public static final int summaryColumn = 16843426; // 0x10102a2
field public static final int summaryOff = 16843248; // 0x10101f0
field public static final int summaryOn = 16843247; // 0x10101ef
- field public static final int supportsAssistGesture = 16844012; // 0x10104ec
+ field public static final int supportsAssistGesture = 16844011; // 0x10104eb
field public static final int supportsRtl = 16843695; // 0x10103af
field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
field public static final int supportsUploading = 16843419; // 0x101029b
@@ -1287,7 +1288,7 @@
field public static final int thicknessRatio = 16843164; // 0x101019c
field public static final int thumb = 16843074; // 0x1010142
field public static final int thumbOffset = 16843075; // 0x1010143
- field public static final int thumbPosition = 16844013; // 0x10104ed
+ field public static final int thumbPosition = 16844012; // 0x10104ec
field public static final int thumbTextPadding = 16843634; // 0x1010372
field public static final int thumbTint = 16843889; // 0x1010471
field public static final int thumbTintMode = 16843890; // 0x1010472
@@ -1351,7 +1352,7 @@
field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
field public static final int useLevel = 16843167; // 0x101019f
field public static final int userVisible = 16843409; // 0x1010291
- field public static final int usesCleartextTraffic = 16844009; // 0x10104e9
+ field public static final int usesCleartextTraffic = 16844008; // 0x10104e8
field public static final int value = 16842788; // 0x1010024
field public static final int valueFrom = 16843486; // 0x10102de
field public static final int valueTo = 16843487; // 0x10102df
@@ -1416,10 +1417,10 @@
field public static final int windowExitTransition = 16843832; // 0x1010438
field public static final int windowFrame = 16842837; // 0x1010055
field public static final int windowFullscreen = 16843277; // 0x101020d
- field public static final int windowHasLightStatusBar = 16843998; // 0x10104de
field public static final int windowHideAnimation = 16842935; // 0x10100b7
field public static final int windowIsFloating = 16842839; // 0x1010057
field public static final int windowIsTranslucent = 16842840; // 0x1010058
+ field public static final int windowLightStatusBar = 16843997; // 0x10104dd
field public static final int windowMinWidthMajor = 16843606; // 0x1010356
field public static final int windowMinWidthMinor = 16843607; // 0x1010357
field public static final int windowNoDisplay = 16843294; // 0x101021e
@@ -5729,6 +5730,7 @@
method public int getPasswordMinimumSymbols(android.content.ComponentName);
method public int getPasswordMinimumUpperCase(android.content.ComponentName);
method public int getPasswordQuality(android.content.ComponentName);
+ method public int getPermissionPolicy(android.content.ComponentName);
method public java.util.List<java.lang.String> getPermittedAccessibilityServices(android.content.ComponentName);
method public java.util.List<java.lang.String> getPermittedInputMethods(android.content.ComponentName);
method public boolean getScreenCaptureDisabled(android.content.ComponentName);
@@ -5781,6 +5783,8 @@
method public void setPasswordMinimumSymbols(android.content.ComponentName, int);
method public void setPasswordMinimumUpperCase(android.content.ComponentName, int);
method public void setPasswordQuality(android.content.ComponentName, int);
+ method public boolean setPermissionGranted(android.content.ComponentName, java.lang.String, java.lang.String, boolean);
+ method public void setPermissionPolicy(android.content.ComponentName, int);
method public boolean setPermittedAccessibilityServices(android.content.ComponentName, java.util.List<java.lang.String>);
method public boolean setPermittedInputMethods(android.content.ComponentName, java.util.List<java.lang.String>);
method public void setPreferredSetupActivity(android.content.ComponentName, android.content.ComponentName);
@@ -5869,6 +5873,9 @@
field public static final int PASSWORD_QUALITY_NUMERIC_COMPLEX = 196608; // 0x30000
field public static final int PASSWORD_QUALITY_SOMETHING = 65536; // 0x10000
field public static final int PASSWORD_QUALITY_UNSPECIFIED = 0; // 0x0
+ field public static final int PERMISSION_POLICY_AUTO_DENY = 2; // 0x2
+ field public static final int PERMISSION_POLICY_AUTO_GRANT = 1; // 0x1
+ field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0
field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
@@ -9402,6 +9409,7 @@
field public static final int GET_SIGNATURES = 64; // 0x40
field public static final int GET_UNINSTALLED_PACKAGES = 8192; // 0x2000
field public static final int GET_URI_PERMISSION_PATTERNS = 2048; // 0x800
+ field public static final int MATCH_ALL = 131072; // 0x20000
field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000
field public static final long MAXIMUM_VERIFICATION_TIMEOUT = 3600000L; // 0x36ee80L
field public static final int PERMISSION_DENIED = -1; // 0xffffffff
@@ -13226,6 +13234,7 @@
field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_POSE_TRANSLATION;
field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_RADIAL_DISTORTION;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REPROCESS_MAX_CAPTURE_STALL;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> REQUEST_AVAILABLE_CAPABILITIES;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_INPUT_STREAMS;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_PROC;
@@ -30418,7 +30427,6 @@
public static abstract class InCallService.VideoCall {
ctor public InCallService.VideoCall();
method public abstract void registerCallback(android.telecom.InCallService.VideoCall.Callback);
- method public abstract void unregisterCallback();
method public abstract void requestCallDataUsage();
method public abstract void requestCameraCapabilities();
method public abstract void sendSessionModifyRequest(android.telecom.VideoProfile);
@@ -30429,6 +30437,7 @@
method public abstract void setPauseImage(java.lang.String);
method public abstract void setPreviewSurface(android.view.Surface);
method public abstract void setZoom(float);
+ method public abstract void unregisterCallback();
}
public static abstract class InCallService.VideoCall.Callback {
@@ -33983,6 +33992,7 @@
method public static void readEvents(int[], java.util.Collection<android.util.EventLog.Event>) throws java.io.IOException;
method public static int writeEvent(int, int);
method public static int writeEvent(int, long);
+ method public static int writeEvent(int, float);
method public static int writeEvent(int, java.lang.String);
method public static int writeEvent(int, java.lang.Object...);
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 9d34060..7210666 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -351,7 +351,7 @@
field public static final int allowParallelSyncs = 16843570; // 0x1010332
field public static final int allowSingleTap = 16843353; // 0x1010259
field public static final int allowTaskReparenting = 16843268; // 0x1010204
- field public static final int allowUndo = 16844006; // 0x10104e6
+ field public static final int allowUndo = 16844005; // 0x10104e5
field public static final int alpha = 16843551; // 0x101031f
field public static final int alphabeticShortcut = 16843235; // 0x10101e3
field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef
@@ -372,7 +372,7 @@
field public static final int anyDensity = 16843372; // 0x101026c
field public static final int apduServiceBanner = 16843757; // 0x10103ed
field public static final int apiKey = 16843281; // 0x1010211
- field public static final int assistBlocked = 16844020; // 0x10104f4
+ field public static final int assistBlocked = 16844019; // 0x10104f3
field public static final int author = 16843444; // 0x10102b4
field public static final int authorities = 16842776; // 0x1010018
field public static final int autoAdvanceViewId = 16843535; // 0x101030f
@@ -383,7 +383,7 @@
field public static final int autoStart = 16843445; // 0x10102b5
field public static final deprecated int autoText = 16843114; // 0x101016a
field public static final int autoUrlDetect = 16843404; // 0x101028c
- field public static final int autoVerify = 16844010; // 0x10104ea
+ field public static final int autoVerify = 16844009; // 0x10104e9
field public static final int background = 16842964; // 0x10100d4
field public static final int backgroundDimAmount = 16842802; // 0x1010032
field public static final int backgroundDimEnabled = 16843295; // 0x101021f
@@ -407,7 +407,7 @@
field public static final int bottomRightRadius = 16843180; // 0x10101ac
field public static final int breadCrumbShortTitle = 16843524; // 0x1010304
field public static final int breadCrumbTitle = 16843523; // 0x1010303
- field public static final int breakStrategy = 16844011; // 0x10104eb
+ field public static final int breakStrategy = 16844010; // 0x10104ea
field public static final int bufferType = 16843086; // 0x101014e
field public static final int button = 16843015; // 0x1010107
field public static final int buttonBarButtonStyle = 16843567; // 0x101032f
@@ -469,7 +469,7 @@
field public static final int colorActivatedHighlight = 16843664; // 0x1010390
field public static final int colorBackground = 16842801; // 0x1010031
field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
- field public static final int colorBackgroundFloating = 16844007; // 0x10104e7
+ field public static final int colorBackgroundFloating = 16844006; // 0x10104e6
field public static final int colorButtonNormal = 16843819; // 0x101042b
field public static final int colorControlActivated = 16843818; // 0x101042a
field public static final int colorControlHighlight = 16843820; // 0x101042c
@@ -578,7 +578,7 @@
field public static final int dropDownWidth = 16843362; // 0x1010262
field public static final int duplicateParentState = 16842985; // 0x10100e9
field public static final int duration = 16843160; // 0x1010198
- field public static final int dynamicResources = 16844019; // 0x10104f3
+ field public static final int dynamicResources = 16844018; // 0x10104f2
field public static final int editTextBackground = 16843602; // 0x1010352
field public static final int editTextColor = 16843601; // 0x1010351
field public static final int editTextPreferenceStyle = 16842898; // 0x1010092
@@ -590,7 +590,7 @@
field public static final int ellipsize = 16842923; // 0x10100ab
field public static final int ems = 16843096; // 0x1010158
field public static final int enabled = 16842766; // 0x101000e
- field public static final int end = 16843997; // 0x10104dd
+ field public static final int end = 16843996; // 0x10104dc
field public static final int endColor = 16843166; // 0x101019e
field public static final deprecated int endYear = 16843133; // 0x101017d
field public static final int enterFadeDuration = 16843532; // 0x101030c
@@ -612,7 +612,7 @@
field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6
field public static final int exported = 16842768; // 0x1010010
field public static final int extraTension = 16843371; // 0x101026b
- field public static final int extractNativeLibs = 16844008; // 0x10104e8
+ field public static final int extractNativeLibs = 16844007; // 0x10104e7
field public static final int factor = 16843219; // 0x10101d3
field public static final int fadeDuration = 16843384; // 0x1010278
field public static final int fadeEnabled = 16843390; // 0x101027e
@@ -726,8 +726,8 @@
field public static final int host = 16842792; // 0x1010028
field public static final int icon = 16842754; // 0x1010002
field public static final int iconPreview = 16843337; // 0x1010249
- field public static final int iconTint = 16844000; // 0x10104e0
- field public static final int iconTintMode = 16844001; // 0x10104e1
+ field public static final int iconTint = 16843999; // 0x10104df
+ field public static final int iconTintMode = 16844000; // 0x10104e0
field public static final int iconifiedByDefault = 16843514; // 0x10102fa
field public static final int id = 16842960; // 0x10100d0
field public static final int ignoreGravity = 16843263; // 0x10101ff
@@ -867,7 +867,7 @@
field public static final int layout_x = 16843135; // 0x101017f
field public static final int layout_y = 16843136; // 0x1010180
field public static final int left = 16843181; // 0x10101ad
- field public static final int leftIndents = 16844016; // 0x10104f0
+ field public static final int leftIndents = 16844015; // 0x10104ef
field public static final int letterSpacing = 16843958; // 0x10104b6
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
@@ -890,7 +890,7 @@
field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208
field public static final int listViewStyle = 16842868; // 0x1010074
field public static final int listViewWhiteStyle = 16842869; // 0x1010075
- field public static final int lockTaskMode = 16844015; // 0x10104ef
+ field public static final int lockTaskMode = 16844014; // 0x10104ee
field public static final int logo = 16843454; // 0x10102be
field public static final int longClickable = 16842982; // 0x10100e6
field public static final int loopViews = 16843527; // 0x1010307
@@ -939,8 +939,8 @@
field public static final int navigationContentDescription = 16843969; // 0x10104c1
field public static final int navigationIcon = 16843968; // 0x10104c0
field public static final int navigationMode = 16843471; // 0x10102cf
- field public static final int navigationTint = 16844004; // 0x10104e4
- field public static final int navigationTintMode = 16844005; // 0x10104e5
+ field public static final int navigationTint = 16844003; // 0x10104e3
+ field public static final int navigationTintMode = 16844004; // 0x10104e4
field public static final int negativeButtonText = 16843254; // 0x10101f6
field public static final int nestedScrollingEnabled = 16843830; // 0x1010436
field public static final int nextFocusDown = 16842980; // 0x10100e4
@@ -954,7 +954,7 @@
field public static final int numColumns = 16843032; // 0x1010118
field public static final int numStars = 16843076; // 0x1010144
field public static final int numbersBackgroundColor = 16843938; // 0x10104a2
- field public static final int numbersInnerTextColor = 16843999; // 0x10104df
+ field public static final int numbersInnerTextColor = 16843998; // 0x10104de
field public static final int numbersSelectorColor = 16843939; // 0x10104a3
field public static final int numbersTextColor = 16843937; // 0x10104a1
field public static final deprecated int numeric = 16843109; // 0x1010165
@@ -972,8 +972,8 @@
field public static final int overScrollFooter = 16843459; // 0x10102c3
field public static final int overScrollHeader = 16843458; // 0x10102c2
field public static final int overScrollMode = 16843457; // 0x10102c1
- field public static final int overflowTint = 16844002; // 0x10104e2
- field public static final int overflowTintMode = 16844003; // 0x10104e3
+ field public static final int overflowTint = 16844001; // 0x10104e1
+ field public static final int overflowTintMode = 16844002; // 0x10104e2
field public static final int overlapAnchor = 16843874; // 0x1010462
field public static final int overridesImplicitlyEnabledSubtype = 16843682; // 0x10103a2
field public static final int packageNames = 16843649; // 0x1010381
@@ -1068,7 +1068,7 @@
field public static final int readPermission = 16842759; // 0x1010007
field public static final int recognitionService = 16843932; // 0x101049c
field public static final int relinquishTaskIdentity = 16843894; // 0x1010476
- field public static final int removeBeforeMRelease = 16844014; // 0x10104ee
+ field public static final int removeBeforeMRelease = 16844013; // 0x10104ed
field public static final int reparent = 16843964; // 0x10104bc
field public static final int reparentWithOverlay = 16843965; // 0x10104bd
field public static final int repeatCount = 16843199; // 0x10101bf
@@ -1087,7 +1087,6 @@
field public static final int resizeClip = 16843983; // 0x10104cf
field public static final int resizeMode = 16843619; // 0x1010363
field public static final int resizeable = 16843405; // 0x101028d
- field public static final int resizeableActivity = 16843995; // 0x10104db
field public static final int resource = 16842789; // 0x1010025
field public static final int restoreAnyVersion = 16843450; // 0x10102ba
field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
@@ -1097,7 +1096,7 @@
field public static final int reversible = 16843851; // 0x101044b
field public static final int revisionCode = 16843989; // 0x10104d5
field public static final int right = 16843183; // 0x10101af
- field public static final int rightIndents = 16844017; // 0x10104f1
+ field public static final int rightIndents = 16844016; // 0x10104f0
field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
field public static final int ringtoneType = 16843257; // 0x10101f9
field public static final int rotation = 16843558; // 0x1010326
@@ -1177,7 +1176,7 @@
field public static final int showAsAction = 16843481; // 0x10102d9
field public static final int showDefault = 16843258; // 0x10101fa
field public static final int showDividers = 16843561; // 0x1010329
- field public static final int showForAllUsers = 16844018; // 0x10104f2
+ field public static final int showForAllUsers = 16844017; // 0x10104f1
field public static final deprecated int showOnLockScreen = 16843721; // 0x10103c9
field public static final int showSilent = 16843259; // 0x10101fb
field public static final int showText = 16843949; // 0x10104ad
@@ -1207,7 +1206,7 @@
field public static final int stackFromBottom = 16843005; // 0x10100fd
field public static final int stackViewStyle = 16843838; // 0x101043e
field public static final int starStyle = 16842882; // 0x1010082
- field public static final int start = 16843996; // 0x10104dc
+ field public static final int start = 16843995; // 0x10104db
field public static final int startColor = 16843165; // 0x101019d
field public static final int startDelay = 16843746; // 0x10103e2
field public static final int startOffset = 16843198; // 0x10101be
@@ -1263,7 +1262,7 @@
field public static final int summaryColumn = 16843426; // 0x10102a2
field public static final int summaryOff = 16843248; // 0x10101f0
field public static final int summaryOn = 16843247; // 0x10101ef
- field public static final int supportsAssistGesture = 16844012; // 0x10104ec
+ field public static final int supportsAssistGesture = 16844011; // 0x10104eb
field public static final int supportsRtl = 16843695; // 0x10103af
field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
field public static final int supportsUploading = 16843419; // 0x101029b
@@ -1364,7 +1363,7 @@
field public static final int thicknessRatio = 16843164; // 0x101019c
field public static final int thumb = 16843074; // 0x1010142
field public static final int thumbOffset = 16843075; // 0x1010143
- field public static final int thumbPosition = 16844013; // 0x10104ed
+ field public static final int thumbPosition = 16844012; // 0x10104ec
field public static final int thumbTextPadding = 16843634; // 0x1010372
field public static final int thumbTint = 16843889; // 0x1010471
field public static final int thumbTintMode = 16843890; // 0x1010472
@@ -1428,7 +1427,7 @@
field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
field public static final int useLevel = 16843167; // 0x101019f
field public static final int userVisible = 16843409; // 0x1010291
- field public static final int usesCleartextTraffic = 16844009; // 0x10104e9
+ field public static final int usesCleartextTraffic = 16844008; // 0x10104e8
field public static final int value = 16842788; // 0x1010024
field public static final int valueFrom = 16843486; // 0x10102de
field public static final int valueTo = 16843487; // 0x10102df
@@ -1493,10 +1492,10 @@
field public static final int windowExitTransition = 16843832; // 0x1010438
field public static final int windowFrame = 16842837; // 0x1010055
field public static final int windowFullscreen = 16843277; // 0x101020d
- field public static final int windowHasLightStatusBar = 16843998; // 0x10104de
field public static final int windowHideAnimation = 16842935; // 0x10100b7
field public static final int windowIsFloating = 16842839; // 0x1010057
field public static final int windowIsTranslucent = 16842840; // 0x1010058
+ field public static final int windowLightStatusBar = 16843997; // 0x10104dd
field public static final int windowMinWidthMajor = 16843606; // 0x1010356
field public static final int windowMinWidthMinor = 16843607; // 0x1010357
field public static final int windowNoDisplay = 16843294; // 0x101021e
@@ -5828,6 +5827,7 @@
method public int getPasswordMinimumSymbols(android.content.ComponentName);
method public int getPasswordMinimumUpperCase(android.content.ComponentName);
method public int getPasswordQuality(android.content.ComponentName);
+ method public int getPermissionPolicy(android.content.ComponentName);
method public java.util.List<java.lang.String> getPermittedAccessibilityServices(android.content.ComponentName);
method public java.util.List<java.lang.String> getPermittedAccessibilityServices(int);
method public java.util.List<java.lang.String> getPermittedInputMethods(android.content.ComponentName);
@@ -5886,6 +5886,8 @@
method public void setPasswordMinimumSymbols(android.content.ComponentName, int);
method public void setPasswordMinimumUpperCase(android.content.ComponentName, int);
method public void setPasswordQuality(android.content.ComponentName, int);
+ method public boolean setPermissionGranted(android.content.ComponentName, java.lang.String, java.lang.String, boolean);
+ method public void setPermissionPolicy(android.content.ComponentName, int);
method public boolean setPermittedAccessibilityServices(android.content.ComponentName, java.util.List<java.lang.String>);
method public boolean setPermittedInputMethods(android.content.ComponentName, java.util.List<java.lang.String>);
method public void setPreferredSetupActivity(android.content.ComponentName, android.content.ComponentName);
@@ -5979,6 +5981,9 @@
field public static final int PASSWORD_QUALITY_NUMERIC_COMPLEX = 196608; // 0x30000
field public static final int PASSWORD_QUALITY_SOMETHING = 65536; // 0x10000
field public static final int PASSWORD_QUALITY_UNSPECIFIED = 0; // 0x0
+ field public static final int PERMISSION_POLICY_AUTO_DENY = 2; // 0x2
+ field public static final int PERMISSION_POLICY_AUTO_GRANT = 1; // 0x1
+ field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0
field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
@@ -9697,6 +9702,7 @@
field public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103; // 0xffffff99
field public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102; // 0xffffff9a
field public static final int INSTALL_SUCCEEDED = 1; // 0x1
+ field public static final int MATCH_ALL = 131072; // 0x20000
field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000
field public static final long MAXIMUM_VERIFICATION_TIMEOUT = 3600000L; // 0x36ee80L
field public static final int PERMISSION_DENIED = -1; // 0xffffffff
@@ -13526,6 +13532,7 @@
field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_POSE_TRANSLATION;
field public static final android.hardware.camera2.CameraCharacteristics.Key<float[]> LENS_RADIAL_DISTORTION;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REPROCESS_MAX_CAPTURE_STALL;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> REQUEST_AVAILABLE_CAPABILITIES;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_INPUT_STREAMS;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_PROC;
@@ -32535,7 +32542,6 @@
public static abstract class InCallService.VideoCall {
ctor public InCallService.VideoCall();
method public abstract void registerCallback(android.telecom.InCallService.VideoCall.Callback);
- method public abstract void unregisterCallback();
method public abstract void requestCallDataUsage();
method public abstract void requestCameraCapabilities();
method public abstract void sendSessionModifyRequest(android.telecom.VideoProfile);
@@ -32546,6 +32552,7 @@
method public abstract void setPauseImage(java.lang.String);
method public abstract void setPreviewSurface(android.view.Surface);
method public abstract void setZoom(float);
+ method public abstract void unregisterCallback();
}
public static abstract class InCallService.VideoCall.Callback {
@@ -36187,6 +36194,7 @@
method public static void readEvents(int[], java.util.Collection<android.util.EventLog.Event>) throws java.io.IOException;
method public static int writeEvent(int, int);
method public static int writeEvent(int, long);
+ method public static int writeEvent(int, float);
method public static int writeEvent(int, java.lang.String);
method public static int writeEvent(int, java.lang.Object...);
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ed814c3..cf9813f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -807,6 +807,24 @@
public static final String ACTION_SYSTEM_UPDATE_POLICY_CHANGED
= "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED";
+ /**
+ * Permission policy to prompt user for new permission requests for runtime permissions.
+ * Already granted or denied permissions are not affected by this.
+ */
+ public static final int PERMISSION_POLICY_PROMPT = 0;
+
+ /**
+ * Permission policy to always grant new permission requests for runtime permissions.
+ * Already granted or denied permissions are not affected by this.
+ */
+ public static final int PERMISSION_POLICY_AUTO_GRANT = 1;
+
+ /**
+ * Permission policy to always deny new permission requests for runtime permissions.
+ * Already granted or denied permissions are not affected by this.
+ */
+ public static final int PERMISSION_POLICY_AUTO_DENY = 2;
+
/**
* Return true if the given administrator component is currently
@@ -4342,4 +4360,58 @@
Log.w(TAG, "Failed talking with device policy service", re);
}
}
+
+ /**
+ * Called by profile or device owners to set the default response for future runtime permission
+ * requests by applications. The policy can allow for normal operation which prompts the
+ * user to grant a permission, or can allow automatic granting or denying of runtime
+ * permission requests by an application. This also applies to new permissions declared by app
+ * updates.
+ * @param admin Which profile or device owner this request is associated with.
+ * @param policy One of the policy constants {@link #PERMISSION_POLICY_PROMPT},
+ * {@link #PERMISSION_POLICY_AUTO_GRANT} and {@link #PERMISSION_POLICY_AUTO_DENY}.
+ */
+ public void setPermissionPolicy(ComponentName admin, int policy) {
+ try {
+ mService.setPermissionPolicy(admin, policy);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Failed talking with device policy service", re);
+ }
+ }
+
+ /**
+ * Returns the current runtime permission policy set by the device or profile owner. The
+ * default is {@link #PERMISSION_POLICY_PROMPT}.
+ * @param admin Which profile or device owner this request is associated with.
+ * @return the current policy for future permission requests.
+ */
+ public int getPermissionPolicy(ComponentName admin) {
+ try {
+ return mService.getPermissionPolicy(admin);
+ } catch (RemoteException re) {
+ return PERMISSION_POLICY_PROMPT;
+ }
+ }
+
+ /**
+ * Grants or revokes a runtime permission to a specific application so that the user
+ * does not have to be prompted. This might affect all permissions in a group that the
+ * runtime permission belongs to. This method can only be called by a profile or device
+ * owner.
+ * @param admin Which profile or device owner this request is associated with.
+ * @param packageName The application to grant or revoke a permission to.
+ * @param permission The permission to grant or revoke.
+ * @param granted Whether or not to grant the permission. If false, all permissions in the
+ * associated permission group will be denied.
+ * @return whether the permission was successfully granted or revoked
+ */
+ public boolean setPermissionGranted(ComponentName admin, String packageName,
+ String permission, boolean granted) {
+ try {
+ return mService.setPermissionGranted(admin, packageName, permission, granted);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Failed talking with device policy service", re);
+ return false;
+ }
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index a678c51..833bc00 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -229,4 +229,9 @@
boolean getDoNotAskCredentialsOnBoot();
void notifyPendingSystemUpdate(in long updateReceivedTime);
+
+ void setPermissionPolicy(in ComponentName admin, int policy);
+ int getPermissionPolicy(in ComponentName admin);
+ boolean setPermissionGranted(in ComponentName admin, String packageName, String permission,
+ boolean granted);
}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index fd65d56..72e701d 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -211,7 +211,27 @@
// We do not call ContentProvider#query with a modified where clause since
// the implementation is not guaranteed to be backed by a SQL database, hence
// it may not handle properly the tautology where clause we would have created.
- return new MatrixCursor(projection, 0);
+ if (projection != null) {
+ return new MatrixCursor(projection, 0);
+ }
+
+ // Null projection means all columns but we have no idea which they are.
+ // However, the caller may be expecting to access them my index. Hence,
+ // we have to execute the query as if allowed to get a cursor with the
+ // columns. We then use the column names to return an empty cursor.
+ Cursor cursor = ContentProvider.this.query(uri, projection, selection,
+ selectionArgs, sortOrder, CancellationSignal.fromTransport(
+ cancellationSignal));
+
+ // Create a projection for all columns.
+ final int columnCount = cursor.getCount();
+ String[] allColumns = new String[columnCount];
+ for (int i = 0; i < columnCount; i++) {
+ allColumns[i] = cursor.getColumnName(i);
+ }
+
+ // Return an empty cursor for all columns.
+ return new MatrixCursor(allColumns, 0);
}
final String original = setCallingPackage(callingPkg);
try {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e1c271d..f01ca09 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -209,7 +209,14 @@
* matching. This is a synonym for including the CATEGORY_DEFAULT in your
* supplied Intent.
*/
- public static final int MATCH_DEFAULT_ONLY = 0x00010000;
+ public static final int MATCH_DEFAULT_ONLY = 0x00010000;
+
+ /**
+ * Querying flag: if set and if the platform is doing any filtering of the results, then
+ * the filtering will not happen. This is a synonym for saying that all results should
+ * be returned.
+ */
+ public static final int MATCH_ALL = 0x00020000;
/**
* Flag for {@link addCrossProfileIntentFilter}: if this flag is set:
@@ -2637,6 +2644,8 @@
* {@link #MATCH_DEFAULT_ONLY}, to limit the resolution to only
* those activities that support the {@link android.content.Intent#CATEGORY_DEFAULT}.
*
+ * You can also set {@link #MATCH_ALL} for preventing the filtering of the results.
+ *
* @return A List<ResolveInfo> containing one entry for each matching
* Activity. These are ordered from best to worst match -- that
* is, the first item in the list is what is returned by
@@ -2658,6 +2667,8 @@
* {@link #MATCH_DEFAULT_ONLY}, to limit the resolution to only
* those activities that support the {@link android.content.Intent#CATEGORY_DEFAULT}.
*
+ * You can also set {@link #MATCH_ALL} for preventing the filtering of the results.
+ *
* @return A List<ResolveInfo> containing one entry for each matching
* Activity. These are ordered from best to worst match -- that
* is, the first item in the list is what is returned by
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 87a1ca9..19e821c 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -603,10 +603,9 @@
/**
* <p>List of available high speed video size and fps range configurations
* supported by the camera device, in the format of (width, height, fps_min, fps_max).</p>
- * <p>When HIGH_SPEED_VIDEO is supported in {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes},
- * this metadata will list the supported high speed video size and fps range
- * configurations. All the sizes listed in this configuration will be a subset
- * of the sizes reported by StreamConfigurationMap#getOutputSizes for processed
+ * <p>When HIGH_SPEED_VIDEO is supported in {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}, this metadata
+ * will list the supported high speed video size and fps range configurations. All the sizes
+ * listed in this configuration will be a subset of the sizes reported by {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } for processed
* non-stalling formats.</p>
* <p>For the high speed video use case, where the application will set
* {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} to HIGH_SPEED_VIDEO in capture requests, the application must
@@ -1116,11 +1115,12 @@
* into the 3 stream types as below:</p>
* <ul>
* <li>Processed (but stalling): any non-RAW format with a stallDurations > 0.
- * Typically JPEG format (ImageFormat#JPEG).</li>
- * <li>Raw formats: ImageFormat#RAW_SENSOR, ImageFormat#RAW10, ImageFormat#RAW12,
- * and ImageFormat#RAW_OPAQUE.</li>
+ * Typically {@link android.graphics.ImageFormat#JPEG JPEG format}.</li>
+ * <li>Raw formats: {@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}, {@link android.graphics.ImageFormat#RAW10 RAW10}, or {@link android.graphics.ImageFormat#RAW12 RAW12}.</li>
* <li>Processed (but not-stalling): any non-RAW format without a stall duration.
- * Typically ImageFormat#YUV_420_888, ImageFormat#NV21, ImageFormat#YV12.</li>
+ * Typically {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888},
+ * {@link android.graphics.ImageFormat#NV21 NV21}, or
+ * {@link android.graphics.ImageFormat#YV12 YV12}.</li>
* </ul>
* <p><b>Range of valid values:</b><br></p>
* <p>For processed (and stalling) format streams, >= 1.</p>
@@ -1148,10 +1148,9 @@
* be any <code>RAW</code> and supported format provided by {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.</p>
* <p>In particular, a <code>RAW</code> format is typically one of:</p>
* <ul>
- * <li>ImageFormat#RAW_SENSOR</li>
- * <li>ImageFormat#RAW10</li>
- * <li>ImageFormat#RAW12</li>
- * <li>Opaque <code>RAW</code></li>
+ * <li>{@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}</li>
+ * <li>{@link android.graphics.ImageFormat#RAW10 RAW10}</li>
+ * <li>{@link android.graphics.ImageFormat#RAW12 RAW12}</li>
* </ul>
* <p>LEGACY mode devices ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} <code>==</code> LEGACY)
* never support raw streams.</p>
@@ -1180,13 +1179,13 @@
* <p>Processed (but not-stalling) is defined as any non-RAW format without a stall duration.
* Typically:</p>
* <ul>
- * <li>ImageFormat#YUV_420_888</li>
- * <li>ImageFormat#NV21</li>
- * <li>ImageFormat#YV12</li>
- * <li>Implementation-defined formats, i.e. StreamConfiguration#isOutputSupportedFor(Class)</li>
+ * <li>{@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888}</li>
+ * <li>{@link android.graphics.ImageFormat#NV21 NV21}</li>
+ * <li>{@link android.graphics.ImageFormat#YV12 YV12}</li>
+ * <li>Implementation-defined formats, i.e. {@link android.hardware.camera2.params.StreamConfigurationMap#isOutputSupportedFor(Class) }</li>
* </ul>
- * <p>For full guarantees, query StreamConfigurationMap#getOutputStallDuration with
- * a processed format -- it will return 0 for a non-stalling stream.</p>
+ * <p>For full guarantees, query {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration } with a
+ * processed format -- it will return 0 for a non-stalling stream.</p>
* <p>LEGACY devices will support at least 2 processing/non-stalling streams.</p>
* <p><b>Range of valid values:</b><br></p>
* <p>>= 3
@@ -1212,10 +1211,11 @@
* the camera device. Using more streams simultaneously may require more hardware and
* CPU resources that will consume more power. The image format for this kind of an output stream can
* be any non-<code>RAW</code> and supported format provided by {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}.</p>
- * <p>A processed and stalling format is defined as any non-RAW format with a stallDurations > 0.
- * Typically only the <code>JPEG</code> format (ImageFormat#JPEG) is a stalling format.</p>
- * <p>For full guarantees, query StreamConfigurationMap#getOutputStallDuration with
- * a processed format -- it will return a non-0 value for a stalling stream.</p>
+ * <p>A processed and stalling format is defined as any non-RAW format with a stallDurations
+ * > 0. Typically only the {@link android.graphics.ImageFormat#JPEG JPEG format} is a
+ * stalling format.</p>
+ * <p>For full guarantees, query {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration } with a
+ * processed format -- it will return a non-0 value for a stalling stream.</p>
* <p>LEGACY devices will support up to 1 processing/stalling stream.</p>
* <p><b>Range of valid values:</b><br></p>
* <p>>= 1</p>
@@ -1232,10 +1232,9 @@
* <p>The maximum numbers of any type of input streams
* that can be configured and used simultaneously by a camera device.</p>
* <p>When set to 0, it means no input stream is supported.</p>
- * <p>The image format for a input stream can be any supported
- * format returned by StreamConfigurationMap#getInputFormats. When using an
- * input stream, there must be at least one output stream
- * configured to to receive the reprocessed images.</p>
+ * <p>The image format for a input stream can be any supported format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }. When using an
+ * input stream, there must be at least one output stream configured to to receive the
+ * reprocessed images.</p>
* <p>When an input stream and some output streams are used in a reprocessing request,
* only the input buffer will be used to produce these output stream buffers, and a
* new sensor image will not be captured.</p>
@@ -1352,7 +1351,7 @@
/**
* <p>A list of all keys that the camera device has available
- * to use with CaptureRequest.</p>
+ * to use with {@link android.hardware.camera2.CaptureRequest }.</p>
* <p>Attempting to set a key into a CaptureRequest that is not
* listed here will result in an invalid request and will be rejected
* by the camera device.</p>
@@ -1370,7 +1369,7 @@
/**
* <p>A list of all keys that the camera device has available
- * to use with CaptureResult.</p>
+ * to use with {@link android.hardware.camera2.CaptureResult }.</p>
* <p>Attempting to get a key from a CaptureResult that is not
* listed here will always return a <code>null</code> value. Getting a key from
* a CaptureResult that is listed here will generally never return a <code>null</code>
@@ -1396,7 +1395,7 @@
/**
* <p>A list of all keys that the camera device has available
- * to use with CameraCharacteristics.</p>
+ * to use with {@link android.hardware.camera2.CameraCharacteristics }.</p>
* <p>This entry follows the same rules as
* android.request.availableResultKeys (except that it applies for
* CameraCharacteristics instead of CaptureResult). See above for more
@@ -1535,34 +1534,31 @@
* </thead>
* <tbody>
* <tr>
- * <td align="left">PRIVATE (ImageFormat#PRIVATE)</td>
- * <td align="left">JPEG</td>
+ * <td align="left">{@link android.graphics.ImageFormat#PRIVATE }</td>
+ * <td align="left">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="left">OPAQUE_REPROCESSING</td>
* </tr>
* <tr>
- * <td align="left">PRIVATE</td>
- * <td align="left">YUV_420_888</td>
+ * <td align="left">{@link android.graphics.ImageFormat#PRIVATE }</td>
+ * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
* <td align="left">OPAQUE_REPROCESSING</td>
* </tr>
* <tr>
- * <td align="left">YUV_420_888</td>
- * <td align="left">JPEG</td>
+ * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
+ * <td align="left">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="left">YUV_REPROCESSING</td>
* </tr>
* <tr>
- * <td align="left">YUV_420_888</td>
- * <td align="left">YUV_420_888</td>
+ * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
+ * <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
* <td align="left">YUV_REPROCESSING</td>
* </tr>
* </tbody>
* </table>
- * <p>PRIVATE refers to a device-internal format that is not directly application-visible.
- * A PRIVATE input surface can be acquired by
- * ImageReader.newOpaqueInstance(width, height, maxImages).
- * For a OPAQUE_REPROCESSING-capable camera device, using the PRIVATE format
- * as either input or output will never hurt maximum frame rate (i.e.
- * StreamConfigurationMap#getOutputStallDuration(format, size) is always 0),
- * where format is ImageFormat#PRIVATE.</p>
+ * <p>PRIVATE refers to a device-internal format that is not directly application-visible. A
+ * PRIVATE input surface can be acquired by {@link android.media.ImageReader#newOpaqueInstance }.</p>
+ * <p>For a OPAQUE_REPROCESSING-capable camera device, using the PRIVATE format as either input
+ * or output will never hurt maximum frame rate (i.e. {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration getOutputStallDuration(ImageFormat.PRIVATE, size)} is always 0),</p>
* <p>Attempting to configure an input stream with output streams not
* listed as available in this map is not valid.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
@@ -1680,7 +1676,7 @@
* android.scaler.availableStallDurations for more details about
* calculating the max frame rate.</p>
* <p>(Keep in sync with
- * StreamConfigurationMap#getOutputMinFrameDuration)</p>
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration })</p>
* <p><b>Units</b>: (format, width, height, ns) x n</p>
* <p>This key is available on all devices.</p>
*
@@ -1692,7 +1688,7 @@
/**
* <p>This lists the maximum stall duration for each
- * format/size combination.</p>
+ * output format/size combination.</p>
* <p>A stall duration is how much extra time would get added
* to the normal minimum frame duration for a repeating request
* that has streams with non-zero stall.</p>
@@ -1734,12 +1730,13 @@
* ignored).</p>
* <p>The following formats may always have a stall duration:</p>
* <ul>
- * <li>ImageFormat#JPEG</li>
- * <li>ImageFormat#RAW_SENSOR</li>
+ * <li>{@link android.graphics.ImageFormat#JPEG }</li>
+ * <li>{@link android.graphics.ImageFormat#RAW_SENSOR }</li>
* </ul>
* <p>The following formats will never have a stall duration:</p>
* <ul>
- * <li>ImageFormat#YUV_420_888</li>
+ * <li>{@link android.graphics.ImageFormat#YUV_420_888 }</li>
+ * <li>{@link android.graphics.ImageFormat#RAW10 }</li>
* </ul>
* <p>All other formats may or may not have an allowed stall duration on
* a per-capability basis; refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
@@ -1747,7 +1744,7 @@
* <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} for more information about
* calculating the max frame rate (absent stalls).</p>
* <p>(Keep up to date with
- * StreamConfigurationMap#getOutputStallDuration(int, Size) )</p>
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration } )</p>
* <p><b>Units</b>: (format, width, height, ns) x n</p>
* <p>This key is available on all devices.</p>
*
@@ -1786,57 +1783,57 @@
* </thead>
* <tbody>
* <tr>
- * <td align="center">JPEG</td>
+ * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="center">{@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</td>
* <td align="center">Any</td>
* <td align="center"></td>
* </tr>
* <tr>
- * <td align="center">JPEG</td>
+ * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="center">1920x1080 (1080p)</td>
* <td align="center">Any</td>
* <td align="center">if 1080p <= activeArraySize</td>
* </tr>
* <tr>
- * <td align="center">JPEG</td>
+ * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="center">1280x720 (720)</td>
* <td align="center">Any</td>
* <td align="center">if 720p <= activeArraySize</td>
* </tr>
* <tr>
- * <td align="center">JPEG</td>
+ * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="center">640x480 (480p)</td>
* <td align="center">Any</td>
* <td align="center">if 480p <= activeArraySize</td>
* </tr>
* <tr>
- * <td align="center">JPEG</td>
+ * <td align="center">{@link android.graphics.ImageFormat#JPEG }</td>
* <td align="center">320x240 (240p)</td>
* <td align="center">Any</td>
* <td align="center">if 240p <= activeArraySize</td>
* </tr>
* <tr>
- * <td align="center">YUV_420_888</td>
+ * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
* <td align="center">all output sizes available for JPEG</td>
* <td align="center">FULL</td>
* <td align="center"></td>
* </tr>
* <tr>
- * <td align="center">YUV_420_888</td>
+ * <td align="center">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
* <td align="center">all output sizes available for JPEG, up to the maximum video size</td>
* <td align="center">LIMITED</td>
* <td align="center"></td>
* </tr>
* <tr>
- * <td align="center">IMPLEMENTATION_DEFINED</td>
+ * <td align="center">{@link android.graphics.ImageFormat#PRIVATE }</td>
* <td align="center">same as YUV_420_888</td>
* <td align="center">Any</td>
* <td align="center"></td>
* </tr>
* </tbody>
* </table>
- * <p>Refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} for additional
- * mandatory stream configurations on a per-capability basis.</p>
+ * <p>Refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} and {@link android.hardware.camera2.CameraDevice#createCaptureSession } for additional mandatory
+ * stream configurations on a per-capability basis.</p>
* <p>This key is available on all devices.</p>
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
@@ -1973,8 +1970,8 @@
* <p>Attempting to use frame durations beyond the maximum will result in the frame
* duration being clipped to the maximum. See that control for a full definition of frame
* durations.</p>
- * <p>Refer to StreamConfigurationMap#getOutputMinFrameDuration(int,Size) for the minimum
- * frame duration values.</p>
+ * <p>Refer to {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }
+ * for the minimum frame duration values.</p>
* <p><b>Units</b>: Nanoseconds</p>
* <p><b>Range of valid values:</b><br>
* For FULL capability devices
@@ -2634,6 +2631,41 @@
new Key<Integer>("android.sync.maxLatency", int.class);
/**
+ * <p>The maximal camera capture pipeline stall (in unit of frame count) introduced by a
+ * reprocess capture request.</p>
+ * <p>The key describes the maximal interference that one reprocess (input) request
+ * can introduce to the camera simultaneous streaming of regular (output) capture
+ * requests, including repeating requests.</p>
+ * <p>When a reprocessing capture request is submitted while a camera output repeating request
+ * (e.g. preview) is being served by the camera device, it may preempt the camera capture
+ * pipeline for at least one frame duration so that the camera device is unable to process
+ * the following capture request in time for the next sensor start of exposure boundary.
+ * When this happens, the application may observe a capture time gap (longer than one frame
+ * duration) between adjacent capture output frames, which usually exhibits as preview
+ * glitch if the repeating request output targets include a preview surface. This key gives
+ * the worst-case number of frame stall introduced by one reprocess request with any kind of
+ * formats/sizes combination.</p>
+ * <p>If this key reports 0, it means a reprocess request doesn't introduce any glitch to the
+ * ongoing camera repeating request outputs, as if this reprocess request is never issued.</p>
+ * <p>This key is supported if the camera device supports OPAQUE or YUV reprocessing (
+ * i.e. {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains OPAQUE_REPROCESSING or
+ * YUV_REPROCESSING).</p>
+ * <p><b>Units</b>: Number of frames.</p>
+ * <p><b>Range of valid values:</b><br>
+ * <= 4</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
+ *
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+ */
+ @PublicKey
+ public static final Key<Integer> REPROCESS_MAX_CAPTURE_STALL =
+ new Key<Integer>("android.reprocess.maxCaptureStall", int.class);
+
+ /**
* <p>The available depth dataspace stream
* configurations that this camera device supports
* (i.e. format, width, height, output/input stream).</p>
@@ -2672,8 +2704,7 @@
* <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} and
* android.scaler.availableStallDurations for more details about
* calculating the max frame rate.</p>
- * <p>(Keep in sync with
- * StreamConfigurationMap#getOutputMinFrameDuration)</p>
+ * <p>(Keep in sync with {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration })</p>
* <p><b>Units</b>: (format, width, height, ns) x n</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* <p><b>Limited capability</b> -
@@ -2689,7 +2720,7 @@
/**
* <p>This lists the maximum stall duration for each
- * format/size combination for depth streams.</p>
+ * output format/size combination for depth streams.</p>
* <p>A stall duration is how much extra time would get added
* to the normal minimum frame duration for a repeating request
* that has streams with non-zero stall.</p>
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 51b326b..f6791a4 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -54,6 +54,7 @@
* means that high frame rate is given priority over the highest-quality
* post-processing. These requests would normally be used with the
* {@link CameraCaptureSession#setRepeatingRequest} method.
+ * This template is guaranteed to be supported on all camera devices.
*
* @see #createCaptureRequest
*/
@@ -63,6 +64,7 @@
* Create a request suitable for still image capture. Specifically, this
* means prioritizing image quality over frame rate. These requests would
* commonly be used with the {@link CameraCaptureSession#capture} method.
+ * This template is guaranteed to be supported on all camera devices.
*
* @see #createCaptureRequest
*/
@@ -73,6 +75,7 @@
* that a stable frame rate is used, and post-processing is set for
* recording quality. These requests would commonly be used with the
* {@link CameraCaptureSession#setRepeatingRequest} method.
+ * This template is guaranteed to be supported on all camera devices.
*
* @see #createCaptureRequest
*/
@@ -84,6 +87,9 @@
* disrupting the ongoing recording. These requests would commonly be used
* with the {@link CameraCaptureSession#capture} method while a request based on
* {@link #TEMPLATE_RECORD} is is in use with {@link CameraCaptureSession#setRepeatingRequest}.
+ * This template is guaranteed to be supported on all camera devices except
+ * legacy devices ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+ * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY})
*
* @see #createCaptureRequest
*/
@@ -93,6 +99,11 @@
* Create a request suitable for zero shutter lag still capture. This means
* means maximizing image quality without compromising preview frame rate.
* AE/AWB/AF should be on auto mode.
+ * This template is guaranteed to be supported on camera devices that support the
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING OPAQUE_REPROCESSING}
+ * capability or the
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING YUV_REPROCESSING}
+ * capability.
*
* @see #createCaptureRequest
*/
@@ -105,6 +116,9 @@
* quality. The manual capture parameters (exposure, sensitivity, and so on)
* are set to reasonable defaults, but should be overriden by the
* application depending on the intended use case.
+ * This template is guaranteed to be supported on camera devices that support the
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR MANUAL_SENSOR}
+ * capability.
*
* @see #createCaptureRequest
*/
@@ -473,12 +487,14 @@
* settings as desired, instead.</p>
*
* @param templateType An enumeration selecting the use case for this
- * request; one of the CameraDevice.TEMPLATE_ values.
+ * request; one of the CameraDevice.TEMPLATE_ values. Not all template
+ * types are supported on every device. See the documentation for each
+ * template type for details.
* @return a builder for a capture request, initialized with default
* settings for that template, and no output streams
*
- * @throws IllegalArgumentException if the templateType is not in the list
- * of supported templates.
+ * @throws IllegalArgumentException if the templateType is not supported by
+ * this device.
* @throws CameraAccessException if the camera device is no longer connected or has
* encountered a fatal error
* @throws IllegalStateException if the camera device has been closed
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index e3f1d73..ca9439b 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -461,22 +461,21 @@
* <p>The camera device supports the Zero Shutter Lag reprocessing use case.</p>
* <ul>
* <li>One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.</li>
- * <li>ImageFormat#PRIVATE is supported as an output/input format, that is,
- * ImageFormat#PRIVATE is included in the lists of formats returned by
- * StreamConfigurationMap#getInputFormats and
- * StreamConfigurationMap#getOutputFormats.</li>
- * <li>StreamConfigurationMap#getValidOutputFormatsForInput returns non empty int[] for
- * each supported input format returned by StreamConfigurationMap#getInputFormats.</li>
- * <li>Each size returned by StreamConfigurationMap#getInputSizes(ImageFormat#PRIVATE)
- * is also included in StreamConfigurationMap#getOutputSizes(ImageFormat#PRIVATE)</li>
- * <li>Using ImageFormat#PRIVATE does not cause a frame rate drop
- * relative to the sensor's maximum capture rate (at that
- * resolution).</li>
- * <li>ImageFormat#PRIVATE will be reprocessable into both YUV_420_888
- * and JPEG formats.</li>
+ * <li>{@link android.graphics.ImageFormat#PRIVATE } is supported as an output/input format,
+ * that is, {@link android.graphics.ImageFormat#PRIVATE } is included in the lists of
+ * formats returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats } and {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputFormats }.</li>
+ * <li>{@link android.hardware.camera2.params.StreamConfigurationMap#getValidOutputFormatsForInput }
+ * returns non empty int[] for each supported input format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }.</li>
+ * <li>Each size returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputSizes getInputSizes(ImageFormat.PRIVATE)} is also included in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes getOutputSizes(ImageFormat.PRIVATE)}</li>
+ * <li>Using {@link android.graphics.ImageFormat#PRIVATE } does not cause a frame rate drop
+ * relative to the sensor's maximum capture rate (at that resolution).</li>
+ * <li>{@link android.graphics.ImageFormat#PRIVATE } will be reprocessable into both
+ * {@link android.graphics.ImageFormat#YUV_420_888 } and
+ * {@link android.graphics.ImageFormat#JPEG } formats.</li>
* <li>The maximum available resolution for OPAQUE streams
* (both input/output) will match the maximum available
* resolution of JPEG streams.</li>
+ * <li>Static metadata {@link CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL android.reprocess.maxCaptureStall}.</li>
* <li>Only below controls are effective for reprocessing requests and
* will be present in capture results, other controls in reprocess
* requests will be ignored by the camera device.<ul>
@@ -489,6 +488,7 @@
*
* @see CaptureRequest#EDGE_MODE
* @see CaptureRequest#NOISE_REDUCTION_MODE
+ * @see CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL
* @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
@@ -569,25 +569,25 @@
* following:</p>
* <ul>
* <li>One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.</li>
- * <li>YUV_420_888 is supported as an output/input format, that is,
+ * <li>{@link android.graphics.ImageFormat#YUV_420_888 } is supported as an output/input format, that is,
* YUV_420_888 is included in the lists of formats returned by
- * StreamConfigurationMap#getInputFormats and
- * StreamConfigurationMap#getOutputFormats.</li>
- * <li>StreamConfigurationMap#getValidOutputFormatsForInput returns non empty int[] for
- * each supported input format returned by StreamConfigurationMap#getInputFormats.</li>
- * <li>Each size returned by StreamConfigurationMap#getInputSizes(YUV_420_888)
- * is also included in StreamConfigurationMap#getOutputSizes(YUV_420_888)</li>
- * <li>Using YUV_420_888 does not cause a frame rate drop
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats } and
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputFormats }.</li>
+ * <li>{@link android.hardware.camera2.params.StreamConfigurationMap#getValidOutputFormatsForInput }
+ * returns non-empty int[] for each supported input format returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputFormats }.</li>
+ * <li>Each size returned by {@link android.hardware.camera2.params.StreamConfigurationMap#getInputSizes getInputSizes(YUV_420_888)} is also included in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes getOutputSizes(YUV_420_888)}</li>
+ * <li>Using {@link android.graphics.ImageFormat#YUV_420_888 } does not cause a frame rate drop
* relative to the sensor's maximum capture rate (at that resolution).</li>
- * <li>YUV_420_888 will be reprocessable into both YUV_420_888
- * and JPEG formats.</li>
- * <li>The maximum available resolution for YUV_420_888 streams
- * (both input/output) will match the maximum available
- * resolution of JPEG streams.</li>
- * <li>Only the below controls are effective for reprocessing requests and will be
- * present in capture results. The reprocess requests are from the original capture
- * results that are assocaited with the intermidate YUV_420_888 output buffers.
- * All other controls in the reprocess requests will be ignored by the camera device.<ul>
+ * <li>{@link android.graphics.ImageFormat#YUV_420_888 } will be reprocessable into both
+ * {@link android.graphics.ImageFormat#YUV_420_888 } and {@link android.graphics.ImageFormat#JPEG } formats.</li>
+ * <li>The maximum available resolution for {@link android.graphics.ImageFormat#YUV_420_888 } streams (both input/output) will match the
+ * maximum available resolution of {@link android.graphics.ImageFormat#JPEG } streams.</li>
+ * <li>Static metadata {@link CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL android.reprocess.maxCaptureStall}.</li>
+ * <li>Only the below controls are effective for reprocessing requests and will be present
+ * in capture results. The reprocess requests are from the original capture results that
+ * are associated with the intermediate {@link android.graphics.ImageFormat#YUV_420_888 }
+ * output buffers. All other controls in the reprocess requests will be ignored by the
+ * camera device.<ul>
* <li>android.jpeg.*</li>
* <li>{@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode}</li>
* <li>{@link CaptureRequest#EDGE_MODE android.edge.mode}</li>
@@ -599,6 +599,7 @@
* @see CaptureRequest#EDGE_MODE
* @see CaptureRequest#NOISE_REDUCTION_MODE
* @see CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
+ * @see CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL
* @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
@@ -608,11 +609,13 @@
* <p>The camera device can produce depth measurements from its field of view.</p>
* <p>This capability requires the camera device to support the following:</p>
* <ul>
- * <li>DEPTH16 is supported as an output format.</li>
- * <li>DEPTH_POINT_CLOUD is optionally supported as an output format.</li>
- * <li>This camera device, and all camera devices with the same android.lens.info.facing,
- * will list the following calibration entries in both CameraCharacteristics and
- * CaptureResults:<ul>
+ * <li>{@link android.graphics.ImageFormat#DEPTH16 } is supported as an output format.</li>
+ * <li>{@link android.graphics.ImageFormat#DEPTH_POINT_CLOUD } is optionally supported as an
+ * output format.</li>
+ * <li>This camera device, and all camera devices with the same {@link CameraCharacteristics#LENS_FACING android.lens.facing},
+ * will list the following calibration entries in both
+ * {@link android.hardware.camera2.CameraCharacteristics } and
+ * {@link android.hardware.camera2.CaptureResult }:<ul>
* <li>{@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation}</li>
* <li>{@link CameraCharacteristics#LENS_POSE_ROTATION android.lens.poseRotation}</li>
* <li>android.lens.intrinsicCalibration</li>
@@ -627,13 +630,14 @@
* <p>Generally, depth output operates at a slower frame rate than standard color capture,
* so the DEPTH16 and DEPTH_POINT_CLOUD formats will commonly have a stall duration that
* should be accounted for (see
- * android.hardware.camera2.StreamConfigurationMap#getOutputStallDuration). On a device
- * that supports both depth and color-based output, to enable smooth preview, using a
- * repeating burst is recommended, where a depth-output target is only included once
- * every N frames, where N is the ratio between preview output rate and depth output
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }).
+ * On a device that supports both depth and color-based output, to enable smooth preview,
+ * using a repeating burst is recommended, where a depth-output target is only included
+ * once every N frames, where N is the ratio between preview output rate and depth output
* rate, including depth stall time.</p>
*
* @see CameraCharacteristics#DEPTH_DEPTH_IS_EXCLUSIVE
+ * @see CameraCharacteristics#LENS_FACING
* @see CameraCharacteristics#LENS_POSE_ROTATION
* @see CameraCharacteristics#LENS_POSE_TRANSLATION
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
@@ -707,7 +711,7 @@
/**
* <p>Timestamps from {@link CaptureResult#SENSOR_TIMESTAMP android.sensor.timestamp} are in the same timebase as
- * android.os.SystemClock#elapsedRealtimeNanos(),
+ * {@link android.os.SystemClock#elapsedRealtimeNanos },
* and they can be compared to other timestamps using that base.</p>
*
* @see CaptureResult#SENSOR_TIMESTAMP
@@ -866,7 +870,7 @@
/**
* <p>Every frame has the requests immediately applied.</p>
* <p>Furthermore for all results,
- * <code>android.sync.frameNumber == CaptureResult#getFrameNumber()</code></p>
+ * <code>android.sync.frameNumber == {@link android.hardware.camera2.CaptureResult#getFrameNumber }</code></p>
* <p>Changing controls over multiple requests one after another will
* produce results that have those controls applied atomically
* each frame.</p>
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 19d17b1..ab6ce91 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1275,8 +1275,9 @@
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
* <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains OPAQUE_REPROCESSING. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains MANUAL_SENSOR. Other intent values are always supported.</p>
+ * contains OPAQUE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR. Other intent values are
+ * always supported.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_CAPTURE_INTENT_CUSTOM CUSTOM}</li>
@@ -2039,8 +2040,8 @@
* cannot process more than 1 capture at a time.</li>
* </ul>
* <p>The necessary information for the application, given the model above,
- * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field
- * using StreamConfigurationMap#getOutputMinFrameDuration(int, Size).
+ * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field using
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }.
* These are used to determine the maximum frame rate / minimum frame
* duration that is possible for a given stream configuration.</p>
* <p>Specifically, the application can use the following rules to
@@ -2049,21 +2050,19 @@
* <ol>
* <li>Let the set of currently configured input/output streams
* be called <code>S</code>.</li>
- * <li>Find the minimum frame durations for each stream in <code>S</code>, by
- * looking it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using
- * StreamConfigurationMap#getOutputMinFrameDuration(int, Size) (with
- * its respective size/format). Let this set of frame durations be called
- * <code>F</code>.</li>
+ * <li>Find the minimum frame durations for each stream in <code>S</code>, by looking
+ * it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }
+ * (with its respective size/format). Let this set of frame durations be
+ * called <code>F</code>.</li>
* <li>For any given request <code>R</code>, the minimum frame duration allowed
* for <code>R</code> is the maximum out of all values in <code>F</code>. Let the streams
* used in <code>R</code> be called <code>S_r</code>.</li>
* </ol>
- * <p>If none of the streams in <code>S_r</code> have a stall time (listed in
- * StreamConfigurationMap#getOutputStallDuration(int,Size) using its
- * respective size/format), then the frame duration in
- * <code>F</code> determines the steady state frame rate that the application will
- * get if it uses <code>R</code> as a repeating request. Let this special kind
- * of request be called <code>Rsimple</code>.</p>
+ * <p>If none of the streams in <code>S_r</code> have a stall time (listed in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }
+ * using its respective size/format), then the frame duration in <code>F</code>
+ * determines the steady state frame rate that the application will get
+ * if it uses <code>R</code> as a repeating request. Let this special kind of
+ * request be called <code>Rsimple</code>.</p>
* <p>A repeating request <code>Rsimple</code> can be <em>occasionally</em> interleaved
* by a single capture of a new request <code>Rstall</code> (which has at least
* one in-use stream with a non-0 stall time) and if <code>Rstall</code> has the
@@ -2071,7 +2070,7 @@
* if all buffers from the previous <code>Rstall</code> have already been
* delivered.</p>
* <p>For more details about stalling, see
- * StreamConfigurationMap#getOutputStallDuration(int,Size).</p>
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }.</p>
* <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
* OFF; otherwise the auto-exposure algorithm will override this value.</p>
* <p><b>Units</b>: Nanoseconds</p>
@@ -2647,8 +2646,12 @@
* <p><b>Range of valid values:</b><br>
* >= 1.0</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
* @see CaptureRequest#EDGE_MODE
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CaptureRequest#NOISE_REDUCTION_MODE
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index ef5d75c..3dc8970 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1698,8 +1698,9 @@
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
* <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains OPAQUE_REPROCESSING. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains MANUAL_SENSOR. Other intent values are always supported.</p>
+ * contains OPAQUE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if
+ * {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR. Other intent values are
+ * always supported.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #CONTROL_CAPTURE_INTENT_CUSTOM CUSTOM}</li>
@@ -2885,8 +2886,8 @@
* cannot process more than 1 capture at a time.</li>
* </ul>
* <p>The necessary information for the application, given the model above,
- * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field
- * using StreamConfigurationMap#getOutputMinFrameDuration(int, Size).
+ * is provided via the {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} field using
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }.
* These are used to determine the maximum frame rate / minimum frame
* duration that is possible for a given stream configuration.</p>
* <p>Specifically, the application can use the following rules to
@@ -2895,21 +2896,19 @@
* <ol>
* <li>Let the set of currently configured input/output streams
* be called <code>S</code>.</li>
- * <li>Find the minimum frame durations for each stream in <code>S</code>, by
- * looking it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using
- * StreamConfigurationMap#getOutputMinFrameDuration(int, Size) (with
- * its respective size/format). Let this set of frame durations be called
- * <code>F</code>.</li>
+ * <li>Find the minimum frame durations for each stream in <code>S</code>, by looking
+ * it up in {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} using {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }
+ * (with its respective size/format). Let this set of frame durations be
+ * called <code>F</code>.</li>
* <li>For any given request <code>R</code>, the minimum frame duration allowed
* for <code>R</code> is the maximum out of all values in <code>F</code>. Let the streams
* used in <code>R</code> be called <code>S_r</code>.</li>
* </ol>
- * <p>If none of the streams in <code>S_r</code> have a stall time (listed in
- * StreamConfigurationMap#getOutputStallDuration(int,Size) using its
- * respective size/format), then the frame duration in
- * <code>F</code> determines the steady state frame rate that the application will
- * get if it uses <code>R</code> as a repeating request. Let this special kind
- * of request be called <code>Rsimple</code>.</p>
+ * <p>If none of the streams in <code>S_r</code> have a stall time (listed in {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }
+ * using its respective size/format), then the frame duration in <code>F</code>
+ * determines the steady state frame rate that the application will get
+ * if it uses <code>R</code> as a repeating request. Let this special kind of
+ * request be called <code>Rsimple</code>.</p>
* <p>A repeating request <code>Rsimple</code> can be <em>occasionally</em> interleaved
* by a single capture of a new request <code>Rstall</code> (which has at least
* one in-use stream with a non-0 stall time) and if <code>Rstall</code> has the
@@ -2917,7 +2916,7 @@
* if all buffers from the previous <code>Rstall</code> have already been
* delivered.</p>
* <p>For more details about stalling, see
- * StreamConfigurationMap#getOutputStallDuration(int,Size).</p>
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration }.</p>
* <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
* OFF; otherwise the auto-exposure algorithm will override this value.</p>
* <p><b>Units</b>: Nanoseconds</p>
@@ -2979,11 +2978,10 @@
* and are monotonically increasing. They can be compared with the
* timestamps for other captures from the same camera device, but are
* not guaranteed to be comparable to any other time source.</p>
- * <p>When {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE android.sensor.info.timestampSource} <code>==</code> REALTIME,
- * the timestamps measure time in the same timebase as
- * android.os.SystemClock#elapsedRealtimeNanos(), and they can be
- * compared to other timestamps from other subsystems that are using
- * that base.</p>
+ * <p>When {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE android.sensor.info.timestampSource} <code>==</code> REALTIME, the
+ * timestamps measure time in the same timebase as {@link android.os.SystemClock#elapsedRealtimeNanos }, and they can
+ * be compared to other timestamps from other subsystems that
+ * are using that base.</p>
* <p><b>Units</b>: Nanoseconds</p>
* <p><b>Range of valid values:</b><br>
* > 0</p>
@@ -3141,7 +3139,7 @@
* <p><b>Units</b>: Nanoseconds</p>
* <p><b>Range of valid values:</b><br>
* >= 0 and <
- * StreamConfigurationMap#getOutputMinFrameDuration(int, Size).</p>
+ * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration }.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* <p><b>Limited capability</b> -
* Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -3966,8 +3964,12 @@
* <p><b>Range of valid values:</b><br>
* >= 1.0</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
* @see CaptureRequest#EDGE_MODE
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CaptureRequest#NOISE_REDUCTION_MODE
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index adab9be..02793f1 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -182,6 +182,10 @@
// The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter).
public float screenAutoBrightnessAdjustment;
+ // Set to true if screenBrightness and screenAutoBrightnessAdjustment were both
+ // set by the user as opposed to being programmatically controlled by apps.
+ public boolean brightnessSetByUser;
+
// If true, enables automatic brightness control.
public boolean useAutoBrightness;
@@ -229,6 +233,7 @@
useProximitySensor = other.useProximitySensor;
screenBrightness = other.screenBrightness;
screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment;
+ brightnessSetByUser = other.brightnessSetByUser;
useAutoBrightness = other.useAutoBrightness;
blockScreenOn = other.blockScreenOn;
lowPowerMode = other.lowPowerMode;
@@ -249,6 +254,7 @@
&& useProximitySensor == other.useProximitySensor
&& screenBrightness == other.screenBrightness
&& screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment
+ && brightnessSetByUser == other.brightnessSetByUser
&& useAutoBrightness == other.useAutoBrightness
&& blockScreenOn == other.blockScreenOn
&& lowPowerMode == other.lowPowerMode
@@ -268,6 +274,7 @@
+ ", useProximitySensor=" + useProximitySensor
+ ", screenBrightness=" + screenBrightness
+ ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment
+ + ", brightnessSetByUser=" + brightnessSetByUser
+ ", useAutoBrightness=" + useAutoBrightness
+ ", blockScreenOn=" + blockScreenOn
+ ", lowPowerMode=" + lowPowerMode
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index a7d9503..ca37d49 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -214,7 +214,7 @@
sConstructors.put(className, constructor);
}
}
-
+ constructor.setAccessible(true);
return constructor.newInstance(mContext, attrs);
}
} catch (InstantiationException e) {
diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java
index aefced8..558b8f5 100644
--- a/core/java/android/util/EventLog.java
+++ b/core/java/android/util/EventLog.java
@@ -74,6 +74,7 @@
private static final byte LONG_TYPE = 1;
private static final byte STRING_TYPE = 2;
private static final byte LIST_TYPE = 3;
+ private static final byte FLOAT_TYPE = 4;
/** @param data containing event, read from the system */
/*package*/ Event(byte[] data) {
@@ -106,7 +107,7 @@
return mBuffer.getInt(offset);
}
- /** @return one of Integer, Long, String, null, or Object[] of same. */
+ /** @return one of Integer, Long, Float, String, null, or Object[] of same. */
public synchronized Object getData() {
try {
int offset = mBuffer.getShort(HEADER_SIZE_OFFSET);
@@ -130,10 +131,13 @@
byte type = mBuffer.get();
switch (type) {
case INT_TYPE:
- return (Integer) mBuffer.getInt();
+ return mBuffer.getInt();
case LONG_TYPE:
- return (Long) mBuffer.getLong();
+ return mBuffer.getLong();
+
+ case FLOAT_TYPE:
+ return mBuffer.getFloat();
case STRING_TYPE:
try {
@@ -180,6 +184,14 @@
/**
* Record an event log message.
* @param tag The event type tag code
+ * @param value A value to log
+ * @return The number of bytes written
+ */
+ public static native int writeEvent(int tag, float value);
+
+ /**
+ * Record an event log message.
+ * @param tag The event type tag code
* @param str A value to log
* @return The number of bytes written
*/
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index eedbc70..46dd857 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -234,25 +234,13 @@
* Draws the specified display list onto this canvas. The display list can only
* be drawn if {@link android.view.RenderNode#isValid()} returns true.
*
- * @param renderNode The RenderNode to replay.
+ * @param renderNode The RenderNode to draw.
*/
public void drawRenderNode(RenderNode renderNode) {
- drawRenderNode(renderNode, RenderNode.FLAG_CLIP_CHILDREN);
+ nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList());
}
- /**
- * Draws the specified display list onto this canvas.
- *
- * @param renderNode The RenderNode to replay.
- * @param flags Optional flags about drawing, see {@link RenderNode} for
- * the possible flags.
- */
- public void drawRenderNode(RenderNode renderNode, int flags) {
- nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList(), flags);
- }
-
- private static native void nDrawRenderNode(long renderer, long renderNode,
- int flags);
+ private static native void nDrawRenderNode(long renderer, long renderNode);
///////////////////////////////////////////////////////////////////////////
// Hardware layer
diff --git a/core/java/android/view/PhoneWindow.java b/core/java/android/view/PhoneWindow.java
index 794c8e7..a3e7a10 100644
--- a/core/java/android/view/PhoneWindow.java
+++ b/core/java/android/view/PhoneWindow.java
@@ -3599,7 +3599,7 @@
if (!mForcedNavigationBarColor) {
mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000);
}
- if (a.getBoolean(R.styleable.Window_windowHasLightStatusBar, false)) {
+ if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
decor.setSystemUiVisibility(
decor.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7da2da4..fa74797 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -30,6 +30,7 @@
import android.annotation.Size;
import android.content.ClipData;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
@@ -2591,7 +2592,7 @@
* {@link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_STATUS
* FLAG_TRANSLUCENT_STATUS}.
*
- * @see android.R.attr#windowHasLightStatusBar
+ * @see android.R.attr#windowLightStatusBar
*/
public static final int SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000;
@@ -4016,37 +4017,7 @@
final String handlerName = a.getString(attr);
if (handlerName != null) {
- setOnClickListener(new OnClickListener() {
- private Method mHandler;
-
- public void onClick(View v) {
- if (mHandler == null) {
- try {
- mHandler = getContext().getClass().getMethod(handlerName,
- View.class);
- } catch (NoSuchMethodException e) {
- int id = getId();
- String idText = id == NO_ID ? "" : " with id '"
- + getContext().getResources().getResourceEntryName(
- id) + "'";
- throw new IllegalStateException("Could not find a method " +
- handlerName + "(View) in the activity "
- + getContext().getClass() + " for onClick handler"
- + " on view " + View.this.getClass() + idText, e);
- }
- }
-
- try {
- mHandler.invoke(getContext(), View.this);
- } catch (IllegalAccessException e) {
- throw new IllegalStateException("Could not execute non "
- + "public method of the activity", e);
- } catch (InvocationTargetException e) {
- throw new IllegalStateException("Could not execute "
- + "method of the activity", e);
- }
- }
- });
+ setOnClickListener(new DeclaredOnClickListener(this, handlerName));
}
break;
case R.styleable.View_overScrollMode:
@@ -4238,6 +4209,66 @@
}
/**
+ * An implementation of OnClickListener that attempts to lazily load a
+ * named click handling method from a parent or ancestor context.
+ */
+ private static class DeclaredOnClickListener implements OnClickListener {
+ private final View mHostView;
+ private final String mMethodName;
+
+ private Method mMethod;
+
+ public DeclaredOnClickListener(@NonNull View hostView, @NonNull String methodName) {
+ mHostView = hostView;
+ mMethodName = methodName;
+ }
+
+ @Override
+ public void onClick(@NonNull View v) {
+ if (mMethod == null) {
+ mMethod = resolveMethod(mHostView.getContext(), mMethodName);
+ }
+
+ try {
+ mMethod.invoke(mHostView.getContext(), v);
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException(
+ "Could not execute non-public method for android:onClick", e);
+ } catch (InvocationTargetException e) {
+ throw new IllegalStateException(
+ "Could not execute method for android:onClick", e);
+ }
+ }
+
+ @NonNull
+ private Method resolveMethod(@Nullable Context context, @NonNull String name) {
+ while (context != null) {
+ try {
+ if (!context.isRestricted()) {
+ return context.getClass().getMethod(mMethodName, View.class);
+ }
+ } catch (NoSuchMethodException e) {
+ // Failed to find method, keep searching up the hierarchy.
+ }
+
+ if (context instanceof ContextWrapper) {
+ context = ((ContextWrapper) context).getBaseContext();
+ } else {
+ // Can't search up the hierarchy, null out and fail.
+ context = null;
+ }
+ }
+
+ final int id = mHostView.getId();
+ final String idText = id == NO_ID ? "" : " with id '"
+ + mHostView.getContext().getResources().getResourceEntryName(id) + "'";
+ throw new IllegalStateException("Could not find method " + mMethodName
+ + "(View) in a parent or ancestor Context for android:onClick "
+ + "attribute defined on view " + mHostView.getClass() + idText);
+ }
+ }
+
+ /**
* Non-public constructor for use in testing
*/
View() {
@@ -15509,7 +15540,7 @@
if (!drawingWithDrawingCache) {
if (drawingWithRenderNode) {
mPrivateFlags &= ~PFLAG_DIRTY_MASK;
- ((DisplayListCanvas) canvas).drawRenderNode(renderNode, parentFlags);
+ ((DisplayListCanvas) canvas).drawRenderNode(renderNode);
} else {
// Fast path for layouts with no backgrounds
if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
diff --git a/core/java/android/widget/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java
index 478fa00..d271af2 100644
--- a/core/java/android/widget/DayPickerPagerAdapter.java
+++ b/core/java/android/widget/DayPickerPagerAdapter.java
@@ -286,14 +286,10 @@
return null;
}
- private boolean isCalendarInRange(Calendar value) {
- return value.compareTo(mMinDate) >= 0 && value.compareTo(mMaxDate) <= 0;
- }
-
private final OnDayClickListener mOnDayClickListener = new OnDayClickListener() {
@Override
public void onDayClick(SimpleMonthView view, Calendar day) {
- if (day != null && isCalendarInRange(day)) {
+ if (day != null) {
setSelectedDay(day);
if (mOnDaySelectedListener != null) {
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index 113e597..334afab 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -178,6 +178,13 @@
});
}
+ private void updateButtonVisibility(int position) {
+ final boolean hasPrev = position > 0;
+ final boolean hasNext = position < (mAdapter.getCount() - 1);
+ mPrevButton.setVisibility(hasPrev ? View.VISIBLE : View.INVISIBLE);
+ mNextButton.setVisibility(hasNext ? View.VISIBLE : View.INVISIBLE);
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final ViewPager viewPager = mViewPager;
@@ -218,12 +225,6 @@
final int height = bottom - top;
mViewPager.layout(0, 0, width, height);
- if (mViewPager.getChildCount() < 1) {
- leftButton.setVisibility(View.INVISIBLE);
- rightButton.setVisibility(View.INVISIBLE);
- return;
- }
-
final SimpleMonthView monthView = (SimpleMonthView) mViewPager.getChildAt(0);
final int monthHeight = monthView.getMonthHeight();
final int cellWidth = monthView.getCellWidth();
@@ -235,7 +236,6 @@
final int leftIconTop = monthView.getPaddingTop() + (monthHeight - leftDH) / 2;
final int leftIconLeft = monthView.getPaddingLeft() + (cellWidth - leftDW) / 2;
leftButton.layout(leftIconLeft, leftIconTop, leftIconLeft + leftDW, leftIconTop + leftDH);
- leftButton.setVisibility(View.VISIBLE);
final int rightDW = rightButton.getMeasuredWidth();
final int rightDH = rightButton.getMeasuredHeight();
@@ -243,7 +243,6 @@
final int rightIconRight = width - monthView.getPaddingRight() - (cellWidth - rightDW) / 2;
rightButton.layout(rightIconRight - rightDW, rightIconTop,
rightIconRight, rightIconTop + rightDH);
- rightButton.setVisibility(View.VISIBLE);
}
public void setDayOfWeekTextAppearance(int resId) {
@@ -399,10 +398,7 @@
@Override
public void onPageSelected(int position) {
- mPrevButton.setVisibility(
- position > 0 ? View.VISIBLE : View.INVISIBLE);
- mNextButton.setVisibility(
- position < (mAdapter.getCount() - 1) ? View.VISIBLE : View.INVISIBLE);
+ updateButtonVisibility(position);
}
};
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 39b9907..089074a 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -145,16 +145,16 @@
InputContentType mInputContentType;
InputMethodState mInputMethodState;
- private static class TextDisplayList {
- RenderNode displayList;
+ private static class TextRenderNode {
+ RenderNode renderNode;
boolean isDirty;
- public TextDisplayList(String name) {
+ public TextRenderNode(String name) {
isDirty = true;
- displayList = RenderNode.create(name, null);
+ renderNode = RenderNode.create(name, null);
}
- boolean needsRecord() { return isDirty || !displayList.isValid(); }
+ boolean needsRecord() { return isDirty || !renderNode.isValid(); }
}
- TextDisplayList[] mTextDisplayLists;
+ TextRenderNode[] mTextRenderNodes;
boolean mFrozenWithFocus;
boolean mSelectionMoved;
@@ -360,10 +360,10 @@
}
private void destroyDisplayListsData() {
- if (mTextDisplayLists != null) {
- for (int i = 0; i < mTextDisplayLists.length; i++) {
- RenderNode displayList = mTextDisplayLists[i] != null
- ? mTextDisplayLists[i].displayList : null;
+ if (mTextRenderNodes != null) {
+ for (int i = 0; i < mTextRenderNodes.length; i++) {
+ RenderNode displayList = mTextRenderNodes[i] != null
+ ? mTextRenderNodes[i].renderNode : null;
if (displayList != null && displayList.isValid()) {
displayList.destroyDisplayListData();
}
@@ -1467,8 +1467,8 @@
firstLine, lastLine);
if (layout instanceof DynamicLayout) {
- if (mTextDisplayLists == null) {
- mTextDisplayLists = ArrayUtils.emptyArray(TextDisplayList.class);
+ if (mTextRenderNodes == null) {
+ mTextRenderNodes = ArrayUtils.emptyArray(TextRenderNode.class);
}
DynamicLayout dynamicLayout = (DynamicLayout) layout;
@@ -1489,19 +1489,19 @@
searchStartIndex);
// Note how dynamic layout's internal block indices get updated from Editor
blockIndices[i] = blockIndex;
- if (mTextDisplayLists[blockIndex] != null) {
- mTextDisplayLists[blockIndex].isDirty = true;
+ if (mTextRenderNodes[blockIndex] != null) {
+ mTextRenderNodes[blockIndex].isDirty = true;
}
searchStartIndex = blockIndex + 1;
}
- if (mTextDisplayLists[blockIndex] == null) {
- mTextDisplayLists[blockIndex] =
- new TextDisplayList("Text " + blockIndex);
+ if (mTextRenderNodes[blockIndex] == null) {
+ mTextRenderNodes[blockIndex] =
+ new TextRenderNode("Text " + blockIndex);
}
- final boolean blockDisplayListIsInvalid = mTextDisplayLists[blockIndex].needsRecord();
- RenderNode blockDisplayList = mTextDisplayLists[blockIndex].displayList;
+ final boolean blockDisplayListIsInvalid = mTextRenderNodes[blockIndex].needsRecord();
+ RenderNode blockDisplayList = mTextRenderNodes[blockIndex].renderNode;
if (i >= indexFirstChangedBlock || blockDisplayListIsInvalid) {
final int blockBeginLine = endOfPreviousBlock + 1;
final int top = layout.getLineTop(blockBeginLine);
@@ -1528,7 +1528,7 @@
// brings this range of text back to the top left corner of the viewport
displayListCanvas.translate(-left, -top);
layout.drawText(displayListCanvas, blockBeginLine, blockEndLine);
- mTextDisplayLists[blockIndex].isDirty = false;
+ mTextRenderNodes[blockIndex].isDirty = false;
// No need to untranslate, previous context is popped after
// drawDisplayList
} finally {
@@ -1543,8 +1543,7 @@
blockDisplayList.setLeftTopRightBottom(left, top, right, bottom);
}
- ((DisplayListCanvas) canvas).drawRenderNode(blockDisplayList,
- 0 /* no child clipping, our TextView parent enforces it */);
+ ((DisplayListCanvas) canvas).drawRenderNode(blockDisplayList);
endOfPreviousBlock = blockEndLine;
}
@@ -1558,7 +1557,7 @@
private int getAvailableDisplayListIndex(int[] blockIndices, int numberOfBlocks,
int searchStartIndex) {
- int length = mTextDisplayLists.length;
+ int length = mTextRenderNodes.length;
for (int i = searchStartIndex; i < length; i++) {
boolean blockIndexFound = false;
for (int j = 0; j < numberOfBlocks; j++) {
@@ -1572,7 +1571,7 @@
}
// No available index found, the pool has to grow
- mTextDisplayLists = GrowingArrayUtils.append(mTextDisplayLists, length, null);
+ mTextRenderNodes = GrowingArrayUtils.append(mTextRenderNodes, length, null);
return length;
}
@@ -1589,7 +1588,7 @@
* Invalidates all the sub-display lists that overlap the specified character range
*/
void invalidateTextDisplayList(Layout layout, int start, int end) {
- if (mTextDisplayLists != null && layout instanceof DynamicLayout) {
+ if (mTextRenderNodes != null && layout instanceof DynamicLayout) {
final int firstLine = layout.getLineForOffset(start);
final int lastLine = layout.getLineForOffset(end);
@@ -1609,7 +1608,7 @@
while (i < numberOfBlocks) {
final int blockIndex = blockIndices[i];
if (blockIndex != DynamicLayout.INVALID_BLOCK_INDEX) {
- mTextDisplayLists[blockIndex].isDirty = true;
+ mTextRenderNodes[blockIndex].isDirty = true;
}
if (blockEndLines[i] >= lastLine) break;
i++;
@@ -1618,9 +1617,9 @@
}
void invalidateTextDisplayList() {
- if (mTextDisplayLists != null) {
- for (int i = 0; i < mTextDisplayLists.length; i++) {
- if (mTextDisplayLists[i] != null) mTextDisplayLists[i].isDirty = true;
+ if (mTextRenderNodes != null) {
+ for (int i = 0; i < mTextRenderNodes.length; i++) {
+ if (mTextRenderNodes[i] != null) mTextRenderNodes[i].isDirty = true;
}
}
}
@@ -4491,7 +4490,7 @@
private class CorrectionHighlighter {
private final Path mPath = new Path();
- private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private final Paint mPaint = new Paint();
private int mStart, mEnd;
private long mFadingStartTime;
private RectF mTempRectF;
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index 2778f0f..acf1df9 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -31,6 +31,7 @@
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.util.IntArray;
+import android.util.MathUtils;
import android.util.StateSet;
import android.view.MotionEvent;
import android.view.View;
@@ -422,7 +423,8 @@
int stateMask = 0;
- if (day >= mEnabledDayStart && day <= mEnabledDayEnd) {
+ final boolean isDayEnabled = isDayEnabled(day);
+ if (isDayEnabled) {
stateMask |= StateSet.VIEW_STATE_ENABLED;
}
@@ -435,8 +437,11 @@
} else if (mTouchedItem == day) {
stateMask |= StateSet.VIEW_STATE_PRESSED;
- // Adjust the circle to be centered on the row.
- canvas.drawCircle(colCenterRtl, rowCenter, mDaySelectorRadius, mDayHighlightPaint);
+ if (isDayEnabled) {
+ // Adjust the circle to be centered on the row.
+ canvas.drawCircle(colCenterRtl, rowCenter,
+ mDaySelectorRadius, mDayHighlightPaint);
+ }
}
final boolean isDayToday = mToday == day;
@@ -460,6 +465,14 @@
}
}
+ private boolean isDayEnabled(int day) {
+ return day >= mEnabledDayStart && day <= mEnabledDayEnd;
+ }
+
+ private boolean isValidDayOfMonth(int day) {
+ return day >= 1 && day <= mDaysInMonth;
+ }
+
private static boolean isValidDayOfWeek(int day) {
return day >= Calendar.SUNDAY && day <= Calendar.SATURDAY;
}
@@ -536,13 +549,6 @@
mWeekStart = mCalendar.getFirstDayOfWeek();
}
- if (enabledDayStart > 0 && enabledDayEnd < 32) {
- mEnabledDayStart = enabledDayStart;
- }
- if (enabledDayEnd > 0 && enabledDayEnd < 32 && enabledDayEnd >= enabledDayStart) {
- mEnabledDayEnd = enabledDayEnd;
- }
-
// Figure out what day today is.
final Calendar today = Calendar.getInstance();
mToday = -1;
@@ -554,6 +560,9 @@
}
}
+ mEnabledDayStart = MathUtils.constrain(enabledDayStart, 1, mDaysInMonth);
+ mEnabledDayEnd = MathUtils.constrain(enabledDayEnd, mEnabledDayStart, mDaysInMonth);
+
// Invalidate the old title.
mTitle = null;
@@ -694,7 +703,7 @@
final int col = (paddedXRtl * DAYS_IN_WEEK) / mPaddedWidth;
final int index = col + row * DAYS_IN_WEEK;
final int day = index + 1 - findDayOffset();
- if (day < 1 || day > mDaysInMonth) {
+ if (!isValidDayOfMonth(day)) {
return -1;
}
@@ -708,7 +717,7 @@
* @param outBounds the rect to populate with bounds
*/
private boolean getBoundsForDay(int id, Rect outBounds) {
- if (id < 1 || id > mDaysInMonth) {
+ if (!isValidDayOfMonth(id)) {
return false;
}
@@ -742,7 +751,7 @@
* @param day the day that was clicked
*/
private boolean onDayClicked(int day) {
- if (day < 0 || day > mDaysInMonth) {
+ if (!isValidDayOfMonth(day) || !isDayEnabled(day)) {
return false;
}
@@ -774,7 +783,7 @@
@Override
protected int getVirtualViewAt(float x, float y) {
final int day = getDayAtLocation((int) (x + 0.5f), (int) (y + 0.5f));
- if (day >= 0) {
+ if (day != -1) {
return day;
}
return ExploreByTouchHelper.INVALID_ID;
@@ -808,7 +817,13 @@
node.setText(getDayText(virtualViewId));
node.setContentDescription(getDayDescription(virtualViewId));
node.setBoundsInParent(mTempRect);
- node.addAction(AccessibilityAction.ACTION_CLICK);
+
+ final boolean isDayEnabled = isDayEnabled(virtualViewId);
+ if (isDayEnabled) {
+ node.addAction(AccessibilityAction.ACTION_CLICK);
+ }
+
+ node.setEnabled(isDayEnabled);
if (virtualViewId == mActivatedDay) {
// TODO: This should use activated once that's supported.
@@ -835,7 +850,7 @@
* @return a description of the virtual view
*/
private CharSequence getDayDescription(int id) {
- if (id >= 1 && id <= mDaysInMonth) {
+ if (isValidDayOfMonth(id)) {
mTempCalendar.set(mYear, mMonth, id);
return DateFormat.format(DATE_FORMAT, mTempCalendar.getTimeInMillis());
}
@@ -850,7 +865,7 @@
* @return the visible text of the virtual view
*/
private CharSequence getDayText(int id) {
- if (id >= 1 && id <= mDaysInMonth) {
+ if (isValidDayOfMonth(id)) {
return Integer.toString(id);
}
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index ae779fe..f94f97c 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -216,7 +216,7 @@
public Switch(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint = new TextPaint();
final Resources res = getResources();
mTextPaint.density = res.getDisplayMetrics().density;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3e8df08..8ce5f08 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -668,11 +668,11 @@
final Resources res = getResources();
final CompatibilityInfo compat = res.getCompatibilityInfo();
- mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint = new TextPaint();
mTextPaint.density = res.getDisplayMetrics().density;
mTextPaint.setCompatibilityScaling(compat.applicationScale);
- mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mHighlightPaint = new Paint();
mHighlightPaint.setCompatibilityScaling(compat.applicationScale);
mMovement = getDefaultMovementMethod();
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 2b77b2c..e347faa 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -405,8 +405,10 @@
int launchedFromUid, boolean filterLastUsed, ChooserTarget[] callerChooserTargets) {
super(context, initialIntents, rList, launchedFromUid, filterLastUsed);
- for (ChooserTarget target : callerChooserTargets) {
- mCallerTargets.add(new ChooserTargetInfo(target));
+ if (callerChooserTargets != null) {
+ for (ChooserTarget target : callerChooserTargets) {
+ mCallerTargets.add(new ChooserTargetInfo(target));
+ }
}
}
diff --git a/core/java/com/android/internal/midi/MidiFramer.java b/core/java/com/android/internal/midi/MidiFramer.java
index 53d71bb..1a7fa0b 100644
--- a/core/java/com/android/internal/midi/MidiFramer.java
+++ b/core/java/com/android/internal/midi/MidiFramer.java
@@ -17,6 +17,7 @@
package com.android.internal.midi;
import android.media.midi.MidiReceiver;
+import android.util.Log;
import java.io.IOException;
@@ -38,6 +39,7 @@
private int mCount;
private int mRunningStatus;
private int mNeeded;
+ private boolean mInSysEx;
public MidiFramer(MidiReceiver receiver) {
mReceiver = receiver;
@@ -52,12 +54,14 @@
}
/*
- * @see android.midi.MidiReceiver#onPost(byte[], int, int, long)
+ * @see android.midi.MidiReceiver#onReceive(byte[], int, int, long)
*/
@Override
public void onReceive(byte[] data, int offset, int count, long timestamp)
throws IOException {
// Log.i(TAG, formatMidiData(data, offset, count));
+ int sysExStartOffset = (mInSysEx ? offset : -1);
+
for (int i = 0; i < count; i++) {
int b = data[offset] & 0xFF;
if (b >= 0x80) { // status byte?
@@ -66,27 +70,50 @@
mCount = 1;
mNeeded = MidiConstants.getBytesPerMessage(b) - 1;
} else if (b < 0xF8) { // system common?
- mBuffer[0] = (byte) b;
- mRunningStatus = 0;
- mCount = 1;
- mNeeded = MidiConstants.getBytesPerMessage(b) - 1;
+ if (b == 0xF0 /* SysEx Start */) {
+ // Log.i(TAG, "SysEx Start");
+ mInSysEx = true;
+ sysExStartOffset = offset;
+ } else if (b == 0xF7 /* SysEx End */) {
+ // Log.i(TAG, "SysEx End");
+ if (mInSysEx) {
+ mReceiver.sendWithTimestamp(data, sysExStartOffset,
+ offset - sysExStartOffset, timestamp);
+ mInSysEx = false;
+ sysExStartOffset = -1;
+ }
+ } else {
+ mBuffer[0] = (byte) b;
+ mRunningStatus = 0;
+ mCount = 1;
+ mNeeded = MidiConstants.getBytesPerMessage(b) - 1;
+ }
} else { // real-time?
// Single byte message interleaved with other data.
mReceiver.sendWithTimestamp(data, offset, 1, timestamp);
}
} else { // data byte
- mBuffer[mCount++] = (byte) b;
- if (--mNeeded == 0) {
- if (mRunningStatus != 0) {
- mBuffer[0] = (byte) mRunningStatus;
+ // Save SysEx data for SysEx End marker or end of buffer.
+ if (!mInSysEx) {
+ mBuffer[mCount++] = (byte) b;
+ if (--mNeeded == 0) {
+ if (mRunningStatus != 0) {
+ mBuffer[0] = (byte) mRunningStatus;
+ }
+ mReceiver.sendWithTimestamp(mBuffer, 0, mCount, timestamp);
+ mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1;
+ mCount = 1;
}
- mReceiver.sendWithTimestamp(mBuffer, 0, mCount, timestamp);
- mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1;
- mCount = 1;
}
}
++offset;
}
+
+ // send any accumulatedSysEx data
+ if (sysExStartOffset >= 0) {
+ mReceiver.sendWithTimestamp(data, sysExStartOffset,
+ offset - sysExStartOffset, timestamp);
+ }
}
}
diff --git a/core/java/com/android/internal/util/ImageUtils.java b/core/java/com/android/internal/util/ImageUtils.java
index 7d56e9e..a0d0b20 100644
--- a/core/java/com/android/internal/util/ImageUtils.java
+++ b/core/java/com/android/internal/util/ImageUtils.java
@@ -66,7 +66,7 @@
COMPACT_BITMAP_SIZE, COMPACT_BITMAP_SIZE, Bitmap.Config.ARGB_8888
);
mTempCompactBitmapCanvas = new Canvas(mTempCompactBitmap);
- mTempCompactBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mTempCompactBitmapPaint = new Paint();
mTempCompactBitmapPaint.setFilterBitmap(true);
}
mTempMatrix.reset();
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 1096e34..3d23986 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -17,9 +17,11 @@
package com.android.internal.widget;
import android.Manifest;
+import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
+import android.bluetooth.BluetoothClass;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -142,11 +144,6 @@
private DevicePolicyManager mDevicePolicyManager;
private ILockSettings mLockSettingsService;
- private final boolean mMultiUserMode;
-
- // The current user is set by KeyguardViewMediator and shared by all LockPatternUtils.
- private static volatile int sCurrentUserId = UserHandle.USER_NULL;
-
public DevicePolicyManager getDevicePolicyManager() {
if (mDevicePolicyManager == null) {
mDevicePolicyManager =
@@ -171,12 +168,6 @@
public LockPatternUtils(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
-
- // If this is being called by the system or by an application like keyguard that
- // has permision INTERACT_ACROSS_USERS, then LockPatternUtils will operate in multi-user
- // mode where calls are for the current user rather than the user of the calling process.
- mMultiUserMode = context.checkCallingOrSelfPermission(
- Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PackageManager.PERMISSION_GRANTED;
}
private ILockSettings getLockSettings() {
@@ -188,93 +179,55 @@
return mLockSettingsService;
}
- public int getRequestedMinimumPasswordLength() {
- return getDevicePolicyManager().getPasswordMinimumLength(null, getCurrentOrCallingUserId());
+ public int getRequestedMinimumPasswordLength(int userId) {
+ return getDevicePolicyManager().getPasswordMinimumLength(null, userId);
}
/**
* Gets the device policy password mode. If the mode is non-specific, returns
* MODE_PATTERN which allows the user to choose anything.
*/
- public int getRequestedPasswordQuality() {
- return getDevicePolicyManager().getPasswordQuality(null, getCurrentOrCallingUserId());
- }
-
- public int getRequestedPasswordHistoryLength() {
- return getRequestedPasswordHistoryLength(getCurrentOrCallingUserId());
+ public int getRequestedPasswordQuality(int userId) {
+ return getDevicePolicyManager().getPasswordQuality(null, userId);
}
private int getRequestedPasswordHistoryLength(int userId) {
return getDevicePolicyManager().getPasswordHistoryLength(null, userId);
}
- public int getRequestedPasswordMinimumLetters() {
- return getDevicePolicyManager().getPasswordMinimumLetters(null,
- getCurrentOrCallingUserId());
+ public int getRequestedPasswordMinimumLetters(int userId) {
+ return getDevicePolicyManager().getPasswordMinimumLetters(null, userId);
}
- public int getRequestedPasswordMinimumUpperCase() {
- return getDevicePolicyManager().getPasswordMinimumUpperCase(null,
- getCurrentOrCallingUserId());
+ public int getRequestedPasswordMinimumUpperCase(int userId) {
+ return getDevicePolicyManager().getPasswordMinimumUpperCase(null, userId);
}
- public int getRequestedPasswordMinimumLowerCase() {
- return getDevicePolicyManager().getPasswordMinimumLowerCase(null,
- getCurrentOrCallingUserId());
+ public int getRequestedPasswordMinimumLowerCase(int userId) {
+ return getDevicePolicyManager().getPasswordMinimumLowerCase(null, userId);
}
- public int getRequestedPasswordMinimumNumeric() {
- return getDevicePolicyManager().getPasswordMinimumNumeric(null,
- getCurrentOrCallingUserId());
+ public int getRequestedPasswordMinimumNumeric(int userId) {
+ return getDevicePolicyManager().getPasswordMinimumNumeric(null, userId);
}
- public int getRequestedPasswordMinimumSymbols() {
- return getDevicePolicyManager().getPasswordMinimumSymbols(null,
- getCurrentOrCallingUserId());
+ public int getRequestedPasswordMinimumSymbols(int userId) {
+ return getDevicePolicyManager().getPasswordMinimumSymbols(null, userId);
}
- public int getRequestedPasswordMinimumNonLetter() {
- return getDevicePolicyManager().getPasswordMinimumNonLetter(null,
- getCurrentOrCallingUserId());
+ public int getRequestedPasswordMinimumNonLetter(int userId) {
+ return getDevicePolicyManager().getPasswordMinimumNonLetter(null, userId);
}
- public void reportFailedPasswordAttempt() {
- int userId = getCurrentOrCallingUserId();
+ public void reportFailedPasswordAttempt(int userId) {
getDevicePolicyManager().reportFailedPasswordAttempt(userId);
getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
getTrustManager().reportRequireCredentialEntry(userId);
}
- public void reportSuccessfulPasswordAttempt() {
- getDevicePolicyManager().reportSuccessfulPasswordAttempt(getCurrentOrCallingUserId());
- getTrustManager().reportUnlockAttempt(true /* authenticated */,
- getCurrentOrCallingUserId());
- }
-
- public void setCurrentUser(int userId) {
- sCurrentUserId = userId;
- }
-
- public int getCurrentUser() {
- if (sCurrentUserId != UserHandle.USER_NULL) {
- // Someone is regularly updating using setCurrentUser() use that value.
- return sCurrentUserId;
- }
- try {
- return ActivityManagerNative.getDefault().getCurrentUser().id;
- } catch (RemoteException re) {
- return UserHandle.USER_OWNER;
- }
- }
-
- private int getCurrentOrCallingUserId() {
- if (mMultiUserMode) {
- // TODO: This is a little inefficient. See if all users of this are able to
- // handle USER_CURRENT and pass that instead.
- return getCurrentUser();
- } else {
- return UserHandle.getCallingUserId();
- }
+ public void reportSuccessfulPasswordAttempt(int userId) {
+ getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
+ getTrustManager().reportUnlockAttempt(true /* authenticated */, userId);
}
/**
@@ -286,8 +239,7 @@
* @param challenge The challenge to verify against the pattern
* @return the attestation that the challenge was verified, or null.
*/
- public byte[] verifyPattern(List<LockPatternView.Cell> pattern, long challenge) {
- final int userId = getCurrentOrCallingUserId();
+ public byte[] verifyPattern(List<LockPatternView.Cell> pattern, long challenge, int userId) {
try {
return getLockSettings().verifyPattern(patternToString(pattern), challenge, userId);
} catch (RemoteException re) {
@@ -301,8 +253,7 @@
* @param pattern The pattern to check.
* @return Whether the pattern matches the stored one.
*/
- public boolean checkPattern(List<LockPatternView.Cell> pattern) {
- final int userId = getCurrentOrCallingUserId();
+ public boolean checkPattern(List<LockPatternView.Cell> pattern, int userId) {
try {
return getLockSettings().checkPattern(patternToString(pattern), userId);
} catch (RemoteException re) {
@@ -319,8 +270,7 @@
* @param challenge The challenge to verify against the password
* @return the attestation that the challenge was verified, or null.
*/
- public byte[] verifyPassword(String password, long challenge) {
- final int userId = getCurrentOrCallingUserId();
+ public byte[] verifyPassword(String password, long challenge, int userId) {
try {
return getLockSettings().verifyPassword(password, challenge, userId);
} catch (RemoteException re) {
@@ -334,8 +284,7 @@
* @param password The password to check.
* @return Whether the password matches the stored one.
*/
- public boolean checkPassword(String password) {
- final int userId = getCurrentOrCallingUserId();
+ public boolean checkPassword(String password, int userId) {
try {
return getLockSettings().checkPassword(password, userId);
} catch (RemoteException re) {
@@ -348,8 +297,7 @@
* Note that this also clears vold's copy of the password.
* @return Whether the vold password matches or not.
*/
- public boolean checkVoldPassword() {
- final int userId = getCurrentOrCallingUserId();
+ public boolean checkVoldPassword(int userId) {
try {
return getLockSettings().checkVoldPassword(userId);
} catch (RemoteException re) {
@@ -364,8 +312,7 @@
* @param password The password to check.
* @return Whether the password matches any in the history.
*/
- public boolean checkPasswordHistory(String password) {
- int userId = getCurrentOrCallingUserId();
+ public boolean checkPasswordHistory(String password, int userId) {
String passwordHashString = new String(
passwordToHash(password, userId), StandardCharsets.UTF_8);
String passwordHistory = getString(PASSWORD_HISTORY_KEY, userId);
@@ -374,7 +321,7 @@
}
// Password History may be too long...
int passwordHashLength = passwordHashString.length();
- int passwordHistoryLength = getRequestedPasswordHistoryLength();
+ int passwordHistoryLength = getRequestedPasswordHistoryLength(userId);
if(passwordHistoryLength == 0) {
return false;
}
@@ -416,16 +363,8 @@
*
* @return True if the user has ever chosen a pattern.
*/
- public boolean isPatternEverChosen() {
- return getBoolean(PATTERN_EVER_CHOSEN_KEY, false, getCurrentOrCallingUserId());
- }
-
- /**
- * Used by device policy manager to validate the current password
- * information it has.
- */
- public int getActivePasswordQuality() {
- return getActivePasswordQuality(getCurrentOrCallingUserId());
+ public boolean isPatternEverChosen(int userId) {
+ return getBoolean(PATTERN_EVER_CHOSEN_KEY, false, userId);
}
/**
@@ -448,10 +387,6 @@
return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
}
- public void clearLock() {
- clearLock(getCurrentOrCallingUserId());
- }
-
/**
* Clear any lock pattern or password.
*/
@@ -479,16 +414,6 @@
}
/**
- * Disable showing lock screen at all when the DevicePolicyManager allows it.
- * This is only meaningful if pattern, pin or password are not set.
- *
- * @param disable Disables lock screen when true
- */
- public void setLockScreenDisabled(boolean disable) {
- setLockScreenDisabled(disable, getCurrentOrCallingUserId());
- }
-
- /**
* Disable showing lock screen at all for a given user.
* This is only meaningful if pattern, pin or password are not set.
*
@@ -505,21 +430,16 @@
*
* @return true if lock screen is disabled
*/
- public boolean isLockScreenDisabled() {
- return !isSecure() &&
- getBoolean(DISABLE_LOCKSCREEN_KEY, false, getCurrentOrCallingUserId());
+ public boolean isLockScreenDisabled(int userId) {
+ return !isSecure(userId) &&
+ getBoolean(DISABLE_LOCKSCREEN_KEY, false, userId);
}
/**
* Save a lock pattern.
* @param pattern The new pattern to save.
- * @param savedPattern The previously saved pattern, or null if none
+ * @param userId the user whose pattern is to be saved.
*/
- public void saveLockPattern(List<LockPatternView.Cell> pattern,
- String savedPattern) {
- this.saveLockPattern(pattern, savedPattern, getCurrentOrCallingUserId());
- }
-
public void saveLockPattern(List<LockPatternView.Cell> pattern, int userId) {
this.saveLockPattern(pattern, null, userId);
}
@@ -588,8 +508,7 @@
updateCryptoUserInfo(userId);
}
- public void setOwnerInfoEnabled(boolean enabled) {
- int userId = getCurrentOrCallingUserId();
+ public void setOwnerInfoEnabled(boolean enabled, int userId) {
setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId);
updateCryptoUserInfo(userId);
}
@@ -598,11 +517,7 @@
return getString(LOCK_SCREEN_OWNER_INFO, userId);
}
- public boolean isOwnerInfoEnabled() {
- return isOwnerInfoEnabled(getCurrentOrCallingUserId());
- }
-
- private boolean isOwnerInfoEnabled(int userId) {
+ public boolean isOwnerInfoEnabled(int userId) {
return getBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, false, userId);
}
@@ -724,21 +639,10 @@
/**
* Save a lock password. Does not ensure that the password is as good
* as the requested mode, but will adjust the mode to be as good as the
- * pattern.
+ * password.
* @param password The password to save
* @param savedPassword The previously saved lock password, or null if none
* @param quality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
- */
- public void saveLockPassword(String password, String savedPassword, int quality) {
- saveLockPassword(password, savedPassword, quality, getCurrentOrCallingUserId());
- }
-
- /**
- * Save a lock password. Does not ensure that the password is as good
- * as the requested mode, but will adjust the mode to be as good as the
- * pattern.
- * @param password The password to save
- * @param quality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
* @param userHandle The userId of the user to change the password for
*/
public void saveLockPassword(String password, String savedPassword, int quality,
@@ -865,16 +769,6 @@
}
/**
- * Retrieves the quality mode we're in.
- * {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
- *
- * @return stored password quality
- */
- public int getKeyguardStoredPasswordQuality() {
- return getKeyguardStoredPasswordQuality(getCurrentOrCallingUserId());
- }
-
- /**
* Retrieves the quality mode for {@param userHandle}.
* {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
*
@@ -997,13 +891,6 @@
}
/**
- * @return Whether the lock screen is secured.
- */
- public boolean isSecure() {
- return isSecure(getCurrentOrCallingUserId());
- }
-
- /**
* @param userId the user for which to report the value
* @return Whether the lock screen is secured.
*/
@@ -1012,13 +899,6 @@
return isLockPatternEnabled(mode, userId) || isLockPasswordEnabled(mode, userId);
}
- /**
- * @return Whether the lock password is enabled
- */
- public boolean isLockPasswordEnabled() {
- return isLockPasswordEnabled(getCurrentOrCallingUserId());
- }
-
public boolean isLockPasswordEnabled(int userId) {
return isLockPasswordEnabled(getKeyguardStoredPasswordQuality(userId), userId);
}
@@ -1035,10 +915,6 @@
/**
* @return Whether the lock pattern is enabled
*/
- public boolean isLockPatternEnabled() {
- return isLockPatternEnabled(getCurrentOrCallingUserId());
- }
-
public boolean isLockPatternEnabled(int userId) {
return isLockPatternEnabled(getKeyguardStoredPasswordQuality(userId), userId);
}
@@ -1051,16 +927,14 @@
/**
* @return Whether the visible pattern is enabled.
*/
- public boolean isVisiblePatternEnabled() {
- return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, false, getCurrentOrCallingUserId());
+ public boolean isVisiblePatternEnabled(int userId) {
+ return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, false, userId);
}
/**
* Set whether the visible pattern is enabled.
*/
- public void setVisiblePatternEnabled(boolean enabled) {
- int userId = getCurrentOrCallingUserId();
-
+ public void setVisiblePatternEnabled(boolean enabled, int userId) {
setBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, enabled, userId);
// Update for crypto if owner
@@ -1095,9 +969,9 @@
* pattern until the deadline has passed.
* @return the chosen deadline.
*/
- public long setLockoutAttemptDeadline() {
+ public long setLockoutAttemptDeadline(int userId) {
final long deadline = SystemClock.elapsedRealtime() + FAILED_ATTEMPT_TIMEOUT_MS;
- setLong(LOCKOUT_ATTEMPT_DEADLINE, deadline, getCurrentOrCallingUserId());
+ setLong(LOCKOUT_ATTEMPT_DEADLINE, deadline, userId);
return deadline;
}
@@ -1106,8 +980,8 @@
* attempt to enter his/her lock pattern, or 0 if the user is welcome to
* enter a pattern.
*/
- public long getLockoutAttemptDeadline() {
- final long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L, getCurrentOrCallingUserId());
+ public long getLockoutAttemptDeadline(int userId) {
+ final long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L, userId);
final long now = SystemClock.elapsedRealtime();
if (deadline < now || deadline > (now + FAILED_ATTEMPT_TIMEOUT_MS)) {
return 0L;
@@ -1166,21 +1040,12 @@
}
}
- public void setPowerButtonInstantlyLocks(boolean enabled) {
- setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, getCurrentOrCallingUserId());
+ public void setPowerButtonInstantlyLocks(boolean enabled, int userId) {
+ setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, userId);
}
- public boolean getPowerButtonInstantlyLocks() {
- return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true,
- getCurrentOrCallingUserId());
- }
-
- public void setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents) {
- setEnabledTrustAgents(activeTrustAgents, getCurrentOrCallingUserId());
- }
-
- public List<ComponentName> getEnabledTrustAgents() {
- return getEnabledTrustAgents(getCurrentOrCallingUserId());
+ public boolean getPowerButtonInstantlyLocks(int userId) {
+ return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true, userId);
}
public void setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents, int userId) {
@@ -1192,7 +1057,7 @@
sb.append(cn.flattenToShortString());
}
setString(ENABLED_TRUST_AGENTS, sb.toString(), userId);
- getTrustManager().reportEnabledTrustAgentsChanged(getCurrentOrCallingUserId());
+ getTrustManager().reportEnabledTrustAgentsChanged(userId);
}
public List<ComponentName> getEnabledTrustAgents(int userId) {
@@ -1228,7 +1093,7 @@
}
public void setCredentialRequiredToDecrypt(boolean required) {
- if (getCurrentUser() != UserHandle.USER_OWNER) {
+ if (ActivityManager.getCurrentUser() != UserHandle.USER_OWNER) {
Log.w(TAG, "Only device owner may call setCredentialRequiredForDecrypt()");
return;
}
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index d86f71a..c384ef9 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -587,9 +587,8 @@
static jboolean android_media_AudioRecord_setInputDevice(
JNIEnv *env, jobject thiz, jint device_id) {
-// sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
-// return lpRecorder->setInputDevice(device_id) == NO_ERROR;
- return false;
+ sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
+ return lpRecorder->setInputDevice(device_id) == NO_ERROR;
}
// ----------------------------------------------------------------------------
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index cfbedda..fb82075 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -200,10 +200,8 @@
* that can be made while an exception is pending, so we want to
* get the VM ptr, throw the exception, and then detach the thread.
*/
- JavaVM* vm = jnienv_to_javavm(env);
env->Throw(excep);
- vm->DetachCurrentThread();
- sleep(60);
+ env->ExceptionDescribe();
ALOGE("Forcefully exiting");
exit(1);
}
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 5cb8b2e..05bc125 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -40,6 +40,9 @@
static jclass gLongClass;
static jfieldID gLongValueID;
+static jclass gFloatClass;
+static jfieldID gFloatValueID;
+
static jclass gStringClass;
/*
@@ -66,6 +69,17 @@
/*
* In class android.util.EventLog:
+ * static native int writeEvent(long tag, float value)
+ */
+static jint android_util_EventLog_writeEvent_Float(JNIEnv* env UNUSED,
+ jobject clazz UNUSED,
+ jint tag, jfloat value)
+{
+ return android_btWriteLog(tag, EVENT_TYPE_FLOAT, &value, sizeof(value));
+}
+
+/*
+ * In class android.util.EventLog:
* static native int writeEvent(int tag, String value)
*/
static jint android_util_EventLog_writeEvent_String(JNIEnv* env,
@@ -128,6 +142,12 @@
buf[pos++] = EVENT_TYPE_LONG;
memcpy(&buf[pos], &longVal, sizeof(longVal));
pos += sizeof(longVal);
+ } else if (env->IsInstanceOf(item, gFloatClass)) {
+ jfloat floatVal = env->GetFloatField(item, gFloatValueID);
+ if (pos + 1 + sizeof(floatVal) > max) break;
+ buf[pos++] = EVENT_TYPE_FLOAT;
+ memcpy(&buf[pos], &floatVal, sizeof(floatVal));
+ pos += sizeof(floatVal);
} else {
jniThrowException(env,
"java/lang/IllegalArgumentException",
@@ -233,6 +253,7 @@
/* name, signature, funcPtr */
{ "writeEvent", "(II)I", (void*) android_util_EventLog_writeEvent_Integer },
{ "writeEvent", "(IJ)I", (void*) android_util_EventLog_writeEvent_Long },
+ { "writeEvent", "(IF)I", (void*) android_util_EventLog_writeEvent_Float },
{ "writeEvent",
"(ILjava/lang/String;)I",
(void*) android_util_EventLog_writeEvent_String
@@ -251,6 +272,7 @@
{ "android/util/EventLog$Event", &gEventClass },
{ "java/lang/Integer", &gIntegerClass },
{ "java/lang/Long", &gLongClass },
+ { "java/lang/Float", &gFloatClass },
{ "java/lang/String", &gStringClass },
{ "java/util/Collection", &gCollectionClass },
};
@@ -258,6 +280,7 @@
static struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = {
{ &gIntegerClass, "value", "I", &gIntegerValueID },
{ &gLongClass, "value", "J", &gLongValueID },
+ { &gFloatClass, "value", "F", &gFloatValueID },
};
static struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = {
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 6bcc92e..a362684 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -112,8 +112,7 @@
jlong rendererPtr, jlong functorPtr) {
DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
Functor* functor = reinterpret_cast<Functor*>(functorPtr);
- android::uirenderer::Rect dirty;
- renderer->callDrawGLFunction(functor, dirty);
+ renderer->callDrawGLFunction(functor);
}
// ----------------------------------------------------------------------------
@@ -212,12 +211,10 @@
}
static void android_view_DisplayListCanvas_drawRenderNode(JNIEnv* env,
- jobject clazz, jlong rendererPtr, jlong renderNodePtr,
- jint flags) {
+ jobject clazz, jlong rendererPtr, jlong renderNodePtr) {
DisplayListCanvas* renderer = reinterpret_cast<DisplayListCanvas*>(rendererPtr);
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
- android::uirenderer::Rect bounds;
- renderer->drawRenderNode(renderNode, bounds, flags);
+ renderer->drawRenderNode(renderNode);
}
// ----------------------------------------------------------------------------
@@ -283,7 +280,7 @@
{ "nDrawCircle", "(JJJJJ)V", (void*) android_view_DisplayListCanvas_drawCircleProps },
{ "nFinishRecording", "(J)J", (void*) android_view_DisplayListCanvas_finishRecording },
- { "nDrawRenderNode", "(JJI)V", (void*) android_view_DisplayListCanvas_drawRenderNode },
+ { "nDrawRenderNode", "(JJ)V", (void*) android_view_DisplayListCanvas_drawRenderNode },
{ "nCreateDisplayListCanvas", "()J", (void*) android_view_DisplayListCanvas_createDisplayListCanvas },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 018c1a1..45c078d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1178,13 +1178,13 @@
<permission android:name="android.permission.REGISTER_CONNECTION_MANAGER"
android:protectionLevel="system|signature" />
- <!-- @SystemApi Allows an application to bind to InCallService implementations.
- @hide -->
+ <!-- Must be required by a {@link android.telecom.InCallService},
+ to ensure that only the system can bind to it. -->
<permission android:name="android.permission.BIND_INCALL_SERVICE"
android:protectionLevel="system|signature" />
- <!-- @SystemApi Allows an application to bind to ConnectionService implementations.
- @hide -->
+ <!-- Must be required by a {@link android.telecom.ConnectionService},
+ to ensure that only the system can bind to it. -->
<permission android:name="android.permission.BIND_CONNECTION_SERVICE"
android:protectionLevel="system|signature" />
diff --git a/core/res/res/color/primary_text_activated_material_dark.xml b/core/res/res/color/primary_text_activated_material_dark.xml
deleted file mode 100644
index f1b742a..0000000
--- a/core/res/res/color/primary_text_activated_material_dark.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_activated="true"
- android:color="@color/primary_text_default_material_light"/>
- <item android:color="@color/primary_text_default_material_dark"/>
-</selector>
diff --git a/core/res/res/color/primary_text_activated_material_light.xml b/core/res/res/color/primary_text_activated_material_light.xml
deleted file mode 100644
index d92da63..0000000
--- a/core/res/res/color/primary_text_activated_material_light.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_activated="true"
- android:color="@color/primary_text_default_material_dark"/>
- <item android:color="@color/primary_text_default_material_light"/>
-</selector>
diff --git a/core/res/res/color/primary_text_inverse_when_activated_material.xml b/core/res/res/color/primary_text_inverse_when_activated_material.xml
new file mode 100644
index 0000000..0f7f9cdf
--- /dev/null
+++ b/core/res/res/color/primary_text_inverse_when_activated_material.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_enabled="false"
+ android:state_activated="true"
+ android:color="?attr/textColorPrimaryInverse"
+ android:alpha="?attr/disabledAlpha" />
+ <item
+ android:state_enabled="false"
+ android:color="?attr/textColorPrimary"
+ android:alpha="?attr/disabledAlpha" />
+ <item
+ android:state_activated="true"
+ android:color="?attr/textColorPrimaryInverse" />
+ <item
+ android:color="?attr/textColorPrimary" />
+</selector>
diff --git a/core/res/res/color/secondary_text_activated_material_dark.xml b/core/res/res/color/secondary_text_activated_material_dark.xml
deleted file mode 100644
index 7a8428a..0000000
--- a/core/res/res/color/secondary_text_activated_material_dark.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_activated="true"
- android:color="@color/secondary_text_default_material_light"/>
- <item android:color="@color/secondary_text_default_material_dark"/>
-</selector>
diff --git a/core/res/res/color/secondary_text_activated_material_light.xml b/core/res/res/color/secondary_text_activated_material_light.xml
deleted file mode 100644
index 36ff408..0000000
--- a/core/res/res/color/secondary_text_activated_material_light.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_activated="true"
- android:color="@color/secondary_text_default_material_dark"/>
- <item android:color="@color/secondary_text_default_material_light"/>
-</selector>
diff --git a/core/res/res/color/secondary_text_inverse_when_activated_material.xml b/core/res/res/color/secondary_text_inverse_when_activated_material.xml
new file mode 100644
index 0000000..5b259de
--- /dev/null
+++ b/core/res/res/color/secondary_text_inverse_when_activated_material.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_enabled="false"
+ android:state_activated="true"
+ android:color="?attr/textColorSecondaryInverse"
+ android:alpha="?attr/disabledAlpha" />
+ <item
+ android:state_enabled="false"
+ android:color="?attr/textColorSecondary"
+ android:alpha="?attr/disabledAlpha" />
+ <item
+ android:state_activated="true"
+ android:color="?attr/textColorSecondaryInverse" />
+ <item
+ android:color="?attr/textColorSecondary" />
+</selector>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 887b0a5..a95cc79 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1971,7 +1971,7 @@
{@link android.R.attr#windowTranslucentStatus}.
Corresponds to setting {@link android.view.View#SYSTEM_UI_FLAG_LIGHT_STATUS_BAR} on
the decor view. -->
- <attr name="windowHasLightStatusBar" format="boolean" />
+ <attr name="windowLightStatusBar" format="boolean" />
</declare-styleable>
<!-- The set of attributes that describe a AlertDialog's theme. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 0c685e0..4631427 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1044,7 +1044,8 @@
<p>NOTE: The value of {@link android.R.attr#screenOrientation} will be ignored for
resizeable activities as the system doesn't support fixed orientation on a resizeable
- activity. -->
+ activity.
+ @hide -->
<attr name="resizeableActivity" format="boolean" />
<!-- This value indicates how tasks rooted at this activity will behave in lockTask mode.
@@ -1796,6 +1797,7 @@
<attr name="autoRemoveFromRecents" />
<attr name="relinquishTaskIdentity" />
<attr name="resumeWhilePausing" />
+ <!-- @hide -->
<attr name="resizeableActivity" />
<attr name="lockTaskMode" />
<attr name="showForAllUsers" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 7920949..dd4c134 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2610,10 +2610,9 @@
<public type="attr" name="trackTint" />
<public type="attr" name="trackTintMode" />
- <public type="attr" name="resizeableActivity" />
<public type="attr" name="start" />
<public type="attr" name="end" />
- <public type="attr" name="windowHasLightStatusBar" />
+ <public type="attr" name="windowLightStatusBar" />
<public type="attr" name="numbersInnerTextColor" />
<public type="attr" name="iconTint" />
<public type="attr" name="iconTintMode" />
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index b0f673c..e679e0a 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -56,11 +56,11 @@
<item name="textColorPrimary">@color/primary_text_material_dark</item>
<item name="textColorPrimaryInverse">@color/primary_text_material_light</item>
- <item name="textColorPrimaryActivated">@color/primary_text_activated_material_dark</item>
+ <item name="textColorPrimaryActivated">@color/primary_text_inverse_when_activated_material</item>
<item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_dark</item>
<item name="textColorSecondary">@color/secondary_text_material_dark</item>
<item name="textColorSecondaryInverse">@color/secondary_text_material_light</item>
- <item name="textColorSecondaryActivated">@color/secondary_text_activated_material_dark</item>
+ <item name="textColorSecondaryActivated">@color/secondary_text_inverse_when_activated_material</item>
<item name="textColorTertiary">@color/secondary_text_material_dark</item>
<item name="textColorTertiaryInverse">@color/secondary_text_material_light</item>
<item name="textColorHint">@color/hint_foreground_material_dark</item>
@@ -410,10 +410,10 @@
<item name="textColorPrimary">@color/primary_text_material_light</item>
<item name="textColorPrimaryInverse">@color/primary_text_material_dark</item>
- <item name="textColorPrimaryActivated">@color/primary_text_activated_material_light</item>
+ <item name="textColorPrimaryActivated">@color/primary_text_inverse_when_activated_material</item>
<item name="textColorSecondary">@color/secondary_text_material_light</item>
<item name="textColorSecondaryInverse">@color/secondary_text_material_dark</item>
- <item name="textColorSecondaryActivated">@color/secondary_text_activated_material_light</item>
+ <item name="textColorSecondaryActivated">@color/secondary_text_inverse_when_activated_material</item>
<item name="textColorTertiary">@color/secondary_text_material_light</item>
<item name="textColorTertiaryInverse">@color/secondary_text_material_dark</item>
<item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_light</item>
@@ -760,7 +760,7 @@
status bar contents. -->
<style name="Theme.Material.Light.LightStatusBar">
<item name="colorPrimaryDark">@color/primary_dark_material_light_light_status_bar</item>
- <item name="windowHasLightStatusBar">true</item>
+ <item name="windowLightStatusBar">true</item>
</style>
<style name="ThemeOverlay" />
@@ -777,10 +777,8 @@
<item name="textColorPrimary">@color/primary_text_material_light</item>
<item name="textColorPrimaryInverse">@color/primary_text_material_dark</item>
- <item name="textColorPrimaryActivated">@color/primary_text_activated_material_light</item>
<item name="textColorSecondary">@color/secondary_text_material_light</item>
<item name="textColorSecondaryInverse">@color/secondary_text_material_dark</item>
- <item name="textColorSecondaryActivated">@color/secondary_text_activated_material_light</item>
<item name="textColorTertiary">@color/secondary_text_material_light</item>
<item name="textColorTertiaryInverse">@color/secondary_text_material_dark</item>
<item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_light</item>
@@ -814,11 +812,9 @@
<item name="textColorPrimary">@color/primary_text_material_dark</item>
<item name="textColorPrimaryInverse">@color/primary_text_material_light</item>
- <item name="textColorPrimaryActivated">@color/primary_text_activated_material_dark</item>
<item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_material_dark</item>
<item name="textColorSecondary">@color/secondary_text_material_dark</item>
<item name="textColorSecondaryInverse">@color/secondary_text_material_light</item>
- <item name="textColorSecondaryActivated">@color/secondary_text_activated_material_dark</item>
<item name="textColorTertiary">@color/secondary_text_material_dark</item>
<item name="textColorTertiaryInverse">@color/secondary_text_material_light</item>
<item name="textColorHint">@color/hint_foreground_material_dark</item>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index e04c214..4b82c3d 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -184,10 +184,10 @@
result.putInt("ap-discovered", ssidAppearInScanResultsCount);
getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, result);
if (i == mScanIterations + 1) {
- writeOutput(String.format("iteration %d out of %d", i, mScanIterations));
+ writeOutput(String.format("iteration %d out of %d", i - 1, mScanIterations));
writeOutput(String.format("average scanning time is %d", scanTimeSum / (i - 1)));
writeOutput(String.format("ssid appear %d out of %d scan iterations",
- ssidAppearInScanResultsCount, i));
+ ssidAppearInScanResultsCount, i - 1));
}
}
@@ -289,7 +289,7 @@
getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, result);
if (i == mReconnectIterations + 1) {
writeOutput(String.format("iteration %d out of %d",
- i, mReconnectIterations));
+ i - 1, mReconnectIterations));
}
}
}
diff --git a/docs/html/distribute/tools/promote/brand.jd b/docs/html/distribute/tools/promote/brand.jd
index a12e753..cf83a5e 100644
--- a/docs/html/distribute/tools/promote/brand.jd
+++ b/docs/html/distribute/tools/promote/brand.jd
@@ -37,6 +37,18 @@
<p>If used with your logo, "for Android" should be no larger than 90% of your logo’s size.
First instance of this use should be followed by a TM symbol, "for Android™".</p>
</li>
+ <li>"Android TV", "Android Wear" and "Android Auto" may only be used to identify or market
+ products or services with prior approval. Use "for Android" or "with Android" for all
+ other Android-based products
+ <ul>
+ <li><span style="color:red">Incorrect</span>: "Android TV Streaming Stick",
+ "Streaming Stick with Android TV"</li>
+ <li><span style="color:green">Correct</span>: "Streaming Stick with Android"</li>
+ </ul>
+ <p>If used with your logo, "for Android" or "with Android" should be no larger than 90% of
+ your logo’s size. First instance of this use should be followed by a TM symbol,
+ "for Android™".</p>
+ </li>
<li>Android may be used as a descriptor, as long as it is followed by a
proper generic term. (Think of "Android" as a term used in place of
"the Android platform.")
diff --git a/docs/html/training/wearables/data-layer/messages.jd b/docs/html/training/wearables/data-layer/messages.jd
index 043aff2..ef9bfb1 100644
--- a/docs/html/training/wearables/data-layer/messages.jd
+++ b/docs/html/training/wearables/data-layer/messages.jd
@@ -34,7 +34,7 @@
<p>Multiple wearable devices can be connected to a user’s handheld device. Each connected device in
the network is considered a <em>node</em>. With multiple connected devices, you must consider which
-nodes receive the messages. For example, In a voice transcription app that receives voice data on
+nodes receive the messages. For example, in a voice transcription app that receives voice data on
the wearable device, you should send the message to a node with the processing power and battery
capacity to handle the request, such as a handheld device.</p>
@@ -196,7 +196,15 @@
<p>The following example shows how to send a message to the transcription-capable node from a
wearable device. Verify that the node is available before you attempt to send the message. This call
-is synchronous and blocks processing until the message is received or until the request times out.
+is synchronous and blocks processing until the system queues the message for delivery.
+</p>
+
+<p class="note"><strong>Note:</strong> A successful result code does not guarantee delivery of the
+message. If your app requires data reliability, use
+<a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code></a>
+objects or the
+<a href="{@docRoot}reference/com/google/android/gms/wearable/ChannelApi.html"><code>ChannelApi</code></a>
+class to send data between devices.
</p>
<pre>
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 4c2817c..dc9aa67 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -133,7 +133,7 @@
private GradientState mGradientState;
- private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private final Paint mFillPaint = new Paint();
private Rect mPadding;
private Paint mStrokePaint; // optional, set by the caller
private ColorFilter mColorFilter; // optional, set by the caller
@@ -323,7 +323,7 @@
private void setStrokeInternal(int width, int color, float dashWidth, float dashGap) {
if (mStrokePaint == null) {
- mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mStrokePaint = new Paint();
mStrokePaint.setStyle(Paint.Style.STROKE);
}
mStrokePaint.setStrokeWidth(width);
@@ -1802,7 +1802,7 @@
mPadding = state.mPadding;
if (state.mStrokeWidth >= 0) {
- mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mStrokePaint = new Paint();
mStrokePaint.setStyle(Paint.Style.STROKE);
mStrokePaint.setStrokeWidth(state.mStrokeWidth);
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 3bbbc71..c3d8cfa 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -1464,7 +1464,8 @@
bounds.right - insetR - padR, bounds.bottom - r.mInsetB - padB);
// Apply resolved gravity to drawable based on resolved size.
- final int gravity = resolveGravity(r.mGravity, r.mWidth, r.mHeight);
+ final int gravity = resolveGravity(r.mGravity, r.mWidth, r.mHeight,
+ d.getIntrinsicWidth(), d.getIntrinsicHeight());
final int w = r.mWidth < 0 ? d.getIntrinsicWidth() : r.mWidth;
final int h = r.mHeight < 0 ? d.getIntrinsicHeight() : r.mHeight;
Gravity.apply(gravity, w, h, container, outRect, layoutDirection);
@@ -1491,7 +1492,8 @@
* @param height height of the layer if set, -1 otherwise
* @return the default gravity for the layer
*/
- private static int resolveGravity(int gravity, int width, int height) {
+ private static int resolveGravity(int gravity, int width, int height,
+ int intrinsicWidth, int intrinsicHeight) {
if (!Gravity.isHorizontal(gravity)) {
if (width < 0) {
gravity |= Gravity.FILL_HORIZONTAL;
@@ -1508,6 +1510,17 @@
}
}
+ // If a dimension if not specified, either implicitly or explicitly,
+ // force FILL for that dimension's gravity. This ensures that colors
+ // are handled correctly and ensures backward compatibility.
+ if (width < 0 && intrinsicWidth < 0) {
+ gravity |= Gravity.FILL_HORIZONTAL;
+ }
+
+ if (height < 0 && intrinsicHeight < 0) {
+ gravity |= Gravity.FILL_VERTICAL;
+ }
+
return gravity;
}
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 334b3bd..caa0787 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -501,7 +501,7 @@
if (mShapeState.mPaint != null) {
mShapeState.mPaint = new Paint(mShapeState.mPaint);
} else {
- mShapeState.mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mShapeState.mPaint = new Paint();
}
if (mShapeState.mPadding != null) {
mShapeState.mPadding = new Rect(mShapeState.mPadding);
@@ -555,7 +555,7 @@
mAlpha = orig.mAlpha;
mShaderFactory = orig.mShaderFactory;
} else {
- mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mPaint = new Paint();
}
}
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index 6b86030..a7784b6 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -88,8 +88,7 @@
void DisplayListCanvas::resume() {
}
-void DisplayListCanvas::callDrawGLFunction(Functor *functor, Rect& dirty) {
- // Ignore dirty during recording, it matters only when we replay
+void DisplayListCanvas::callDrawGLFunction(Functor *functor) {
addDrawOp(new (alloc()) DrawFunctorOp(functor));
mDisplayListData->functors.add(functor);
}
@@ -202,12 +201,12 @@
return mState.clipRegion(region, op);
}
-void DisplayListCanvas::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) {
+void DisplayListCanvas::drawRenderNode(RenderNode* renderNode) {
LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode");
// dirty is an out parameter and should not be recorded,
// it matters only when replaying the display list
- DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *mState.currentTransform());
+ DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, *mState.currentTransform());
addRenderNodeOp(op);
}
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index 2b0b6b2..fa4b2b4 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -115,10 +115,10 @@
// HWUI Canvas draw operations - special
// ----------------------------------------------------------------------------
void drawLayer(DeferredLayerUpdater* layerHandle, float x, float y);
- void drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags);
+ void drawRenderNode(RenderNode* renderNode);
// TODO: rename for consistency
- void callDrawGLFunction(Functor* functor, Rect& dirty);
+ void callDrawGLFunction(Functor* functor);
void setHighContrastText(bool highContrastText) {
mHighContrastText = highContrastText;
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index b5801fc..4863ed2 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1398,10 +1398,9 @@
friend class RenderNode; // grant RenderNode access to info of child
friend class DisplayListData; // grant DisplayListData access to info of child
public:
- DrawRenderNodeOp(RenderNode* renderNode, int flags, const mat4& transformFromParent)
+ DrawRenderNodeOp(RenderNode* renderNode, const mat4& transformFromParent)
: DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr)
, mRenderNode(renderNode)
- , mFlags(flags)
, mTransformFromParent(transformFromParent)
, mSkipInOrderDraw(false) {}
@@ -1424,7 +1423,7 @@
}
virtual void output(int level, uint32_t logFlags) const override {
- OP_LOG("Draw RenderNode %p %s, flags %#x", mRenderNode, mRenderNode->getName(), mFlags);
+ OP_LOG("Draw RenderNode %p %s, flags %#x", mRenderNode, mRenderNode->getName());
if (mRenderNode && (logFlags & kOpLogFlag_Recurse)) {
mRenderNode->output(level + 1);
}
@@ -1436,7 +1435,6 @@
private:
RenderNode* mRenderNode;
- const int mFlags;
///////////////////////////
// Properties below are used by RenderNode::computeOrderingImpl() and issueOperations()
diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp
index 61ad082..62782af 100644
--- a/libs/hwui/tests/main.cpp
+++ b/libs/hwui/tests/main.cpp
@@ -111,15 +111,13 @@
public:
std::vector< sp<RenderNode> > cards;
void createContent(int width, int height, DisplayListCanvas* renderer) override {
- android::uirenderer::Rect DUMMY;
-
renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
renderer->insertReorderBarrier(true);
for (int x = dp(16); x < (width - dp(116)); x += dp(116)) {
for (int y = dp(16); y < (height - dp(116)); y += dp(116)) {
sp<RenderNode> card = createCard(x, y, dp(100), dp(100));
- renderer->drawRenderNode(card.get(), DUMMY, 0);
+ renderer->drawRenderNode(card.get());
cards.push_back(card);
}
}
@@ -153,13 +151,11 @@
public:
sp<RenderNode> card;
void createContent(int width, int height, DisplayListCanvas* renderer) override {
- android::uirenderer::Rect DUMMY;
-
renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
renderer->insertReorderBarrier(true);
card = createCard(40, 40, 200, 200);
- renderer->drawRenderNode(card.get(), DUMMY, 0);
+ renderer->drawRenderNode(card.get());
renderer->insertReorderBarrier(false);
}
@@ -202,13 +198,11 @@
public:
sp<RenderNode> card;
void createContent(int width, int height, DisplayListCanvas* renderer) override {
- android::uirenderer::Rect DUMMY;
-
renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
renderer->insertReorderBarrier(true);
card = createCard(40, 40, 400, 400);
- renderer->drawRenderNode(card.get(), DUMMY, 0);
+ renderer->drawRenderNode(card.get());
renderer->insertReorderBarrier(false);
}
diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
index 1699809..25b1875 100644
--- a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
@@ -120,7 +120,7 @@
KeyguardUpdateMonitor.getInstance(mContext).reportEmergencyCallAction(
true /* bypassHandler */);
getContext().startActivityAsUser(INTENT_EMERGENCY_DIAL,
- new UserHandle(mLockPatternUtils.getCurrentUser()));
+ new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
}
}
@@ -138,7 +138,7 @@
visible = mEnableEmergencyCallWhileSimLocked;
} else {
// Only show if there is a secure screen (pin/pattern/SIM pin/SIM puk);
- visible = mLockPatternUtils.isSecure();
+ visible = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
}
}
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index 322be91..c4f4b9a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -63,7 +63,8 @@
// start fresh
resetPasswordText(false /* animate */);
// if the user is currently locked out, enforce it.
- long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+ long deadline = mLockPatternUtils.getLockoutAttemptDeadline(
+ KeyguardUpdateMonitor.getCurrentUser());
if (shouldLockout(deadline)) {
handleAttemptLockout(deadline);
} else {
@@ -106,7 +107,7 @@
protected void verifyPasswordAndUnlock() {
String entry = getPasswordText();
- if (mLockPatternUtils.checkPassword(entry)) {
+ if (mLockPatternUtils.checkPassword(entry, KeyguardUpdateMonitor.getCurrentUser())) {
mCallback.reportUnlockAttempt(true);
mCallback.dismiss(true);
} else {
@@ -116,7 +117,8 @@
mCallback.reportUnlockAttempt(false);
int attempts = KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts();
if (0 == (attempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
- long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+ long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
+ KeyguardUpdateMonitor.getCurrentUser());
handleAttemptLockout(deadline);
}
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index be71b034..2cf30ba 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -71,7 +71,7 @@
@Override
public void onTrustGrantedWithFlags(int flags, int userId) {
- if (userId != mLockPatternUtils.getCurrentUser()) return;
+ if (userId != KeyguardUpdateMonitor.getCurrentUser()) return;
if (!isAttachedToWindow()) return;
boolean bouncerVisible = isVisibleToUser();
boolean initiatedByUser =
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 9aa5729..557cd13 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -130,7 +130,8 @@
mLockPatternView.setOnPatternListener(new UnlockPatternListener());
// stealth mode will be the same for the life of this screen
- mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled());
+ mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled(
+ KeyguardUpdateMonitor.getCurrentUser()));
// vibrate mode will be the same for the life of this screen
mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
@@ -176,7 +177,8 @@
mLockPatternView.clearPattern();
// if the user is currently locked out, enforce it.
- long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+ long deadline = mLockPatternUtils.getLockoutAttemptDeadline(
+ KeyguardUpdateMonitor.getCurrentUser());
if (deadline != 0) {
handleAttemptLockout(deadline);
} else {
@@ -213,7 +215,7 @@
}
public void onPatternDetected(List<LockPatternView.Cell> pattern) {
- if (mLockPatternUtils.checkPattern(pattern)) {
+ if (mLockPatternUtils.checkPattern(pattern, KeyguardUpdateMonitor.getCurrentUser())) {
mCallback.reportUnlockAttempt(true);
mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
mCallback.dismiss(true);
@@ -230,7 +232,8 @@
int attempts = mKeyguardUpdateMonitor.getFailedUnlockAttempts();
if (registeredAttempt &&
0 == (attempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
- long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+ long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
+ KeyguardUpdateMonitor.getCurrentUser());
handleAttemptLockout(deadline);
} else {
mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern, true);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index 5af7783..ae4baad 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -261,7 +261,7 @@
SecurityMode mode = mSecurityModel.getSecurityMode();
final boolean usingPattern = mode == KeyguardSecurityModel.SecurityMode.Pattern;
- final int currentUser = mLockPatternUtils.getCurrentUser();
+ final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
final DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
final int failedAttemptsBeforeWipe =
dpm.getMaximumFailedPasswordsForWipe(null, currentUser);
@@ -296,7 +296,7 @@
(failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
}
monitor.reportFailedUnlockAttempt();
- mLockPatternUtils.reportFailedPasswordAttempt();
+ mLockPatternUtils.reportFailedPasswordAttempt(KeyguardUpdateMonitor.getCurrentUser());
if (showTimeout) {
showTimeoutDialog();
}
@@ -321,7 +321,7 @@
boolean showNextSecurityScreenOrFinish(boolean authenticated) {
if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
boolean finish = false;
- if (mUpdateMonitor.getUserHasTrust(mLockPatternUtils.getCurrentUser())) {
+ if (mUpdateMonitor.getUserHasTrust(KeyguardUpdateMonitor.getCurrentUser())) {
finish = true;
} else if (SecurityMode.None == mCurrentSecuritySelection) {
SecurityMode securityMode = mSecurityModel.getSecurityMode();
@@ -430,7 +430,8 @@
KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
if (success) {
monitor.clearFailedUnlockAttempts();
- mLockPatternUtils.reportSuccessfulPasswordAttempt();
+ mLockPatternUtils.reportSuccessfulPasswordAttempt(
+ KeyguardUpdateMonitor.getCurrentUser());
} else {
KeyguardSecurityContainer.this.reportFailedUnlockAttempt();
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
index 3eb31ad..454221a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -67,7 +67,8 @@
return SecurityMode.SimPuk;
}
- final int security = mLockPatternUtils.getActivePasswordQuality();
+ final int security = mLockPatternUtils.getActivePasswordQuality(
+ KeyguardUpdateMonitor.getCurrentUser());
switch (security) {
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index af6360a..4e9621a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -200,9 +200,10 @@
private String getOwnerInfo() {
ContentResolver res = getContext().getContentResolver();
String info = null;
- final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled();
+ final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled(
+ KeyguardUpdateMonitor.getCurrentUser());
if (ownerInfoEnabled) {
- info = mLockPatternUtils.getOwnerInfo(mLockPatternUtils.getCurrentUser());
+ info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser());
}
return info;
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 1eec5325..b8d9053 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -244,6 +244,16 @@
private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
+ private static int sCurrentUser;
+
+ public synchronized static void setCurrentUser(int currentUser) {
+ sCurrentUser = currentUser;
+ }
+
+ public synchronized static int getCurrentUser() {
+ return sCurrentUser;
+ }
+
@Override
public void onTrustChanged(boolean enabled, int userId, int flags) {
mUserHasTrust.put(userId, enabled);
@@ -669,7 +679,7 @@
cb.onScreenTurnedOn();
}
}
- startListeningForFingerprint();
+ updateFingerprintListeningState();
}
protected void handleScreenTurnedOff(int arg1) {
@@ -681,7 +691,7 @@
cb.onScreenTurnedOff(arg1);
}
}
- stopListeningForFingerprint();
+ updateFingerprintListeningState();
}
/**
@@ -754,14 +764,14 @@
mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
newUserId, 0, reply));
mSwitchingUser = true;
- stopListeningForFingerprint();
+ updateFingerprintListeningState();
}
@Override
public void onUserSwitchComplete(int newUserId) throws RemoteException {
mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
newUserId, 0));
mSwitchingUser = false;
- startListeningForFingerprint();
+ updateFingerprintListeningState();
}
@Override
public void onForegroundProfileSwitch(int newProfileId) {
@@ -777,7 +787,20 @@
trustManager.registerTrustListener(this);
mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
- startListeningForFingerprint();
+ updateFingerprintListeningState();
+ }
+
+ private void updateFingerprintListeningState() {
+ boolean shouldListenForFingerprint = shouldListenForFingerprint();
+ if (mFingerprintDetectionRunning && !shouldListenForFingerprint) {
+ stopListeningForFingerprint();
+ } else if (!mFingerprintDetectionRunning && shouldListenForFingerprint) {
+ startListeningForFingerprint();
+ }
+ }
+
+ private boolean shouldListenForFingerprint() {
+ return mScreenOn && mKeyguardIsVisible && !mSwitchingUser;
}
private void startListeningForFingerprint() {
@@ -794,7 +817,7 @@
}
}
- public void stopListeningForFingerprint() {
+ private void stopListeningForFingerprint() {
if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
if (isFingerprintDetectionRunning()) {
mFingerprintCancelSignal.cancel();
@@ -1052,6 +1075,7 @@
cb.onKeyguardVisibilityChangedRaw(isShowing);
}
}
+ updateFingerprintListeningState();
}
/**
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 870f043..7bf2223 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2066,7 +2066,7 @@
LockPatternUtils lpu = new LockPatternUtils(mContext);
List<LockPatternView.Cell> cellPattern =
LockPatternUtils.stringToPattern(lockPattern);
- lpu.saveLockPattern(cellPattern, null);
+ lpu.saveLockPattern(cellPattern, null, UserHandle.USER_OWNER);
} catch (IllegalArgumentException e) {
// Don't want corrupted lock pattern to hang the reboot process
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 7f826ef..d99f741 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -754,7 +754,7 @@
*/
private byte[] getLockSettings() {
final LockPatternUtils lockPatternUtils = new LockPatternUtils(this);
- final boolean ownerInfoEnabled = lockPatternUtils.isOwnerInfoEnabled();
+ final boolean ownerInfoEnabled = lockPatternUtils.isOwnerInfoEnabled(UserHandle.myUserId());
final String ownerInfo = lockPatternUtils.getOwnerInfo(UserHandle.myUserId());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -871,7 +871,8 @@
}
switch (key) {
case KEY_LOCK_SETTINGS_OWNER_INFO_ENABLED:
- lockPatternUtils.setOwnerInfoEnabled("1".equals(value));
+ lockPatternUtils.setOwnerInfoEnabled("1".equals(value),
+ UserHandle.myUserId());
break;
case KEY_LOCK_SETTINGS_OWNER_INFO:
lockPatternUtils.setOwnerInfo(value, UserHandle.myUserId());
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_fingerprint_ridges_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_fingerprint_ridges_animation.xml
new file mode 100644
index 0000000..c6a4622
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_fingerprint_ridges_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="100"
+ android:propertyName="rotation"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="566"
+ android:propertyName="rotation"
+ android:valueFrom="0.0"
+ android:valueTo="-305.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3" />
+ <objectAnimator
+ android:duration="1066"
+ android:propertyName="rotation"
+ android:valueFrom="-305.0"
+ android:valueTo="-305.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+ <objectAnimator
+ android:duration="800"
+ android:propertyName="rotation"
+ android:valueFrom="-305.0"
+ android:valueTo="-720.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_1_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_1_animation.xml
new file mode 100644
index 0000000..0e2c2f0
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_1_animation.xml
@@ -0,0 +1,36 @@
+<?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="183"
+ android:propertyName="rotation"
+ android:valueFrom="285.0"
+ android:valueTo="285.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="516"
+ android:propertyName="rotation"
+ android:valueFrom="285.0"
+ android:valueTo="90.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_2_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_2_animation.xml
new file mode 100644
index 0000000..c01010d
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_group_2_animation.xml
@@ -0,0 +1,70 @@
+<?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="283"
+ android:propertyName="scaleX"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="316"
+ android:propertyName="scaleX"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="283"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="316"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="283"
+ android:propertyName="rotation"
+ android:valueFrom="184.0"
+ android:valueTo="184.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="316"
+ android:propertyName="rotation"
+ android:valueFrom="184.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_path_3_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_path_3_animation.xml
new file mode 100644
index 0000000..454be24
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_path_3_animation.xml
@@ -0,0 +1,36 @@
+<?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="233"
+ android:propertyName="trimPathStart"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="466"
+ android:propertyName="trimPathStart"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_0_animation.xml
new file mode 100644
index 0000000..faeecf4
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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="133"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_animation.xml
new file mode 100644
index 0000000..3bacf03
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_1_path_animation.xml
@@ -0,0 +1,36 @@
+<?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="16"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="66"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_0_animation.xml
new file mode 100644
index 0000000..80a0faa
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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="116"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="116"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3" />
+ </set>
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="trimPathStart"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3" />
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_animation.xml
new file mode 100644
index 0000000..3a18296
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_2_path_animation.xml
@@ -0,0 +1,36 @@
+<?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="16"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_0_animation.xml
new file mode 100644
index 0000000..1e16df7
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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="trimPathEnd"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="166"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_animation.xml
new file mode 100644
index 0000000..a1cf8df
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_5_path_animation.xml
@@ -0,0 +1,26 @@
+<?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="150"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_0_animation.xml
new file mode 100644
index 0000000..f88c070
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_0_animation.xml
@@ -0,0 +1,43 @@
+<?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="250"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="216"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_animation.xml
new file mode 100644
index 0000000..ada7c10
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_6_path_animation.xml
@@ -0,0 +1,36 @@
+<?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="16"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="216"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_0_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_0_animation.xml
new file mode 100644
index 0000000..e6b12da
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_0_animation.xml
@@ -0,0 +1,53 @@
+<?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="16"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="216"
+ android:propertyName="trimPathEnd"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="266"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_animation.xml
new file mode 100644
index 0000000..8c6e71d
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_ridge_7_path_animation.xml
@@ -0,0 +1,36 @@
+<?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="33"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="trimPathStart"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_white_fingerprint_ridges_animation.xml b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_white_fingerprint_ridges_animation.xml
new file mode 100644
index 0000000..c6a4622
--- /dev/null
+++ b/packages/SystemUI/res/anim/lockscreen_fingerprint_error_state_white_fingerprint_ridges_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="100"
+ android:propertyName="rotation"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="566"
+ android:propertyName="rotation"
+ android:valueFrom="0.0"
+ android:valueTo="-305.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3" />
+ <objectAnimator
+ android:duration="1066"
+ android:propertyName="rotation"
+ android:valueFrom="-305.0"
+ android:valueTo="-305.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+ <objectAnimator
+ android:duration="800"
+ android:propertyName="rotation"
+ android:valueFrom="-305.0"
+ android:valueTo="-720.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state.xml
new file mode 100644
index 0000000..cc8aba9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state.xml
@@ -0,0 +1,180 @@
+<?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="lockscreen_fingerprint_error_state"
+ android:width="32dp"
+ android:viewportWidth="32"
+ android:height="32dp"
+ android:viewportHeight="32" >
+ <group
+ android:name="white_fingerprint_ridges"
+ android:translateX="16.125"
+ android:translateY="19.75" >
+ <group
+ android:name="white_fingerprint_ridges_pivot"
+ android:translateX="33.2085"
+ android:translateY="30.91685" >
+ <group
+ android:name="ridge_5" >
+ <path
+ android:name="ridge_5_path"
+ android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="0.5"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round" />
+ </group>
+ <group
+ android:name="ridge_4" >
+ <path
+ android:name="ridge_7_path"
+ android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="0.5"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round" />
+ </group>
+ <group
+ android:name="ridge_3" >
+ <path
+ android:name="ridge_6_path"
+ android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="0.5"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round" />
+ </group>
+ <group
+ android:name="ridge_2" >
+ <path
+ android:name="ridge_2_path"
+ android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="0.5"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round" />
+ </group>
+ <group
+ android:name="ridge_1"
+ android:translateX="-97.5"
+ android:translateY="-142.5" >
+ <path
+ android:name="ridge_1_path"
+ android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
+ android:strokeColor="#FFFFFFFF"
+ android:strokeAlpha="0.5"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round" />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="fingerprint_ridges"
+ android:translateX="16.125"
+ android:translateY="19.75" >
+ <group
+ android:name="fingerprint_ridges_pivot"
+ android:translateX="33.2085"
+ android:translateY="30.91685" >
+ <group
+ android:name="ridge_6" >
+ <path
+ android:name="ridge_5_path_0"
+ android:pathData="M -25.3591003418,-24.4138946533 c -0.569000244141,0.106399536133 -1.12660217285,0.140594482422 -1.45460510254,0.140594482422 c -1.29689025879,0.0 -2.53239440918,-0.343307495117 -3.62019348145,-1.12400817871 c -1.67700195312,-1.20349121094 -2.76950073242,-3.17008972168 -2.76950073242,-5.39189147949"
+ android:strokeColor="#FFF2501D"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round"
+ android:trimPathEnd="0" />
+ </group>
+ <group
+ android:name="ridge_7" >
+ <path
+ android:name="ridge_7_path_0"
+ android:pathData="M -36.1409912109,-21.7843475342 c -1.00540161133,-1.19300842285 -1.57499694824,-1.9181060791 -2.36520385742,-3.50170898438 c -0.827560424805,-1.65869140625 -1.31352233887,-3.49159240723 -1.31352233887,-5.48489379883 c 0.0,-3.66279602051 2.96932983398,-6.63220214844 6.63221740723,-6.63220214844 c 3.6628112793,0.0 6.63220214844,2.96940612793 6.63220214844,6.63220214844"
+ android:strokeColor="#FFF2501D"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round"
+ android:trimPathEnd="0" />
+ </group>
+ <group
+ android:name="ridge_8" >
+ <path
+ android:name="ridge_6_path_0"
+ android:pathData="M -42.1907958984,-25.6756896973 c -0.758117675781,-2.14370727539 -0.896545410156,-3.86891174316 -0.896545410156,-5.12921142578 c 0.0,-1.46069335938 0.249176025391,-2.84799194336 0.814682006836,-4.09748840332 c 1.56153869629,-3.45030212402 5.03434753418,-5.85076904297 9.0679473877,-5.85076904297 c 5.49430847168,0.0 9.94830322266,4.4539642334 9.94830322266,9.94825744629 c 0.0,1.83151245117 -1.48460388184,3.31610107422 -3.31610107422,3.31610107422 c -1.83149719238,0.0 -3.31610107422,-1.48469543457 -3.31610107422,-3.31610107422 c 0.0,-1.83139038086 -1.48458862305,-3.31610107422 -3.31610107422,-3.31610107422 c -1.83149719238,0.0 -3.31610107422,1.48471069336 -3.31610107422,3.31610107422 c 0.0,2.57020568848 0.989517211914,4.88710021973 2.60510253906,6.5865020752 c 1.22210693359,1.28550720215 2.43139648438,2.09950256348 4.47590637207,2.69030761719"
+ android:strokeColor="#FFF2501D"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round"
+ android:trimPathEnd="0" />
+ </group>
+ <group
+ android:name="ridge_9" >
+ <path
+ android:name="ridge_2_path_0"
+ android:pathData="M -44.0646514893,-38.1672973633 c 1.19026184082,-1.77430725098 2.67503356934,-3.24531555176 4.55902099609,-4.27278137207 c 1.88395690918,-1.0274810791 4.04466247559,-1.61137390137 6.34175109863,-1.61137390137 c 2.28761291504,0.0 4.43991088867,0.579071044922 6.31831359863,1.59861755371 c 1.8784942627,1.01954650879 3.36059570312,2.4796295166 4.55279541016,4.24153137207"
+ android:strokeColor="#FFF2501D"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round"
+ android:trimPathStart="1" />
+ </group>
+ <group
+ android:name="ridge_10"
+ android:translateX="-97.5"
+ android:translateY="-142.5" >
+ <path
+ android:name="ridge_1_path_0"
+ android:pathData="M 71.7812347412,97.0507202148 c -2.27149963379,-1.31344604492 -4.71360778809,-2.07006835938 -7.56221008301,-2.07006835938 c -2.84869384766,0.0 -5.23320007324,0.779556274414 -7.34411621094,2.07006835938"
+ android:strokeColor="#FFF2501D"
+ android:strokeWidth="1.45"
+ android:strokeLineCap="round"
+ android:trimPathEnd="0" />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="exclamation"
+ android:translateX="16"
+ android:translateY="16" >
+ <group
+ android:name="group_2"
+ android:scaleX="0"
+ android:scaleY="0"
+ android:rotation="184" >
+ <path
+ android:name="path_2_merged"
+ android:pathData="M 1.35900878906,6.76104736328 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-2.69995117188 0.0,-2.69995117188 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,2.69995117188 0.0,2.69995117188 Z M 1.35363769531,1.36633300781 c 0.0,0.0 -2.69998168945,0.0 -2.69998168945,0.0 c 0.0,0.0 0.0,-8.09997558594 0.0,-8.09997558594 c 0.0,0.0 2.69998168945,0.0 2.69998168945,0.0 c 0.0,0.0 0.0,8.09997558594 0.0,8.09997558594 Z"
+ android:fillColor="#FFF2501D" />
+ </group>
+ </group>
+ <group
+ android:name="circle_outline"
+ android:translateX="16"
+ android:translateY="16" >
+ <group
+ android:name="group_1"
+ android:scaleX="1.12734"
+ android:scaleY="1.12734"
+ android:rotation="285" >
+ <path
+ android:name="path_3"
+ android:pathData="M 0.0101470947266,10.8087768555 c -5.96701049805,0.0 -10.8000183105,-4.8330078125 -10.8000183105,-10.8000488281 c 0.0,-5.96691894531 4.8330078125,-10.7999267578 10.8000183105,-10.7999267578 c 5.96697998047,0.0 10.799987793,4.8330078125 10.799987793,10.7999267578 c 0.0,5.96704101562 -4.8330078125,10.8000488281 -10.799987793,10.8000488281 Z"
+ android:strokeColor="#FFF2501D"
+ android:strokeWidth="2"
+ android:trimPathStart="1" />
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_animation.xml b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_animation.xml
new file mode 100644
index 0000000..8cc8ac2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/lockscreen_fingerprint_error_state_animation.xml
@@ -0,0 +1,65 @@
+<?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/lockscreen_fingerprint_error_state" >
+ <target
+ android:name="white_fingerprint_ridges"
+ android:animation="@anim/lockscreen_fingerprint_error_state_white_fingerprint_ridges_animation" />
+ <target
+ android:name="ridge_5_path"
+ android:animation="@anim/lockscreen_fingerprint_error_state_ridge_5_path_animation" />
+ <target
+ android:name="ridge_7_path"
+ android:animation="@anim/lockscreen_fingerprint_error_state_ridge_7_path_animation" />
+ <target
+ android:name="ridge_6_path"
+ android:animation="@anim/lockscreen_fingerprint_error_state_ridge_6_path_animation" />
+ <target
+ android:name="ridge_2_path"
+ android:animation="@anim/lockscreen_fingerprint_error_state_ridge_2_path_animation" />
+ <target
+ android:name="ridge_1_path"
+ android:animation="@anim/lockscreen_fingerprint_error_state_ridge_1_path_animation" />
+ <target
+ android:name="fingerprint_ridges"
+ android:animation="@anim/lockscreen_fingerprint_error_state_fingerprint_ridges_animation" />
+ <target
+ android:name="ridge_5_path_0"
+ android:animation="@anim/lockscreen_fingerprint_error_state_ridge_5_path_0_animation" />
+ <target
+ android:name="ridge_7_path_0"
+ android:animation="@anim/lockscreen_fingerprint_error_state_ridge_7_path_0_animation" />
+ <target
+ android:name="ridge_6_path_0"
+ android:animation="@anim/lockscreen_fingerprint_error_state_ridge_6_path_0_animation" />
+ <target
+ android:name="ridge_2_path_0"
+ android:animation="@anim/lockscreen_fingerprint_error_state_ridge_2_path_0_animation" />
+ <target
+ android:name="ridge_1_path_0"
+ android:animation="@anim/lockscreen_fingerprint_error_state_ridge_1_path_0_animation" />
+ <target
+ android:name="group_2"
+ android:animation="@anim/lockscreen_fingerprint_error_state_group_2_animation" />
+ <target
+ android:name="group_1"
+ android:animation="@anim/lockscreen_fingerprint_error_state_group_1_animation" />
+ <target
+ android:name="path_3"
+ android:animation="@anim/lockscreen_fingerprint_error_state_path_3_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0.xml
new file mode 100644
index 0000000..39c5211
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_0.xml
@@ -0,0 +1,19 @@
+<?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.16666666667,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1.xml
new file mode 100644
index 0000000..d3ae9d7
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_1.xml
@@ -0,0 +1,19 @@
+<?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.0,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2.xml
new file mode 100644
index 0000000..e10db01
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_2.xml
@@ -0,0 +1,19 @@
+<?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.8,0.0 0.5,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3.xml
new file mode 100644
index 0000000..736eac6
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/lockscreen_fingerprint_error_state_animation_interpolator_3.xml
@@ -0,0 +1,19 @@
+<?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.4,0.0 0.6,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index fca8231..1057464 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -61,7 +61,7 @@
android:scaleType="center"
android:contentDescription="@string/accessibility_phone_button" />
- <com.android.systemui.statusbar.KeyguardAffordanceView
+ <com.android.systemui.statusbar.phone.LockIcon
android:id="@+id/lock_icon"
android:layout_width="@dimen/keyguard_affordance_width"
android:layout_height="@dimen/keyguard_affordance_height"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 2e44547..81f2953 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -150,7 +150,7 @@
<integer name="heads_up_notification_minimum_time">2000</integer>
<!-- milliseconds before the heads up notification accepts touches. -->
- <integer name="heads_up_sensitivity_delay">700</integer>
+ <integer name="touch_acceptance_delay">700</integer>
<!-- The duration in seconds to wait before the dismiss buttons are shown. -->
<integer name="recents_task_bar_dismiss_delay_seconds">1</integer>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 0d331d1..3fbc76b 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -225,23 +225,23 @@
mSubpixelSmoothingRight = context.getResources().getFraction(
R.fraction.battery_subpixel_smoothing_right, 1, 1);
- mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mFramePaint = new Paint();
mFramePaint.setColor(frameColor);
mFramePaint.setDither(true);
mFramePaint.setStrokeWidth(0);
mFramePaint.setStyle(Paint.Style.FILL_AND_STROKE);
- mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mBatteryPaint = new Paint();
mBatteryPaint.setDither(true);
mBatteryPaint.setStrokeWidth(0);
mBatteryPaint.setStyle(Paint.Style.FILL_AND_STROKE);
- mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint = new Paint();
Typeface font = Typeface.create("sans-serif-condensed", Typeface.BOLD);
mTextPaint.setTypeface(font);
mTextPaint.setTextAlign(Paint.Align.CENTER);
- mWarningTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mWarningTextPaint = new Paint();
mWarningTextPaint.setColor(mColors[1]);
font = Typeface.create("sans-serif", Typeface.BOLD);
mWarningTextPaint.setTypeface(font);
@@ -249,7 +249,7 @@
mChargeColor = context.getColor(R.color.batterymeter_charge_color);
- mBoltPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mBoltPaint = new Paint();
mBoltPaint.setColor(context.getColor(R.color.batterymeter_bolt_color));
mBoltPoints = loadBoltPoints(res);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 7b555fc..6479dc5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -539,10 +539,11 @@
mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
mLockPatternUtils = new LockPatternUtils(mContext);
- mLockPatternUtils.setCurrentUser(ActivityManager.getCurrentUser());
+ KeyguardUpdateMonitor.setCurrentUser(ActivityManager.getCurrentUser());
// Assume keyguard is showing (unless it's disabled) until we know for sure...
- setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled());
+ setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled(
+ KeyguardUpdateMonitor.getCurrentUser()));
mTrustManager.reportKeyguardShowingChanged();
mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(mContext,
@@ -623,8 +624,10 @@
// Lock immediately based on setting if secure (user has a pin/pattern/password).
// This also "locks" the device when not secure to provide easy access to the
// camera while preventing unwanted input.
+ int currentUser = KeyguardUpdateMonitor.getCurrentUser();
final boolean lockImmediately =
- mLockPatternUtils.getPowerButtonInstantlyLocks() || !mLockPatternUtils.isSecure();
+ mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
+ || !mLockPatternUtils.isSecure(currentUser);
notifyScreenOffLocked();
@@ -670,7 +673,7 @@
// From DevicePolicyAdmin
final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
- .getMaximumTimeToLock(null, mLockPatternUtils.getCurrentUser());
+ .getMaximumTimeToLock(null, KeyguardUpdateMonitor.getCurrentUser());
long timeout;
if (policyTimeout > 0) {
@@ -719,7 +722,8 @@
}
private void maybeSendUserPresentBroadcast() {
- if (mSystemReady && mLockPatternUtils.isLockScreenDisabled()) {
+ if (mSystemReady && mLockPatternUtils.isLockScreenDisabled(
+ KeyguardUpdateMonitor.getCurrentUser())) {
// Lock screen is disabled because the user has set the preference to "None".
// In this case, send out ACTION_USER_PRESENT here instead of in
// handleKeyguardDone()
@@ -733,7 +737,7 @@
*/
public void onDreamingStarted() {
synchronized (this) {
- if (mScreenOn && mLockPatternUtils.isSecure()) {
+ if (mScreenOn && mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
doKeyguardLaterLocked();
}
}
@@ -974,12 +978,13 @@
return;
}
- if (mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
+ if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
+ && !lockedOrMissing) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
return;
}
- if (mLockPatternUtils.checkVoldPassword()) {
+ if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
// Without this, settings is not enabled until the lock screen first appears
setShowingLocked(false);
@@ -1072,7 +1077,7 @@
}
public boolean isSecure() {
- return mLockPatternUtils.isSecure()
+ return mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())
|| KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure();
}
@@ -1083,7 +1088,7 @@
* @param newUserId The id of the incoming user.
*/
public void setCurrentUser(int newUserId) {
- mLockPatternUtils.setCurrentUser(newUserId);
+ KeyguardUpdateMonitor.setCurrentUser(newUserId);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -1213,7 +1218,7 @@
private void sendUserPresentBroadcast() {
synchronized (this) {
if (mBootCompleted) {
- final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser());
+ final UserHandle currentUser = new UserHandle(KeyguardUpdateMonitor.getCurrentUser());
final UserManager um = (UserManager) mContext.getSystemService(
Context.USER_SERVICE);
List <UserInfo> userHandles = um.getProfiles(currentUser.getIdentifier());
@@ -1393,14 +1398,9 @@
updateActivityLockScreenState();
adjustStatusBarLocked();
sendUserPresentBroadcast();
- maybeStopListeningForFingerprint();
}
}
- private void maybeStopListeningForFingerprint() {
- mUpdateMonitor.stopListeningForFingerprint();
- }
-
private void adjustStatusBarLocked() {
if (mStatusBarManager == null) {
mStatusBarManager = (StatusBarManager)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 7271469..26c3b4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -87,6 +87,7 @@
import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.util.NotificationColorUtil;
import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SwipeHelper;
@@ -639,7 +640,7 @@
Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 1)) {
Log.d(TAG, "user hasn't seen notification about hidden notifications");
final LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
- if (!lockPatternUtils.isSecure()) {
+ if (!lockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
Log.d(TAG, "insecure lockscreen, skipping notification");
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
@@ -708,18 +709,6 @@
mNotificationListener.setNotificationsShown(keys);
}
- protected void setNotificationsShownAll() {
- ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
- final int N = activeNotifications.size();
-
- String[] keys = new String[N];
- for (int i = 0; i < N; i++) {
- NotificationData.Entry entry = activeNotifications.get(i);
- keys[i] = entry.key;
- }
- setNotificationsShown(keys);
- }
-
protected boolean isCurrentProfile(int userId) {
synchronized (mCurrentProfiles) {
return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null;
@@ -795,7 +784,8 @@
protected void applyColorsAndBackgrounds(StatusBarNotification sbn,
NotificationData.Entry entry) {
- if (entry.expanded.getId() != com.android.internal.R.id.status_bar_latest_event_content) {
+ if (entry.getContentView().getId()
+ != com.android.internal.R.id.status_bar_latest_event_content) {
// Using custom RemoteViews
if (entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD
&& entry.targetSdk < Build.VERSION_CODES.LOLLIPOP) {
@@ -820,8 +810,9 @@
public boolean isMediaNotification(NotificationData.Entry entry) {
// TODO: confirm that there's a valid media key
- return entry.expandedBig != null &&
- entry.expandedBig.findViewById(com.android.internal.R.id.media_actions) != null;
+ return entry.getExpandedContentView() != null &&
+ entry.getExpandedContentView()
+ .findViewById(com.android.internal.R.id.media_actions) != null;
}
// The gear button in the guts that links to the app's own notification settings
@@ -1145,9 +1136,9 @@
}
/**
- * if the interrupting notification had a fullscreen intent, fire it now.
+ * If there is an active heads-up notification and it has a fullscreen intent, fire it now.
*/
- public abstract void escalateHeadsUp();
+ public abstract void maybeEscalateHeadsUp();
/**
* Save the current "public" (locked and secure) state of the lockscreen.
@@ -1348,8 +1339,8 @@
View publicViewLocal = null;
if (publicNotification != null) {
try {
- publicViewLocal = publicNotification.contentView.apply(mContext, contentContainerPublic,
- mOnClickHandler);
+ publicViewLocal = publicNotification.contentView.apply(mContext,
+ contentContainerPublic, mOnClickHandler);
if (publicViewLocal != null) {
publicViewLocal.setIsRootNamespace(true);
@@ -1456,9 +1447,7 @@
entry.row = row;
entry.row.setHeightRange(mRowMinHeight, maxHeight);
entry.row.setOnActivatedListener(this);
- entry.expanded = contentViewLocal;
- entry.expandedPublic = publicViewLocal;
- entry.setBigContentView(bigContentViewLocal);
+ entry.row.setExpandable(bigContentViewLocal != null);
applyColorsAndBackgrounds(sbn, entry);
@@ -1547,12 +1536,13 @@
// See if we have somewhere to put that remote input
if (remoteInput != null) {
- if (entry.expandedBig != null) {
- inflateRemoteInput(entry.expandedBig, remoteInput, actions);
+ View bigContentView = entry.getExpandedContentView();
+ if (bigContentView != null) {
+ inflateRemoteInput(bigContentView, remoteInput, actions);
}
- View headsUpChild = entry.row.getPrivateLayout().getHeadsUpChild();
- if (headsUpChild != null) {
- inflateRemoteInput(headsUpChild, remoteInput, actions);
+ View headsUpContentView = entry.getHeadsUpContentView();
+ if (headsUpContentView != null) {
+ inflateRemoteInput(headsUpContentView, remoteInput, actions);
}
}
@@ -1701,7 +1691,6 @@
boolean clearNotificationEffects =
(mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED);
mBarService.onPanelRevealed(clearNotificationEffects);
- setNotificationsShownAll();
} else {
mBarService.onPanelHidden();
}
@@ -1895,15 +1884,14 @@
logUpdate(entry, n);
}
boolean applyInPlace = shouldApplyInPlace(entry, n);
- final boolean shouldInterrupt = shouldInterrupt(notification);
- final boolean alertAgain = alertAgain(entry, n);
+ boolean shouldInterrupt = shouldInterrupt(notification);
+ boolean alertAgain = alertAgain(entry, n);
entry.notification = notification;
mGroupManager.onEntryUpdated(entry, entry.notification);
boolean updateSuccessful = false;
if (applyInPlace) {
- // We can just reapply the notifications in place
if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
try {
if (entry.icon != null) {
@@ -1924,7 +1912,7 @@
updateSuccessful = true;
}
catch (RuntimeException e) {
- // It failed to add cleanly. Log, and remove the view from the panel.
+ // It failed to apply cleanly.
Log.w(TAG, "Couldn't reapply views for package " + n.contentView.getPackage(), e);
}
}
@@ -1948,11 +1936,12 @@
// swipe-dismissable)
updateNotificationVetoButton(entry.row, notification);
- // Is this for you?
- boolean isForCurrentUser = isNotificationForCurrentProfiles(notification);
- if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
+ if (DEBUG) {
+ // Is this for you?
+ boolean isForCurrentUser = isNotificationForCurrentProfiles(notification);
+ Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
+ }
- // Recalculate the position of the sliding windows and the titles.
setAreThereNotifications();
}
@@ -1963,7 +1952,7 @@
StatusBarNotification oldNotification = oldEntry.notification;
Log.d(TAG, "old notification: when=" + oldNotification.getNotification().when
+ " ongoing=" + oldNotification.isOngoing()
- + " expanded=" + oldEntry.expanded
+ + " expanded=" + oldEntry.getContentView()
+ " contentView=" + oldNotification.getNotification().contentView
+ " bigContentView=" + oldNotification.getNotification().bigContentView
+ " publicView=" + oldNotification.getNotification().publicVersion
@@ -1976,7 +1965,8 @@
}
/**
- * @return whether we can just reapply the RemoteViews in place when it is updated
+ * @return whether we can just reapply the RemoteViews from a notification in-place when it is
+ * updated
*/
private boolean shouldApplyInPlace(Entry entry, Notification n) {
StatusBarNotification oldNotification = entry.notification;
@@ -1994,15 +1984,15 @@
final Notification publicNotification = n.publicVersion;
final RemoteViews publicContentView = publicNotification != null
? publicNotification.contentView : null;
- boolean contentsUnchanged = entry.expanded != null
+ boolean contentsUnchanged = entry.getContentView() != null
&& contentView.getPackage() != null
&& oldContentView.getPackage() != null
&& oldContentView.getPackage().equals(contentView.getPackage())
&& oldContentView.getLayoutId() == contentView.getLayoutId();
// large view may be null
boolean bigContentsUnchanged =
- (entry.getBigContentView() == null && bigContentView == null)
- || ((entry.getBigContentView() != null && bigContentView != null)
+ (entry.getExpandedContentView() == null && bigContentView == null)
+ || ((entry.getExpandedContentView() != null && bigContentView != null)
&& bigContentView.getPackage() != null
&& oldBigContentView.getPackage() != null
&& oldBigContentView.getPackage().equals(bigContentView.getPackage())
@@ -2034,12 +2024,12 @@
: null;
// Reapply the RemoteViews
- contentView.reapply(mContext, entry.expanded, mOnClickHandler);
- if (bigContentView != null && entry.getBigContentView() != null) {
- bigContentView.reapply(mContext, entry.getBigContentView(),
+ contentView.reapply(mContext, entry.getContentView(), mOnClickHandler);
+ if (bigContentView != null && entry.getExpandedContentView() != null) {
+ bigContentView.reapply(mContext, entry.getExpandedContentView(),
mOnClickHandler);
}
- View headsUpChild = entry.row.getPrivateLayout().getHeadsUpChild();
+ View headsUpChild = entry.getHeadsUpContentView();
if (headsUpContentView != null && headsUpChild != null) {
headsUpContentView.reapply(mContext, headsUpChild, mOnClickHandler);
}
@@ -2062,7 +2052,7 @@
}
protected void notifyHeadsUpScreenOff() {
- escalateHeadsUp();
+ maybeEscalateHeadsUp();
}
private boolean alertAgain(Entry oldEntry, Notification newNotification) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index cb8217e..9ef495d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -84,7 +84,6 @@
private ExpansionLogger mLogger;
private String mLoggingKey;
private boolean mWasReset;
-
private NotificationGuts mGuts;
private StatusBarNotification mStatusBarNotification;
private boolean mIsHeadsUp;
@@ -102,6 +101,7 @@
private ViewStub mGutsStub;
private boolean mHasExpandAction;
private boolean mIsSystemChildExpanded;
+ private boolean mIsPinned;
private OnClickListener mExpandClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
@@ -109,7 +109,6 @@
!mChildrenExpanded);
}
};
- private boolean mInShade;
public NotificationContentView getPrivateLayout() {
return mPrivateLayout;
@@ -284,12 +283,18 @@
return realActualHeight;
}
- public void setInShade(boolean inShade) {
- mInShade = inShade;
+ /**
+ * Set this notification to be pinned to the top if {@link #isHeadsUp()} is true. By doing this
+ * the notification will be rendered on top of the screen.
+ *
+ * @param pinned whether it is pinned
+ */
+ public void setPinned(boolean pinned) {
+ mIsPinned = pinned;
}
- public boolean isInShade() {
- return mInShade;
+ public boolean isPinned() {
+ return mIsPinned;
}
public int getHeadsUpHeight() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 1c53655..110b14c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -32,37 +32,34 @@
import com.android.systemui.R;
/**
- * A frame layout containing the actual payload of the notification, including the contracted and
- * expanded layout. This class is responsible for clipping the content and and switching between the
- * expanded and contracted view depending on its clipped size.
+ * A frame layout containing the actual payload of the notification, including the contracted,
+ * expanded and heads up layout. This class is responsible for clipping the content and and
+ * switching between the expanded, contracted and the heads up view depending on its clipped size.
*/
public class NotificationContentView extends FrameLayout {
private static final long ANIMATION_DURATION_LENGTH = 170;
- private static final int CONTRACTED = 1;
- private static final int EXPANDED = 2;
- private static final int HEADSUP = 3;
+ private static final int VISIBLE_TYPE_CONTRACTED = 0;
+ private static final int VISIBLE_TYPE_EXPANDED = 1;
+ private static final int VISIBLE_TYPE_HEADSUP = 2;
private final Rect mClipBounds = new Rect();
+ private final int mSmallHeight;
+ private final int mHeadsUpHeight;
+ private final Interpolator mLinearInterpolator = new LinearInterpolator();
private View mContractedChild;
private View mExpandedChild;
private View mHeadsUpChild;
private NotificationViewWrapper mContractedWrapper;
-
- private final int mSmallHeight;
- private final int mHeadsUpHeight;
private int mClipTopAmount;
-
private int mContentHeight;
-
- private final Interpolator mLinearInterpolator = new LinearInterpolator();
- private int mVisibleView = CONTRACTED;
-
+ private int mVisibleType = VISIBLE_TYPE_CONTRACTED;
private boolean mDark;
private final Paint mFadePaint = new Paint();
private boolean mAnimate;
+ private boolean mIsHeadsUp;
private ViewTreeObserver.OnPreDrawListener mEnableAnimationPredrawListener
= new ViewTreeObserver.OnPreDrawListener() {
@Override
@@ -72,7 +69,6 @@
return true;
}
};
- private boolean mIsHeadsUp;
public NotificationContentView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -105,9 +101,9 @@
// An actual height is set
size = Math.min(maxSize, layoutParams.height);
}
- int spec = size == Integer.MAX_VALUE ?
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED) :
- MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
+ int spec = size == Integer.MAX_VALUE
+ ? MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
+ : MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
mExpandedChild.measure(widthMeasureSpec, spec);
maxChildHeight = Math.max(maxChildHeight, mExpandedChild.getMeasuredHeight());
}
@@ -153,7 +149,7 @@
mContractedChild = null;
mExpandedChild = null;
mHeadsUpChild = null;
- mVisibleView = CONTRACTED;
+ mVisibleType = VISIBLE_TYPE_CONTRACTED;
if (resetActualHeight) {
mContentHeight = mSmallHeight;
}
@@ -263,30 +259,32 @@
if (mContractedChild == null) {
return;
}
- int visibleView = calculateVisibleView();
- if (visibleView != mVisibleView || force) {
- if (animate && mExpandedChild != null) {
- runSwitchAnimation(visibleView);
+ int visibleType = calculateVisibleType();
+ if (visibleType != mVisibleType || force) {
+ if (animate && (visibleType == VISIBLE_TYPE_EXPANDED && mExpandedChild != null)
+ || (visibleType == VISIBLE_TYPE_HEADSUP && mHeadsUpChild != null)
+ || visibleType == VISIBLE_TYPE_CONTRACTED) {
+ runSwitchAnimation(visibleType);
} else {
- updateViewVisibilities(visibleView);
+ updateViewVisibilities(visibleType);
}
- mVisibleView = visibleView;
+ mVisibleType = visibleType;
}
}
- private void updateViewVisibilities(int visibleView) {
- boolean contractedVisible = visibleView == CONTRACTED;
+ private void updateViewVisibilities(int visibleType) {
+ boolean contractedVisible = visibleType == VISIBLE_TYPE_CONTRACTED;
mContractedChild.setVisibility(contractedVisible ? View.VISIBLE : View.INVISIBLE);
mContractedChild.setAlpha(contractedVisible ? 1f : 0f);
mContractedChild.setLayerType(LAYER_TYPE_NONE, null);
if (mExpandedChild != null) {
- boolean expandedVisible = visibleView == EXPANDED;
+ boolean expandedVisible = visibleType == VISIBLE_TYPE_EXPANDED;
mExpandedChild.setVisibility(expandedVisible ? View.VISIBLE : View.INVISIBLE);
mExpandedChild.setAlpha(expandedVisible ? 1f : 0f);
mExpandedChild.setLayerType(LAYER_TYPE_NONE, null);
}
if (mHeadsUpChild != null) {
- boolean headsUpVisible = visibleView == HEADSUP;
+ boolean headsUpVisible = visibleType == VISIBLE_TYPE_HEADSUP;
mHeadsUpChild.setVisibility(headsUpVisible ? View.VISIBLE : View.INVISIBLE);
mHeadsUpChild.setAlpha(headsUpVisible ? 1f : 0f);
mHeadsUpChild.setLayerType(LAYER_TYPE_NONE, null);
@@ -294,9 +292,9 @@
setLayerType(LAYER_TYPE_NONE, null);
}
- private void runSwitchAnimation(int visibleView) {
- View shownView = getViewFromFlag(visibleView);
- View hiddenView = getViewFromFlag(mVisibleView);
+ private void runSwitchAnimation(int visibleType) {
+ View shownView = getViewForVisibleType(visibleType);
+ View hiddenView = getViewForVisibleType(mVisibleType);
shownView.setVisibility(View.VISIBLE);
hiddenView.setVisibility(View.VISIBLE);
shownView.setLayerType(LAYER_TYPE_HARDWARE, mFadePaint);
@@ -314,34 +312,42 @@
.withEndAction(new Runnable() {
@Override
public void run() {
- updateViewVisibilities(mVisibleView);
+ updateViewVisibilities(mVisibleType);
}
});
}
- private View getViewFromFlag(int visibleView) {
- switch (visibleView) {
- case EXPANDED:
+ /**
+ * @param visibleType one of the static enum types in this view
+ * @return the corresponding view according to the given visible type
+ */
+ private View getViewForVisibleType(int visibleType) {
+ switch (visibleType) {
+ case VISIBLE_TYPE_EXPANDED:
return mExpandedChild;
- case HEADSUP:
+ case VISIBLE_TYPE_HEADSUP:
return mHeadsUpChild;
+ default:
+ return mContractedChild;
}
- return mContractedChild;
}
- private int calculateVisibleView() {
+ /**
+ * @return one of the static enum types in this view, calculated form the current state
+ */
+ private int calculateVisibleType() {
boolean noExpandedChild = mExpandedChild == null;
if (mIsHeadsUp && mHeadsUpChild != null) {
if (mContentHeight <= mHeadsUpChild.getHeight() || noExpandedChild) {
- return HEADSUP;
+ return VISIBLE_TYPE_HEADSUP;
} else {
- return EXPANDED;
+ return VISIBLE_TYPE_EXPANDED;
}
} else {
if (mContentHeight <= mSmallHeight || noExpandedChild) {
- return CONTRACTED;
+ return VISIBLE_TYPE_CONTRACTED;
} else {
- return EXPANDED;
+ return VISIBLE_TYPE_EXPANDED;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 429889d..2a8b4ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -45,9 +45,6 @@
public StatusBarNotification notification;
public StatusBarIconView icon;
public ExpandableNotificationRow row; // the outer expanded view
- public View expanded; // the inflated RemoteViews
- public View expandedPublic; // for insecure lockscreens
- public View expandedBig;
private boolean interruption;
public boolean autoRedacted; // whether the redacted notification was generated by us
public boolean legacy; // whether the notification has a legacy, dark background
@@ -58,14 +55,6 @@
this.notification = n;
this.icon = ic;
}
- public void setBigContentView(View bigContentView) {
- this.expandedBig = bigContentView;
- row.setExpandable(bigContentView != null);
- }
- public View getBigContentView() {
- return expandedBig;
- }
- public View getPublicContentView() { return expandedPublic; }
public void setInterruption() {
interruption = true;
@@ -81,15 +70,28 @@
public void reset() {
// NOTE: Icon needs to be preserved for now.
// We should fix this at some point.
- expanded = null;
- expandedPublic = null;
- expandedBig = null;
autoRedacted = false;
legacy = false;
if (row != null) {
row.reset();
}
}
+
+ public View getContentView() {
+ return row.getPrivateLayout().getContractedChild();
+ }
+
+ public View getExpandedContentView() {
+ return row.getPrivateLayout().getExpandedChild();
+ }
+
+ public View getHeadsUpContentView() {
+ return row.getPrivateLayout().getHeadsUpChild();
+ }
+
+ public View getPublicContentView() {
+ return row.getPublicLayout().getContractedChild();
+ }
}
private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
@@ -258,7 +260,7 @@
*/
public boolean hasActiveClearableNotifications() {
for (Entry e : mSortedAndFiltered) {
- if (e.expanded != null) { // the view successfully inflated
+ if (e.getContentView() != null) { // the view successfully inflated
if (e.notification.isClearable()) {
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 3997807..fe7bc97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -27,7 +27,7 @@
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
/**
- * A Helper class to handle touches on the heads-up views
+ * A helper class to handle touches on the heads-up views.
*/
public class HeadsUpTouchHelper implements Gefingerpoken {
@@ -37,19 +37,30 @@
private float mTouchSlop;
private float mInitialTouchX;
private float mInitialTouchY;
- private boolean mMotionOnHeadsUpView;
+ private boolean mTouchingHeadsUpView;
private boolean mTrackingHeadsUp;
private boolean mCollapseSnoozes;
private NotificationPanelView mPanel;
private ExpandableNotificationRow mPickedChild;
+ public HeadsUpTouchHelper(HeadsUpManager headsUpManager,
+ NotificationStackScrollLayout stackScroller,
+ NotificationPanelView notificationPanelView) {
+ mHeadsUpManager = headsUpManager;
+ mStackScroller = stackScroller;
+ mPanel = notificationPanelView;
+ Context context = stackScroller.getContext();
+ final ViewConfiguration configuration = ViewConfiguration.get(context);
+ mTouchSlop = configuration.getScaledTouchSlop();
+ }
+
public boolean isTrackingHeadsUp() {
return mTrackingHeadsUp;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
- if (!mMotionOnHeadsUpView && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
+ if (!mTouchingHeadsUpView && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
return false;
}
int pointerIndex = event.findPointerIndex(mTrackingPointer);
@@ -65,10 +76,10 @@
mInitialTouchX = x;
setTrackingHeadsUp(false);
ExpandableView child = mStackScroller.getChildAtPosition(x, y);
- mMotionOnHeadsUpView = false;
+ mTouchingHeadsUpView = false;
if (child instanceof ExpandableNotificationRow) {
mPickedChild = (ExpandableNotificationRow) child;
- mMotionOnHeadsUpView = mPickedChild.isHeadsUp() && !mPickedChild.isInShade();
+ mTouchingHeadsUpView = mPickedChild.isHeadsUp() && mPickedChild.isPinned();
}
break;
case MotionEvent.ACTION_POINTER_UP:
@@ -97,7 +108,8 @@
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- if (mPickedChild != null && mMotionOnHeadsUpView) {
+ if (mPickedChild != null && mTouchingHeadsUpView) {
+ // We may swallow this click if the heads up just came in.
if (mHeadsUpManager.shouldSwallowClick(
mPickedChild.getStatusBarNotification().getKey())) {
endMotion();
@@ -141,20 +153,6 @@
private void endMotion() {
mTrackingPointer = -1;
mPickedChild = null;
- mMotionOnHeadsUpView = false;
- }
-
- public ExpandableView getPickedChild() {
- return mPickedChild;
- }
-
- public void bind(HeadsUpManager headsUpManager, NotificationStackScrollLayout stackScroller,
- NotificationPanelView notificationPanelView) {
- mHeadsUpManager = headsUpManager;
- mStackScroller = stackScroller;
- mPanel = notificationPanelView;
- Context context = stackScroller.getContext();
- final ViewConfiguration configuration = ViewConfiguration.get(context);
- mTouchSlop = configuration.getScaledTouchSlop();
+ mTouchingHeadsUpView = false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index e5ef6ff..fabc1a6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -86,7 +86,7 @@
private KeyguardAffordanceView mCameraImageView;
private KeyguardAffordanceView mPhoneImageView;
- private KeyguardAffordanceView mLockIcon;
+ private LockIcon mLockIcon;
private TextView mIndicationText;
private ViewGroup mPreviewContainer;
@@ -102,11 +102,8 @@
private AccessibilityController mAccessibilityController;
private PhoneStatusBar mPhoneStatusBar;
- private final TrustDrawable mTrustDrawable;
private final Interpolator mLinearOutSlowInInterpolator;
- private int mLastUnlockIconRes = 0;
private boolean mPrewarmSent;
- private boolean mTransientFpError;
public KeyguardBottomAreaView(Context context) {
this(context, null);
@@ -123,7 +120,6 @@
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- mTrustDrawable = new TrustDrawable(mContext);
mLinearOutSlowInInterpolator =
AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
}
@@ -169,20 +165,19 @@
mPreviewContainer = (ViewGroup) findViewById(R.id.preview_container);
mCameraImageView = (KeyguardAffordanceView) findViewById(R.id.camera_button);
mPhoneImageView = (KeyguardAffordanceView) findViewById(R.id.phone_button);
- mLockIcon = (KeyguardAffordanceView) findViewById(R.id.lock_icon);
+ mLockIcon = (LockIcon) findViewById(R.id.lock_icon);
mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
watchForCameraPolicyChanges();
updateCameraVisibility();
updatePhoneVisibility();
mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
mUnlockMethodCache.addListener(this);
- updateLockIcon();
+ mLockIcon.update();
setClipChildren(false);
setClipToPadding(false);
mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext));
inflatePreviews();
mLockIcon.setOnClickListener(this);
- mLockIcon.setBackground(mTrustDrawable);
mLockIcon.setOnLongClickListener(this);
mCameraImageView.setOnClickListener(this);
mPhoneImageView.setOnClickListener(this);
@@ -222,6 +217,7 @@
public void setAccessibilityController(AccessibilityController accessibilityController) {
mAccessibilityController = accessibilityController;
+ mLockIcon.setAccessibilityController(accessibilityController);
accessibilityController.addStateChangedCallback(this);
}
@@ -233,9 +229,9 @@
private Intent getCameraIntent() {
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
boolean currentUserHasTrust = updateMonitor.getUserHasTrust(
- mLockPatternUtils.getCurrentUser());
- return mLockPatternUtils.isSecure() && !currentUserHasTrust
- ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
+ KeyguardUpdateMonitor.getCurrentUser());
+ boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
+ return (secure && !currentUserHasTrust) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
}
private void updateCameraVisibility() {
@@ -245,7 +241,7 @@
}
ResolveInfo resolved = mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
PackageManager.MATCH_DEFAULT_ONLY,
- mLockPatternUtils.getCurrentUser());
+ KeyguardUpdateMonitor.getCurrentUser());
boolean visible = !isCameraDisabledByDpm() && resolved != null
&& getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance);
mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
@@ -294,21 +290,7 @@
mPhoneImageView.setClickable(touchExplorationEnabled);
mCameraImageView.setFocusable(accessibilityEnabled);
mPhoneImageView.setFocusable(accessibilityEnabled);
- updateLockIconClickability();
- }
-
- private void updateLockIconClickability() {
- if (mAccessibilityController == null) {
- return;
- }
- boolean clickToUnlock = mAccessibilityController.isTouchExplorationEnabled();
- boolean clickToForceLock = mUnlockMethodCache.isTrustManaged()
- && !mAccessibilityController.isAccessibilityEnabled();
- boolean longClickToForceLock = mUnlockMethodCache.isTrustManaged()
- && !clickToForceLock;
- mLockIcon.setClickable(clickToForceLock || clickToUnlock);
- mLockIcon.setLongClickable(longClickToForceLock);
- mLockIcon.setFocusable(mAccessibilityController.isAccessibilityEnabled());
+ mLockIcon.update();
}
@Override
@@ -339,13 +321,13 @@
0 /* velocityDp - N/A */);
mIndicationController.showTransientIndication(
R.string.keyguard_indication_trust_disabled);
- mLockPatternUtils.requireCredentialEntry(mLockPatternUtils.getCurrentUser());
+ mLockPatternUtils.requireCredentialEntry(KeyguardUpdateMonitor.getCurrentUser());
}
public void prewarmCamera() {
Intent intent = getCameraIntent();
String targetPackage = PreviewInflater.getTargetPackage(mContext, intent,
- mLockPatternUtils.getCurrentUser());
+ KeyguardUpdateMonitor.getCurrentUser());
if (targetPackage != null) {
Intent prewarm = new Intent(MediaStore.ACTION_STILL_IMAGE_CAMERA_PREWARM);
prewarm.setPackage(targetPackage);
@@ -361,7 +343,7 @@
mPrewarmSent = false;
Intent intent = getCameraIntent();
String targetPackage = PreviewInflater.getTargetPackage(mContext, intent,
- mLockPatternUtils.getCurrentUser());
+ KeyguardUpdateMonitor.getCurrentUser());
if (targetPackage != null) {
Intent prewarm = new Intent(MediaStore.ACTION_STILL_IMAGE_CAMERA_COOLDOWN);
prewarm.setPackage(targetPackage);
@@ -375,7 +357,7 @@
mPrewarmSent = false;
final Intent intent = getCameraIntent();
boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity(
- mContext, intent, mLockPatternUtils.getCurrentUser());
+ mContext, intent, KeyguardUpdateMonitor.getCurrentUser());
if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) {
AsyncTask.execute(new Runnable() {
@Override
@@ -409,69 +391,12 @@
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
- if (isShown()) {
- mTrustDrawable.start();
- } else {
- mTrustDrawable.stop();
- }
if (changedView == this && visibility == VISIBLE) {
- updateLockIcon();
+ mLockIcon.update();
updateCameraVisibility();
}
}
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mTrustDrawable.stop();
- }
-
- private void updateLockIcon() {
- boolean visible = isShown() && KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
- if (visible) {
- mTrustDrawable.start();
- } else {
- mTrustDrawable.stop();
- }
- if (!visible) {
- return;
- }
- // TODO: Real icon for facelock.
- boolean isFingerprintIcon =
- KeyguardUpdateMonitor.getInstance(mContext).isFingerprintDetectionRunning();
- boolean anyFingerprintIcon = isFingerprintIcon || mTransientFpError;
- int iconRes = mTransientFpError ? R.drawable.ic_fingerprint_error
- : isFingerprintIcon ? R.drawable.ic_fingerprint
- : mUnlockMethodCache.isFaceUnlockRunning()
- ? com.android.internal.R.drawable.ic_account_circle
- : mUnlockMethodCache.isCurrentlyInsecure() ? R.drawable.ic_lock_open_24dp
- : R.drawable.ic_lock_24dp;
-
- if (mLastUnlockIconRes != iconRes) {
- Drawable icon = mContext.getDrawable(iconRes);
- int iconHeight = getResources().getDimensionPixelSize(
- R.dimen.keyguard_affordance_icon_height);
- int iconWidth = getResources().getDimensionPixelSize(
- R.dimen.keyguard_affordance_icon_width);
- if (!anyFingerprintIcon && (icon.getIntrinsicHeight() != iconHeight
- || icon.getIntrinsicWidth() != iconWidth)) {
- icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
- }
- mLockIcon.setImageDrawable(icon);
- mLockIcon.setPaddingRelative(0, 0, 0, anyFingerprintIcon
- ? getResources().getDimensionPixelSize(
- R.dimen.fingerprint_icon_additional_padding)
- : 0);
- mLockIcon.setRestingAlpha(
- anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
- }
-
- // Hide trust circle when fingerprint is running.
- boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !anyFingerprintIcon;
- mTrustDrawable.setTrustManaged(trustManaged);
- updateLockIconClickability();
- }
-
public KeyguardAffordanceView getPhoneView() {
return mPhoneImageView;
}
@@ -503,7 +428,7 @@
@Override
public void onUnlockMethodStateChanged() {
- updateLockIcon();
+ mLockIcon.update();
updateCameraVisibility();
}
@@ -563,9 +488,8 @@
private final Runnable mTransientFpErrorClearRunnable = new Runnable() {
@Override
public void run() {
- mTransientFpError = false;
+ mLockIcon.setTransientFpError(false);
mIndicationController.hideTransientIndication();
- updateLockIcon();
}
};
@@ -578,17 +502,17 @@
@Override
public void onScreenTurnedOn() {
- updateLockIcon();
+ mLockIcon.update();
}
@Override
public void onScreenTurnedOff(int why) {
- updateLockIcon();
+ mLockIcon.update();
}
@Override
public void onKeyguardVisibilityChanged(boolean showing) {
- updateLockIcon();
+ mLockIcon.update();
}
@Override
@@ -597,24 +521,21 @@
@Override
public void onFingerprintRunningStateChanged(boolean running) {
- updateLockIcon();
+ mLockIcon.update();
}
@Override
public void onFingerprintHelp(int msgId, String helpString) {
- mTransientFpError = true;
+ mLockIcon.setTransientFpError(true);
mIndicationController.showTransientIndication(helpString,
getResources().getColor(R.color.system_warning_color, null));
removeCallbacks(mTransientFpErrorClearRunnable);
postDelayed(mTransientFpErrorClearRunnable, TRANSIENT_FP_ERROR_TIMEOUT);
- updateLockIcon();
}
@Override
public void onFingerprintError(int msgId, String errString) {
// TODO: Go to bouncer if this is "too many attempts" (lockout) error.
- Log.i(TAG, "FP Error: " + errString);
- updateLockIcon();
}
};
@@ -622,29 +543,4 @@
KeyguardIndicationController keyguardIndicationController) {
mIndicationController = keyguardIndicationController;
}
-
- /**
- * A wrapper around another Drawable that overrides the intrinsic size.
- */
- private static class IntrinsicSizeDrawable extends InsetDrawable {
-
- private final int mIntrinsicWidth;
- private final int mIntrinsicHeight;
-
- public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
- super(drawable, 0);
- mIntrinsicWidth = intrinsicWidth;
- mIntrinsicHeight = intrinsicHeight;
- }
-
- @Override
- public int getIntrinsicWidth() {
- return mIntrinsicWidth;
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mIntrinsicHeight;
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
new file mode 100644
index 0000000..66f3232
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -0,0 +1,212 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.KeyguardAffordanceView;
+import com.android.systemui.statusbar.policy.AccessibilityController;
+
+/**
+ * Manages the different states and animations of the unlock icon.
+ */
+public class LockIcon extends KeyguardAffordanceView {
+
+
+ private static final int STATE_LOCKED = 0;
+ private static final int STATE_LOCK_OPEN = 1;
+ private static final int STATE_FACE_UNLOCK = 2;
+ private static final int STATE_FINGERPRINT = 3;
+ private static final int STATE_FINGERPRINT_ERROR = 4;
+
+ private int mLastState = 0;
+ private boolean mTransientFpError;
+ private final TrustDrawable mTrustDrawable;
+ private final UnlockMethodCache mUnlockMethodCache;
+ private AccessibilityController mAccessibilityController;
+
+ public LockIcon(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mTrustDrawable = new TrustDrawable(context);
+ setBackground(mTrustDrawable);
+ mUnlockMethodCache = UnlockMethodCache.getInstance(context);
+ }
+
+ @Override
+ protected void onVisibilityChanged(View changedView, int visibility) {
+ super.onVisibilityChanged(changedView, visibility);
+ if (isShown()) {
+ mTrustDrawable.start();
+ } else {
+ mTrustDrawable.stop();
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mTrustDrawable.stop();
+ }
+
+ public void setTransientFpError(boolean transientFpError) {
+ mTransientFpError = transientFpError;
+ update();
+ }
+
+ public void update() {
+ boolean visible = isShown() && KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
+ if (visible) {
+ mTrustDrawable.start();
+ } else {
+ mTrustDrawable.stop();
+ }
+ if (!visible) {
+ return;
+ }
+ // TODO: Real icon for facelock.
+ int state = getState();
+ boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR;
+ if (state != mLastState) {
+ int iconRes = getAnimationResForTransition(mLastState, state);
+ if (iconRes == -1) {
+ iconRes = getIconForState(state);
+ }
+ Drawable icon = mContext.getDrawable(iconRes);
+ AnimatedVectorDrawable animation = null;
+ if (icon instanceof AnimatedVectorDrawable) {
+ animation = (AnimatedVectorDrawable) icon;
+ }
+ int iconHeight = getResources().getDimensionPixelSize(
+ R.dimen.keyguard_affordance_icon_height);
+ int iconWidth = getResources().getDimensionPixelSize(
+ R.dimen.keyguard_affordance_icon_width);
+ if (!anyFingerprintIcon && (icon.getIntrinsicHeight() != iconHeight
+ || icon.getIntrinsicWidth() != iconWidth)) {
+ icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
+ }
+ setPaddingRelative(0, 0, 0, anyFingerprintIcon
+ ? getResources().getDimensionPixelSize(
+ R.dimen.fingerprint_icon_additional_padding)
+ : 0);
+ setRestingAlpha(
+ anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
+ setImageDrawable(icon);
+ if (animation != null) {
+ animation.start();
+ }
+ }
+
+ // Hide trust circle when fingerprint is running.
+ boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !anyFingerprintIcon;
+ mTrustDrawable.setTrustManaged(trustManaged);
+ mLastState = state;
+ updateClickability();
+ }
+
+ private void updateClickability() {
+ if (mAccessibilityController == null) {
+ return;
+ }
+ boolean clickToUnlock = mAccessibilityController.isTouchExplorationEnabled();
+ boolean clickToForceLock = mUnlockMethodCache.isTrustManaged()
+ && !mAccessibilityController.isAccessibilityEnabled();
+ boolean longClickToForceLock = mUnlockMethodCache.isTrustManaged()
+ && !clickToForceLock;
+ setClickable(clickToForceLock || clickToUnlock);
+ setLongClickable(longClickToForceLock);
+ setFocusable(mAccessibilityController.isAccessibilityEnabled());
+ }
+
+ public void setAccessibilityController(AccessibilityController accessibilityController) {
+ mAccessibilityController = accessibilityController;
+ }
+
+ private int getIconForState(int state) {
+ switch (state) {
+ case STATE_LOCKED:
+ return R.drawable.ic_lock_24dp;
+ case STATE_LOCK_OPEN:
+ return R.drawable.ic_lock_open_24dp;
+ case STATE_FACE_UNLOCK:
+ return com.android.internal.R.drawable.ic_account_circle;
+ case STATE_FINGERPRINT:
+ return R.drawable.ic_fingerprint;
+ case STATE_FINGERPRINT_ERROR:
+ return R.drawable.ic_fingerprint_error;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private int getAnimationResForTransition(int oldState, int newState) {
+ if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
+ return R.drawable.lockscreen_fingerprint_error_state_animation;
+ } else {
+ return -1;
+ }
+ }
+
+ private int getState() {
+ boolean fingerprintRunning =
+ KeyguardUpdateMonitor.getInstance(mContext).isFingerprintDetectionRunning();
+ if (mTransientFpError) {
+ return STATE_FINGERPRINT_ERROR;
+ } else if (fingerprintRunning) {
+ return STATE_FINGERPRINT;
+ } else if (mUnlockMethodCache.isFaceUnlockRunning()) {
+ return STATE_FACE_UNLOCK;
+ } else if (mUnlockMethodCache.isCurrentlyInsecure()) {
+ return STATE_LOCK_OPEN;
+ } else {
+ return STATE_LOCKED;
+ }
+ }
+
+ /**
+ * A wrapper around another Drawable that overrides the intrinsic size.
+ */
+ private static class IntrinsicSizeDrawable extends InsetDrawable {
+
+ private final int mIntrinsicWidth;
+ private final int mIntrinsicHeight;
+
+ public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
+ super(drawable, 0);
+ mIntrinsicWidth = intrinsicWidth;
+ mIntrinsicHeight = intrinsicHeight;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mIntrinsicWidth;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mIntrinsicHeight;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index b87c25b..8914fb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -182,11 +182,11 @@
private float mKeyguardStatusBarAnimateAlpha = 1f;
private int mOldLayoutDirection;
- private HeadsUpTouchHelper mHeadsUpTouchHelper = new HeadsUpTouchHelper();
- private boolean mPinnedHeadsUpExist;
- private boolean mExpansionIsFromHeadsUp;
- private int mBottomBarHeight;
+ private HeadsUpTouchHelper mHeadsUpTouchHelper;
+ private boolean mIsExpansionFromHeadsUp;
+ private int mNavigationBarBottomHeight;
private boolean mExpandingFromHeadsUp;
+ private boolean mCollapsedOnDown;
private int mPositionMinSideMargin;
private int mLastOrientation = -1;
@@ -534,17 +534,16 @@
}
@Override
- public boolean
- onInterceptTouchEvent(MotionEvent event) {
+ public boolean onInterceptTouchEvent(MotionEvent event) {
if (mBlockTouches) {
return false;
}
initDownStates(event);
if (mHeadsUpTouchHelper.onInterceptTouchEvent(event)) {
- mExpansionIsFromHeadsUp = true;
+ mIsExpansionFromHeadsUp = true;
return true;
}
- if (!isShadeCollapsed() && onQsIntercept(event)) {
+ if (!isFullyCollapsed() && onQsIntercept(event)) {
return true;
}
return super.onInterceptTouchEvent(event);
@@ -641,6 +640,7 @@
mOnlyAffordanceInThisMotion = false;
mQsTouchAboveFalsingThreshold = mQsFullyExpanded;
mDozingOnDown = isDozing();
+ mCollapsedOnDown = isFullyCollapsed();
}
}
@@ -695,7 +695,7 @@
return true;
}
mHeadsUpTouchHelper.onTouchEvent(event);
- if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQSTouch(event)) {
+ if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQsTouch(event)) {
return true;
}
if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()) {
@@ -705,7 +705,7 @@
return true;
}
- private boolean handleQSTouch(MotionEvent event) {
+ private boolean handleQsTouch(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f
&& mStatusBar.getBarState() != StatusBarState.KEYGUARD && !mQsExpanded
&& mQsExpansionEnabled) {
@@ -718,7 +718,7 @@
mInitialTouchY = event.getX();
mInitialTouchX = event.getY();
}
- if (!isShadeCollapsed()) {
+ if (!isFullyCollapsed()) {
handleQsDown(event);
}
if (!mQsExpandImmediate && mQsTracking) {
@@ -731,7 +731,7 @@
|| event.getActionMasked() == MotionEvent.ACTION_UP) {
mConflictingQsExpansionGesture = false;
}
- if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isShadeCollapsed()
+ if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()
&& mQsExpansionEnabled) {
mTwoFingerQsExpandPossible = true;
}
@@ -1191,8 +1191,8 @@
updateEmptyShadeView();
mQsNavbarScrim.setVisibility(mStatusBarState == StatusBarState.SHADE && mQsExpanded
&& !mStackScrollerOverscrolling && mQsScrimEnabled
- ? View.VISIBLE
- : View.INVISIBLE);
+ ? View.VISIBLE
+ : View.INVISIBLE);
if (mKeyguardUserSwitcher != null && mQsExpanded && !mStackScrollerOverscrolling) {
mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
}
@@ -1386,7 +1386,7 @@
* @return Whether we should intercept a gesture to open Quick Settings.
*/
private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) {
- if (!mQsExpansionEnabled) {
+ if (!mQsExpansionEnabled || mCollapsedOnDown) {
return false;
}
View header = mKeyguardShowing ? mKeyguardStatusBar : mHeader;
@@ -1461,8 +1461,8 @@
updateHeader();
updateUnlockIcon();
updateNotificationTranslucency();
- mHeadsUpManager.setIsExpanded(!isShadeCollapsed());
- mNotificationStackScroller.setShadeExpanded(!isShadeCollapsed());
+ mHeadsUpManager.setIsExpanded(!isFullyCollapsed());
+ mNotificationStackScroller.setShadeExpanded(!isFullyCollapsed());
if (DEBUG) {
invalidate();
}
@@ -1535,21 +1535,19 @@
float alpha;
if (mExpandingFromHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()) {
alpha = 1f;
- if (mNotificationStackScroller.getLayerType() == LAYER_TYPE_HARDWARE) {
- mNotificationStackScroller.setLayerType(LAYER_TYPE_NONE, null);
- }
} else {
alpha = (getNotificationsTopY() + mNotificationStackScroller.getItemHeight())
/ (mQsMinExpansionHeight + mNotificationStackScroller.getBottomStackPeekSize()
- mNotificationStackScroller.getCollapseSecondCardPadding());
alpha = Math.max(0, Math.min(alpha, 1));
alpha = (float) Math.pow(alpha, 0.75);
- if (alpha != 1f && mNotificationStackScroller.getLayerType() != LAYER_TYPE_HARDWARE) {
- mNotificationStackScroller.setLayerType(LAYER_TYPE_HARDWARE, null);
- } else if (alpha == 1f
- && mNotificationStackScroller.getLayerType() == LAYER_TYPE_HARDWARE) {
- mNotificationStackScroller.setLayerType(LAYER_TYPE_NONE, null);
- }
+ }
+
+ if (alpha != 1f && mNotificationStackScroller.getLayerType() != LAYER_TYPE_HARDWARE) {
+ mNotificationStackScroller.setLayerType(LAYER_TYPE_HARDWARE, null);
+ } else if (alpha == 1f
+ && mNotificationStackScroller.getLayerType() == LAYER_TYPE_HARDWARE) {
+ mNotificationStackScroller.setLayerType(LAYER_TYPE_NONE, null);
}
mNotificationStackScroller.setAlpha(alpha);
}
@@ -1615,7 +1613,7 @@
}
float stackTranslation = mNotificationStackScroller.getStackTranslation();
float translation = stackTranslation / HEADER_RUBBERBAND_FACTOR;
- if (mHeadsUpManager.hasPinnedHeadsUp() || mExpansionIsFromHeadsUp) {
+ if (mHeadsUpManager.hasPinnedHeadsUp() || mIsExpansionFromHeadsUp) {
translation = mNotificationStackScroller.getTopPadding() + stackTranslation
- mNotificationTopPadding - mQsMinExpansionHeight;
}
@@ -1683,16 +1681,16 @@
mHeadsUpManager.onExpandingFinished();
mIsExpanding = false;
mScrollYOverride = -1;
- if (isShadeCollapsed()) {
+ if (isFullyCollapsed()) {
setListening(false);
} else {
setListening(true);
}
mQsExpandImmediate = false;
mTwoFingerQsExpandPossible = false;
- mExpansionIsFromHeadsUp = false;
- mNotificationStackScroller.setTrackingHeadsUp(mHeadsUpTouchHelper.isTrackingHeadsUp());
- mExpandingFromHeadsUp = mHeadsUpTouchHelper.isTrackingHeadsUp();
+ mIsExpansionFromHeadsUp = false;
+ mNotificationStackScroller.setTrackingHeadsUp(false);
+ mExpandingFromHeadsUp = false;
}
private void setListening(boolean listening) {
@@ -1793,13 +1791,13 @@
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- mBottomBarHeight = insets.getSystemWindowInsetBottom();
+ mNavigationBarBottomHeight = insets.getSystemWindowInsetBottom();
updateMaxHeadsUpTranslation();
return insets;
}
private void updateMaxHeadsUpTranslation() {
- mNotificationStackScroller.setHeadsUpBoundaries(getHeight(), mBottomBarHeight);
+ mNotificationStackScroller.setHeadsUpBoundaries(getHeight(), mNavigationBarBottomHeight);
}
@Override
@@ -2160,48 +2158,43 @@
}
@Override
- public void OnPinnedHeadsUpExistChanged(final boolean exist, boolean changeImmediatly) {
- if (exist != mPinnedHeadsUpExist) {
- mPinnedHeadsUpExist = exist;
- if (exist) {
- mHeadsUpExistenceChangedRunnable.run();
- updateNotificationTranslucency();
- } else {
- mNotificationStackScroller.performOnAnimationFinished(
- mHeadsUpExistenceChangedRunnable);
- }
+ public void onPinnedModeChanged(final boolean inPinnedMode) {
+ if (inPinnedMode) {
+ mHeadsUpExistenceChangedRunnable.run();
+ updateNotificationTranslucency();
+ } else {
+ mNotificationStackScroller.runAfterAnimationFinished(
+ mHeadsUpExistenceChangedRunnable);
}
}
@Override
- public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) {
- if (isHeadsUp) {
- mNotificationStackScroller.generateHeadsUpAnimation(headsUp, true);
- }
+ public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
+ mNotificationStackScroller.generateHeadsUpAnimation(headsUp, true);
}
@Override
- public void OnHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
+ public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
+ }
+
+ @Override
+ public void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
mNotificationStackScroller.generateHeadsUpAnimation(entry.row, isHeadsUp);
}
@Override
- protected boolean isShadeCollapsed() {
- return mExpandedHeight == 0;
- }
-
- @Override
public void setHeadsUpManager(HeadsUpManager headsUpManager) {
super.setHeadsUpManager(headsUpManager);
- mHeadsUpTouchHelper.bind(headsUpManager, mNotificationStackScroller, this);
+ mHeadsUpTouchHelper = new HeadsUpTouchHelper(headsUpManager, mNotificationStackScroller,
+ this);
}
public void setTrackingHeadsUp(boolean tracking) {
if (tracking) {
- // otherwise we update the state when the expansion is finished
mNotificationStackScroller.setTrackingHeadsUp(true);
mExpandingFromHeadsUp = true;
}
+ // otherwise we update the state when the expansion is finished
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 4452dd7c..85f312c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -46,13 +46,13 @@
public abstract class PanelView extends FrameLayout {
public static final boolean DEBUG = PanelBar.DEBUG;
public static final String TAG = PanelView.class.getSimpleName();
- protected HeadsUpManager mHeadsUpManager;
-
private final void logf(String fmt, Object... args) {
Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
}
protected PhoneStatusBar mStatusBar;
+ protected HeadsUpManager mHeadsUpManager;
+
private float mPeekHeight;
private float mHintDistance;
private int mEdgeTapAreaWidth;
@@ -242,15 +242,15 @@
final float y = event.getY(pointerIndex);
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
- mGestureWaitForTouchSlop = isShadeCollapsed() || hasConflictingGestures();
- mIgnoreXTouchSlop = isShadeCollapsed() || shouldGestureIgnoreXTouchSlop(x, y);
+ mGestureWaitForTouchSlop = isFullyCollapsed() || hasConflictingGestures();
+ mIgnoreXTouchSlop = isFullyCollapsed() || shouldGestureIgnoreXTouchSlop(x, y);
}
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
startExpandMotion(x, y, false /* startTracking */, mExpandedHeight);
mJustPeeked = false;
- mPanelClosedOnDown = isShadeCollapsed();
+ mPanelClosedOnDown = isFullyCollapsed();
mHasLayoutedSinceDown = false;
mUpdateFlingOnLayout = false;
mMotionAborted = false;
@@ -268,7 +268,7 @@
|| mPeekPending || mPeekAnimator != null;
onTrackingStarted();
}
- if (isShadeCollapsed()) {
+ if (isFullyCollapsed()) {
schedulePeek();
}
break;
@@ -472,7 +472,7 @@
mTouchSlopExceeded = false;
mJustPeeked = false;
mMotionAborted = false;
- mPanelClosedOnDown = isShadeCollapsed();
+ mPanelClosedOnDown = isFullyCollapsed();
mHasLayoutedSinceDown = false;
mUpdateFlingOnLayout = false;
mTouchAboveFalsingThreshold = false;
@@ -707,7 +707,7 @@
// If the user isn't actively poking us, let's update the height
if ((!mTracking || isTrackingBlocked())
&& mHeightAnimator == null
- && !isShadeCollapsed()
+ && !isFullyCollapsed()
&& currentMaxPanelHeight != mExpandedHeight
&& !mPeekPending
&& mPeekAnimator == null
@@ -1057,8 +1057,6 @@
*/
protected abstract int getClearAllHeight();
- protected abstract boolean isShadeCollapsed();
-
public void setHeadsUpManager(HeadsUpManager headsUpManager) {
mHeadsUpManager = headsUpManager;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 6b17589..b1d48f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1152,11 +1152,11 @@
@Override
public void removeNotification(String key, RankingMap ranking) {
- boolean defferRemoval = false;
+ boolean deferRemoval = false;
if (mHeadsUpManager.isHeadsUp(key)) {
- defferRemoval = !mHeadsUpManager.removeNotification(key);
+ deferRemoval = !mHeadsUpManager.removeNotification(key);
}
- if (defferRemoval) {
+ if (deferRemoval) {
mLatestRankingMap = ranking;
mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
return;
@@ -1838,8 +1838,8 @@
}
@Override
- public void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly) {
- if (exist) {
+ public void onPinnedModeChanged(boolean inPinnedMode) {
+ if (inPinnedMode) {
mStatusBarWindowManager.setHeadsUpShowing(true);
} else {
Runnable endRunnable = new Runnable() {
@@ -1850,20 +1850,24 @@
}
}
};
- if (changeImmediatly) {
+ if (!mNotificationPanel.isFullyCollapsed()) {
endRunnable.run();
} else {
- mStackScroller.performOnAnimationFinished(endRunnable);
+ mStackScroller.runAfterAnimationFinished(endRunnable);
}
}
}
@Override
- public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) {
+ public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
}
@Override
- public void OnHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
+ public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
+ }
+
+ @Override
+ public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
if (!isHeadsUp && mHeadsUpEntriesToRemoveOnSwitch.contains(entry)) {
removeNotification(entry.key, mLatestRankingMap);
mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
@@ -1880,10 +1884,11 @@
boolean alertAgain) {
final boolean wasHeadsUp = isHeadsUp(key);
if (wasHeadsUp) {
- mHeadsUpManager.updateNotification(entry, alertAgain);
if (!shouldInterrupt) {
// We don't want this to be interrupting anymore, lets remove it
mHeadsUpManager.removeNotification(key);
+ } else {
+ mHeadsUpManager.updateNotification(entry, alertAgain);
}
} else if (shouldInterrupt && alertAgain) {
// This notification was updated to be a heads-up, show it!
@@ -1929,7 +1934,7 @@
}
@Override
- public void escalateHeadsUp() {
+ public void maybeEscalateHeadsUp() {
TreeSet<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getSortedEntries();
for (HeadsUpManager.HeadsUpEntry entry : entries) {
final StatusBarNotification sbn = entry.entry.notification;
@@ -2852,6 +2857,7 @@
} catch (RemoteException e) {
// Ignore.
}
+ setNotificationsShown(newlyVisibleAr);
}
// State logging
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index e701783..ae98e76 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -80,7 +80,7 @@
private float mCurrentInFrontAlpha;
private float mCurrentBehindAlpha;
private float mCurrentHeadsUpAlpha = 1;
- private int mAmountOfPinnedHeadsUps;
+ private int mPinnedHeadsUpCount;
private float mTopHeadsUpDragAmount;
private View mDraggedHeadsUpView;
@@ -347,25 +347,27 @@
}
@Override
- public void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly) {
+ public void onPinnedModeChanged(boolean inPinnedMode) {
}
@Override
- public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) {
- if (isHeadsUp) {
- mAmountOfPinnedHeadsUps++;
- } else {
- mAmountOfPinnedHeadsUps--;
- if (headsUp == mDraggedHeadsUpView) {
- mDraggedHeadsUpView = null;
- mTopHeadsUpDragAmount = 0.0f;
- }
+ public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
+ mPinnedHeadsUpCount++;
+ updateHeadsUpScrim(true);
+ }
+
+ @Override
+ public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
+ mPinnedHeadsUpCount--;
+ if (headsUp == mDraggedHeadsUpView) {
+ mDraggedHeadsUpView = null;
+ mTopHeadsUpDragAmount = 0.0f;
}
updateHeadsUpScrim(true);
}
@Override
- public void OnHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
+ public void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
}
private void updateHeadsUpScrim(boolean animate) {
@@ -374,12 +376,10 @@
TAG_KEY_ANIM);
float animEndValue = -1;
if (previousAnimator != null) {
- if ((animate || alpha == mCurrentHeadsUpAlpha)) {
- // lets cancel any running animators
+ if (animate || alpha == mCurrentHeadsUpAlpha) {
previousAnimator.cancel();
}
- animEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
- TAG_HUN_START_ALPHA);
+ animEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim, TAG_HUN_START_ALPHA);
}
if (alpha != mCurrentHeadsUpAlpha && alpha != animEndValue) {
if (animate) {
@@ -390,7 +390,7 @@
if (previousAnimator != null) {
float previousStartValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
TAG_HUN_START_ALPHA);
- float previousEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
+ float previousEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim,
TAG_HUN_END_ALPHA);
// we need to increase all animation keyframes of the previous animator by the
// relative change to the end value
@@ -410,6 +410,13 @@
}
}
+ /**
+ * Set the amount the current top heads up view is dragged. The range is from 0 to 1 and 0 means
+ * the heads up is in its resting space and 1 means it's fully dragged out.
+ *
+ * @param draggedHeadsUpView the dragged view
+ * @param topHeadsUpDragAmount how far is it dragged
+ */
public void setTopHeadsUpDragAmount(View draggedHeadsUpView, float topHeadsUpDragAmount) {
mTopHeadsUpDragAmount = topHeadsUpDragAmount;
mDraggedHeadsUpView = draggedHeadsUpView;
@@ -417,9 +424,9 @@
}
private float calculateHeadsUpAlpha() {
- if (mAmountOfPinnedHeadsUps >= 2) {
+ if (mPinnedHeadsUpCount >= 2) {
return 1.0f;
- } else if (mAmountOfPinnedHeadsUps == 0) {
+ } else if (mPinnedHeadsUpCount == 0) {
return 0.0f;
} else {
return 1.0f - mTopHeadsUpDragAmount;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
index 4a43c47..45c8938 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java
@@ -27,6 +27,7 @@
import android.util.Log;
import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
import java.util.HashMap;
import java.util.List;
@@ -228,7 +229,7 @@
// Get the list of applications that can handle the intent.
final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
- intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
+ intent, PackageManager.MATCH_DEFAULT_ONLY, KeyguardUpdateMonitor.getCurrentUser());
if (appList.size() == 0) {
if (DEBUG) Log.d(TAG, "No targets found for secure camera intent");
return false;
@@ -237,7 +238,7 @@
// Get the application that the intent resolves to.
ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
- mLockPatternUtils.getCurrentUser());
+ KeyguardUpdateMonitor.getCurrentUser());
if (resolved == null || resolved.activityInfo == null) {
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index 65cd268..66d71f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -80,8 +80,8 @@
}
private void update(boolean updateAlways) {
- int user = mLockPatternUtils.getCurrentUser();
- boolean secure = mLockPatternUtils.isSecure();
+ int user = KeyguardUpdateMonitor.getCurrentUser();
+ boolean secure = mLockPatternUtils.isSecure(user);
boolean currentlyInsecure = !secure || mKeyguardUpdateMonitor.getUserHasTrust(user);
boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
boolean faceUnlockRunning = mKeyguardUpdateMonitor.isFaceUnlockRunning(user)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index b4e4773..8f83daa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * 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.
@@ -35,11 +35,16 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Stack;
import java.util.TreeSet;
+/**
+ * A manager which handles heads up notifications which is a special mode where
+ * they simply peek from the top of the screen.
+ */
public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsListener {
private static final String TAG = "HeadsUpManager";
private static final boolean DEBUG = false;
@@ -48,7 +53,7 @@
private final int mHeadsUpNotificationDecay;
private final int mMinimumDisplayTime;
- private final int mTouchSensitivityDelay;
+ private final int mTouchAcceptanceDelay;
private final ArrayMap<String, Long> mSnoozedPackages;
private final HashSet<OnHeadsUpChangedListener> mListeners = new HashSet<>();
private final int mDefaultSnoozeLengthMs;
@@ -67,13 +72,12 @@
@Override
public boolean release(HeadsUpEntry instance) {
- instance.removeAutoCancelCallbacks();
+ instance.reset();
mPoolObjects.push(instance);
return true;
}
};
-
private PhoneStatusBar mBar;
private int mSnoozeLengthMs;
private ContentObserver mSettingsObserver;
@@ -86,13 +90,12 @@
private boolean mTrackingHeadsUp;
private HashSet<NotificationData.Entry> mEntriesToRemoveAfterExpand = new HashSet<>();
private boolean mIsExpanded;
- private boolean mHasPinnedHeadsUp;
+ private boolean mHasPinnedNotification;
private int[] mTmpTwoArray = new int[2];
public HeadsUpManager(final Context context, ViewTreeObserver observer) {
Resources resources = context.getResources();
- mTouchSensitivityDelay = resources.getInteger(R.integer.heads_up_sensitivity_delay);
- if (DEBUG) Log.v(TAG, "create() " + mTouchSensitivityDelay);
+ mTouchAcceptanceDelay = resources.getInteger(R.integer.touch_acceptance_delay);
mSnoozedPackages = new ArrayMap<>();
mDefaultSnoozeLengthMs = resources.getInteger(R.integer.heads_up_default_snooze_length_ms);
mSnoozeLengthMs = mDefaultSnoozeLengthMs;
@@ -116,7 +119,6 @@
context.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(SETTING_HEADS_UP_SNOOZE_LENGTH_MS), false,
mSettingsObserver);
- if (DEBUG) Log.v(TAG, "mSnoozeLengthMs = " + mSnoozeLengthMs);
observer.addOnComputeInternalInsetsListener(this);
}
@@ -154,7 +156,7 @@
if (alert) {
HeadsUpEntry headsUpEntry = mHeadsUpEntries.get(headsUp.key);
headsUpEntry.updateEntry();
- setEntryToShade(headsUpEntry, mIsExpanded, false /* justAdded */, false);
+ setEntryPinned(headsUpEntry, !mIsExpanded /* isPinned */);
}
}
@@ -165,22 +167,23 @@
headsUpEntry.setEntry(entry);
mHeadsUpEntries.put(entry.key, headsUpEntry);
entry.row.setHeadsUp(true);
- setEntryToShade(headsUpEntry, mIsExpanded /* inShade */, true /* justAdded */, false);
+ setEntryPinned(headsUpEntry, !mIsExpanded /* isPinned */);
for (OnHeadsUpChangedListener listener : mListeners) {
- listener.OnHeadsUpStateChanged(entry, true);
+ listener.onHeadsUpStateChanged(entry, true);
}
entry.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
}
- private void setEntryToShade(HeadsUpEntry headsUpEntry, boolean inShade, boolean justAdded,
- boolean forceImmediate) {
+ private void setEntryPinned(HeadsUpEntry headsUpEntry, boolean isPinned) {
ExpandableNotificationRow row = headsUpEntry.entry.row;
- if (row.isInShade() != inShade || justAdded) {
- row.setInShade(inShade);
- if (!justAdded || !inShade) {
- updatePinnedHeadsUpState(forceImmediate);
- for (OnHeadsUpChangedListener listener : mListeners) {
- listener.OnHeadsUpPinnedChanged(row, !inShade);
+ if (row.isPinned() != isPinned) {
+ row.setPinned(isPinned);
+ updatePinnedMode();
+ for (OnHeadsUpChangedListener listener : mListeners) {
+ if (isPinned) {
+ listener.onHeadsUpPinned(row);
+ } else {
+ listener.onHeadsUpUnPinned(row);
}
}
}
@@ -189,24 +192,23 @@
private void removeHeadsUpEntry(NotificationData.Entry entry) {
HeadsUpEntry remove = mHeadsUpEntries.remove(entry.key);
mSortedEntries.remove(remove);
- mEntryPool.release(remove);
entry.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
entry.row.setHeadsUp(false);
- setEntryToShade(remove, true /* inShade */, false /* justAdded */,
- false /* forceImmediate */);
+ setEntryPinned(remove, false /* isPinned */);
for (OnHeadsUpChangedListener listener : mListeners) {
- listener.OnHeadsUpStateChanged(entry, false);
+ listener.onHeadsUpStateChanged(entry, false);
}
+ mEntryPool.release(remove);
}
- private void updatePinnedHeadsUpState(boolean forceImmediate) {
- boolean hasPinnedHeadsUp = hasPinnedHeadsUpInternal();
- if (hasPinnedHeadsUp == mHasPinnedHeadsUp) {
+ private void updatePinnedMode() {
+ boolean hasPinnedNotification = hasPinnedNotificationInternal();
+ if (hasPinnedNotification == mHasPinnedNotification) {
return;
}
- mHasPinnedHeadsUp = hasPinnedHeadsUp;
- for (OnHeadsUpChangedListener listener :mListeners) {
- listener.OnPinnedHeadsUpExistChanged(hasPinnedHeadsUp, forceImmediate);
+ mHasPinnedNotification = hasPinnedNotification;
+ for (OnHeadsUpChangedListener listener : mListeners) {
+ listener.onPinnedModeChanged(hasPinnedNotification);
}
}
@@ -222,7 +224,7 @@
releaseImmediately(key);
return true;
} else {
- getHeadsUpEntry(key).hideAsSoonAsPossible();
+ getHeadsUpEntry(key).removeAsSoonAsPossible();
return false;
}
}
@@ -245,14 +247,13 @@
return mHeadsUpEntries.containsKey(key);
}
-
/**
* Push any current Heads Up notification down into the shade.
*/
public void releaseAllImmediately() {
if (DEBUG) Log.v(TAG, "releaseAllImmediately");
- HashSet<String> keys = new HashSet<>(mHeadsUpEntries.keySet());
- for (String key: keys) {
+ ArrayList<String> keys = new ArrayList<>(mHeadsUpEntries.keySet());
+ for (String key : keys) {
releaseImmediately(key);
}
}
@@ -280,7 +281,7 @@
}
public void snooze() {
- for (String key: mHeadsUpEntries.keySet()) {
+ for (String key : mHeadsUpEntries.keySet()) {
HeadsUpEntry entry = mHeadsUpEntries.get(key);
String packageName = entry.entry.notification.getPackageName();
mSnoozedPackages.put(snoozeKey(packageName, mUser),
@@ -310,8 +311,11 @@
}
/**
+ * Decides whether a click is invalid for a notification, i.e it has not been shown long enough
+ * that a user might have consciously clicked on it.
+ *
* @param key the key of the touched notification
- * @return whether the touch is valid and should not be discarded
+ * @return whether the touch is invalid and should be discarded
*/
public boolean shouldSwallowClick(String key) {
HeadsUpEntry entry = mHeadsUpEntries.get(key);
@@ -322,14 +326,14 @@
}
public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
- if (!mIsExpanded && mHasPinnedHeadsUp) {
+ if (!mIsExpanded && mHasPinnedNotification) {
int minX = Integer.MAX_VALUE;
int maxX = 0;
int minY = Integer.MAX_VALUE;
int maxY = 0;
- for (HeadsUpEntry entry: mSortedEntries) {
+ for (HeadsUpEntry entry : mSortedEntries) {
ExpandableNotificationRow row = entry.entry.row;
- if (!row.isInShade()) {
+ if (row.isPinned()) {
row.getLocationOnScreen(mTmpTwoArray);
minX = Math.min(minX, mTmpTwoArray[0]);
minY = Math.min(minY, 0);
@@ -349,7 +353,7 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("HeadsUpManager state:");
- pw.print(" mTouchSensitivityDelay="); pw.println(mTouchSensitivityDelay);
+ pw.print(" mTouchAcceptanceDelay="); pw.println(mTouchAcceptanceDelay);
pw.print(" mSnoozeLengthMs="); pw.println(mSnoozeLengthMs);
pw.print(" now="); pw.println(SystemClock.elapsedRealtime());
pw.print(" mUser="); pw.println(mUser);
@@ -365,38 +369,32 @@
}
public boolean hasPinnedHeadsUp() {
- return mHasPinnedHeadsUp;
+ return mHasPinnedNotification;
}
- private boolean hasPinnedHeadsUpInternal() {
- for (String key: mHeadsUpEntries.keySet()) {
+ private boolean hasPinnedNotificationInternal() {
+ for (String key : mHeadsUpEntries.keySet()) {
HeadsUpEntry entry = mHeadsUpEntries.get(key);
- if (!entry.entry.row.isInShade()) {
+ if (entry.entry.row.isPinned()) {
return true;
}
}
return false;
}
- public void addSwipedOutKey(String key) {
+ /**
+ * Notifies that a notification was swiped out and will be removed.
+ *
+ * @param key the notification key
+ */
+ public void addSwipedOutNotification(String key) {
mSwipedOutKeys.add(key);
}
- public float getHighestPinnedHeadsUp() {
- float max = 0;
- for (HeadsUpEntry entry: mSortedEntries) {
- if (!entry.entry.row.isInShade()) {
- max = Math.max(max, entry.entry.row.getActualHeight());
- }
- }
- return max;
- }
-
- public void releaseAllToShade() {
- for (String key: mHeadsUpEntries.keySet()) {
+ public void unpinAll() {
+ for (String key : mHeadsUpEntries.keySet()) {
HeadsUpEntry entry = mHeadsUpEntries.get(key);
- setEntryToShade(entry, true /* toShade */, false /* justAdded */,
- true /* forceImmediate */);
+ setEntryPinned(entry, false /* isPinned */);
}
}
@@ -420,7 +418,7 @@
if (isExpanded != mIsExpanded) {
mIsExpanded = isExpanded;
if (isExpanded) {
- releaseAllToShade();
+ unpinAll();
}
}
}
@@ -430,6 +428,12 @@
return topEntry != null ? topEntry.entry.row.getHeadsUpHeight() : 0;
}
+ /**
+ * Compare two entries and decide how they should be ranked.
+ *
+ * @return -1 if the first argument should be ranked higher than the second, 1 if the second
+ * one should be ranked higher and 0 if they are equal.
+ */
public int compare(NotificationData.Entry a, NotificationData.Entry b) {
HeadsUpEntry aEntry = getHeadsUpEntry(a.key);
HeadsUpEntry bEntry = getHeadsUpEntry(b.key);
@@ -439,6 +443,11 @@
return aEntry.compareTo(bEntry);
}
+
+ /**
+ * This represents a notification and how long it is in a heads up mode. It also manages its
+ * lifecycle automatically when created.
+ */
public class HeadsUpEntry implements Comparable<HeadsUpEntry> {
public NotificationData.Entry entry;
public long postTime;
@@ -449,7 +458,7 @@
this.entry = entry;
// The actual post time will be just after the heads-up really slided in
- postTime = mClock.currentTimeMillis() + mTouchSensitivityDelay;
+ postTime = mClock.currentTimeMillis() + mTouchAcceptanceDelay;
mRemoveHeadsUpRunnable = new Runnable() {
@Override
public void run() {
@@ -467,7 +476,7 @@
long currentTime = mClock.currentTimeMillis();
earliestRemovaltime = currentTime + mMinimumDisplayTime;
postTime = Math.max(postTime, currentTime);
- removeAutoCancelCallbacks();
+ removeAutoRemovalCallbacks();
if (canEntryDecay()) {
long finishTime = postTime + mHeadsUpNotificationDecay;
long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
@@ -487,7 +496,7 @@
: -1;
}
- public void removeAutoCancelCallbacks() {
+ public void removeAutoRemovalCallbacks() {
mHandler.removeCallbacks(mRemoveHeadsUpRunnable);
}
@@ -495,11 +504,17 @@
return earliestRemovaltime < mClock.currentTimeMillis();
}
- public void hideAsSoonAsPossible() {
- removeAutoCancelCallbacks();
+ public void removeAsSoonAsPossible() {
+ removeAutoRemovalCallbacks();
mHandler.postDelayed(mRemoveHeadsUpRunnable,
earliestRemovaltime - mClock.currentTimeMillis());
}
+
+ public void reset() {
+ removeAutoRemovalCallbacks();
+ entry = null;
+ mRemoveHeadsUpRunnable = null;
+ }
}
/**
@@ -519,8 +534,29 @@
}
public interface OnHeadsUpChangedListener {
- void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly);
- void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp);
- void OnHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp);
+ /**
+ * The state whether there exist pinned heads-ups or not changed.
+ *
+ * @param inPinnedMode whether there are any pinned heads-ups
+ */
+ void onPinnedModeChanged(boolean inPinnedMode);
+
+ /**
+ * A notification was just pinned to the top.
+ */
+ void onHeadsUpPinned(ExpandableNotificationRow headsUp);
+
+ /**
+ * A notification was just unpinned from the top.
+ */
+ void onHeadsUpUnPinned(ExpandableNotificationRow headsUp);
+
+ /**
+ * A notification just became a heads up or turned back to its normal state.
+ *
+ * @param entry the entry of the changed notification
+ * @param isHeadsUp whether the notification is now a headsUp notification
+ */
+ void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
index 0dce82f..5d89e2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
@@ -26,6 +26,7 @@
import android.view.View;
import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.statusbar.phone.KeyguardPreviewContainer;
import java.util.List;
@@ -80,13 +81,13 @@
WidgetInfo info = new WidgetInfo();
PackageManager packageManager = mContext.getPackageManager();
final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
- intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
+ intent, PackageManager.MATCH_DEFAULT_ONLY, KeyguardUpdateMonitor.getCurrentUser());
if (appList.size() == 0) {
return null;
}
ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
- mLockPatternUtils.getCurrentUser());
+ KeyguardUpdateMonitor.getCurrentUser());
if (wouldLaunchResolverActivity(resolved, appList)) {
return null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/HeadsUpAppearInterpolator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/HeadsUpAppearInterpolator.java
new file mode 100644
index 0000000..05c0099
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/HeadsUpAppearInterpolator.java
@@ -0,0 +1,51 @@
+/*
+ * 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.systemui.statusbar.stack;
+
+import android.graphics.Path;
+import android.view.animation.PathInterpolator;
+
+/**
+ * An interpolator specifically designed for the appear animation of heads up notifications.
+ */
+public class HeadsUpAppearInterpolator extends PathInterpolator {
+ public HeadsUpAppearInterpolator() {
+ super(getAppearPath());
+ }
+
+ private static Path getAppearPath() {
+ Path path = new Path();
+ path.moveTo(0, 0);
+ float x1 = 250f;
+ float x2 = 150f;
+ float x3 = 100f;
+ float y1 = 90f;
+ float y2 = 78f;
+ float y3 = 80f;
+ float xTot = (x1 + x2 + x3);
+ path.cubicTo(x1 * 0.9f / xTot, 0f,
+ x1 * 0.8f / xTot, y1 / y3,
+ x1 / xTot , y1 / y3);
+ path.cubicTo((x1 + x2 * 0.4f) / xTot, y1 / y3,
+ (x1 + x2 * 0.2f) / xTot, y2 / y3,
+ (x1 + x2) / xTot, y2 / y3);
+ path.cubicTo((x1 + x2 + x3 * 0.4f) / xTot, y2 / y3,
+ (x1 + x2 + x3 * 0.2f) / xTot, 1f,
+ 1f, 1f);
+ return path;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 88fc602..a1b0cae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -204,7 +204,6 @@
private ViewGroup mScrollView;
private boolean mInterceptDelegateEnabled;
private boolean mDelegateToScrollView;
-
private boolean mDisallowScrollingInThisMotion;
private long mGoToFullShadeDelay;
private ViewTreeObserver.OnPreDrawListener mChildrenUpdater
@@ -487,9 +486,9 @@
int stackHeight;
float paddingOffset;
boolean trackingHeadsUp = mTrackingHeadsUp;
- int normalExpandPositionStart = trackingHeadsUp ? mHeadsUpManager.getTopHeadsUpHeight()
+ int normalUnfoldPositionStart = trackingHeadsUp ? mHeadsUpManager.getTopHeadsUpHeight()
: minStackHeight;
- if (newStackHeight - mTopPadding - mTopPaddingOverflow >= normalExpandPositionStart
+ if (newStackHeight - mTopPadding - mTopPaddingOverflow >= normalUnfoldPositionStart
|| getNotGoneChildCount() == 0) {
paddingOffset = mTopPaddingOverflow;
stackHeight = newStackHeight;
@@ -582,7 +581,7 @@
if (v instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) v;
if (row.isHeadsUp()) {
- mHeadsUpManager.addSwipedOutKey(row.getStatusBarNotification().getKey());
+ mHeadsUpManager.addSwipedOutNotification(row.getStatusBarNotification().getKey());
}
}
final View veto = v.findViewById(R.id.veto);
@@ -626,10 +625,10 @@
requestChildrenUpdate();
}
- public boolean isPinnedHeadsUp(View v) {
+ public static boolean isPinnedHeadsUp(View v) {
if (v instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) v;
- return row.isHeadsUp() && !row.isInShade();
+ return row.isHeadsUp() && row.isPinned();
}
return false;
}
@@ -711,7 +710,7 @@
if (touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) {
if (slidingChild instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) slidingChild;
- if (row.isHeadsUp() && !row.isInShade()
+ if (row.isHeadsUp() && row.isPinned()
&& mHeadsUpManager.getTopEntry().entry.row != row) {
continue;
}
@@ -812,7 +811,8 @@
}
handleEmptySpaceClick(ev);
boolean expandWantsIt = false;
- if (!mSwipingInProgress && !mOnlyScrollingInThisMotion && isScrollingEnabled()) {
+ if (mIsExpanded && !mSwipingInProgress && !mOnlyScrollingInThisMotion
+ && isScrollingEnabled()) {
if (isCancelOrUp) {
mExpandHelper.onlyObserveMovements(false);
}
@@ -824,7 +824,8 @@
}
}
boolean scrollerWantsIt = false;
- if (!mSwipingInProgress && !mExpandingNotification && !mDisallowScrollingInThisMotion) {
+ if (mIsExpanded && !mSwipingInProgress && !mExpandingNotification
+ && !mDisallowScrollingInThisMotion) {
scrollerWantsIt = onScrollTouch(ev);
}
boolean horizontalSwipeWantsIt = false;
@@ -1872,15 +1873,15 @@
boolean onBottom = false;
if (!mIsExpanded && !isHeadsUp) {
type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
- } else if (mAddedHeadsUpChildren.contains(row) || (!row.isInShade() && !mIsExpanded)) {
- if (!row.isInShade() || shouldHunAppearFromBottom(row)) {
+ } else if (mAddedHeadsUpChildren.contains(row) || (row.isPinned() && !mIsExpanded)) {
+ if (row.isPinned() || shouldHunAppearFromBottom(row)) {
// Our custom add animation
type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR;
} else {
// Normal add animation
type = AnimationEvent.ANIMATION_TYPE_ADD;
}
- onBottom = row.isInShade();
+ onBottom = !row.isPinned();
}
AnimationEvent event = new AnimationEvent(row, type);
event.headsUpFromBottom = onBottom;
@@ -2670,7 +2671,7 @@
}
}
- public void performOnAnimationFinished(Runnable runnable) {
+ public void runAfterAnimationFinished(Runnable runnable) {
mAnimationFinishedRunnables.add(runnable);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 2a49a4c..202063a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -311,7 +311,8 @@
StackViewState viewState = resultState.getViewStateForView(
nextChild);
// The child below the dragged one must be fully visible
- if (!isPinnedHeadsUpView(draggedView) || isPinnedHeadsUpView(nextChild)) {
+ if (!NotificationStackScrollLayout.isPinnedHeadsUp(draggedView)
+ || NotificationStackScrollLayout.isPinnedHeadsUp(nextChild)) {
viewState.alpha = 1;
}
}
@@ -324,14 +325,6 @@
}
}
- private boolean isPinnedHeadsUpView(View view) {
- if (view instanceof ExpandableNotificationRow) {
- ExpandableNotificationRow row = (ExpandableNotificationRow) view;
- return row.isHeadsUp() && !row.isInShade();
- }
- return false;
- }
-
/**
* Update the visible children on the state.
*/
@@ -380,7 +373,7 @@
/**
* Determine the positions for the views. This is the main part of the algorithm.
*
- * @param resultState The result state to update if a change to the properties of a child occurs
+ * @param resultState The result state to update if a change to the properties of a child occurs
* @param algorithmState The state in which the current pass of the algorithm is currently in
* @param ambientState The current ambient state
*/
@@ -515,11 +508,12 @@
}
StackViewState childState = resultState.getViewStateForView(row);
boolean isTopEntry = topHeadsUpEntry == row;
- if (!row.isInShade()) {
+ if (row.isPinned()) {
childState.yTranslation = 0;
childState.height = row.getHeadsUpHeight();
if (!isTopEntry) {
- // Ensure that a headsUp is never below the topmost headsUp
+ // Ensure that a headsUp doesn't vertically extend further than the heads-up at
+ // the top most z-position
StackViewState topState = resultState.getViewStateForView(topHeadsUpEntry);
childState.height = row.getHeadsUpHeight();
childState.yTranslation = topState.yTranslation + topState.height
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index f5d94c8..b9466d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -21,11 +21,9 @@
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
-import android.graphics.Path;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -78,6 +76,7 @@
private final Interpolator mFastOutSlowInInterpolator;
private final Interpolator mHeadsUpAppearInterpolator;
private final int mGoToFullShadeAppearingTranslation;
+ private final StackViewState mTmpState = new StackViewState();
public NotificationStackScrollLayout mHostLayout;
private ArrayList<NotificationStackScrollLayout.AnimationEvent> mNewEvents =
new ArrayList<>();
@@ -95,7 +94,6 @@
private ValueAnimator mTopOverScrollAnimator;
private ValueAnimator mBottomOverScrollAnimator;
private ExpandableNotificationRow mChildExpandingView;
- private StackViewState mTmpState = new StackViewState();
private int mHeadsUpAppearHeightBottom;
private boolean mShadeExpanded;
@@ -106,25 +104,7 @@
mGoToFullShadeAppearingTranslation =
hostLayout.getContext().getResources().getDimensionPixelSize(
R.dimen.go_to_full_shade_appearing_translation);
- Path path = new Path();
- path.moveTo(0, 0);
- float x1 = 250f;
- float x2 = 150f;
- float x3 = 100f;
- float y1 = 90f;
- float y2 = 78f;
- float y3 = 80f;
- float xTot = (x1 + x2 + x3);
- path.cubicTo(x1 * 0.9f / xTot, 0f,
- x1 * 0.8f / xTot, y1 / y3,
- x1 / xTot , y1 / y3);
- path.cubicTo((x1 + x2 * 0.4f) / xTot, y1 / y3,
- (x1 + x2 * 0.2f) / xTot, y2 / y3,
- (x1 + x2) / xTot, y2 / y3);
- path.cubicTo((x1 + x2 + x3 * 0.4f) / xTot, y2 / y3,
- (x1 + x2 + x3 * 0.2f) / xTot, 1f,
- 1f, 1f);
- mHeadsUpAppearInterpolator = new PathInterpolator(path);
+ mHeadsUpAppearInterpolator = new HeadsUpAppearInterpolator();
}
public boolean isRunning() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index dda40d3..a5684a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -121,7 +121,7 @@
}
@Override
- public void escalateHeadsUp() {
+ public void maybeEscalateHeadsUp() {
}
@Override
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index abd2ca0..ef9d0c3 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -180,6 +180,11 @@
34001 device_idle_step
34002 device_idle_wake_from_idle (is_idle|1|5), (reason|3)
+# ---------------------------
+# DisplayManagerService.java
+# ---------------------------
+# Auto-brightness adjustments by the user.
+35000 auto_brightness_adj (old_adj|5),(old_lux|5),(old_brightness|5),(old_gamma|5),(new_adj|5),(new_lux|5),(new_brightness|5),(new_gamma|5)
# ---------------------------
# ConnectivityService.java
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 7172ab7..643ff5f 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -580,7 +580,9 @@
case H_FSTRIM: {
if (!isReady()) {
Slog.i(TAG, "fstrim requested, but no daemon connection yet; trying again");
- sendMessageDelayed(obtainMessage(H_FSTRIM), DateUtils.SECOND_IN_MILLIS);
+ sendMessageDelayed(obtainMessage(H_FSTRIM, msg.obj),
+ DateUtils.SECOND_IN_MILLIS);
+ break;
}
Slog.i(TAG, "Running fstrim idle maintenance");
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 4ee6657..8c6e290 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -759,47 +759,50 @@
}
public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) {
- log("notifySignalStrengthForSubscriber: subId=" + subId
- + " signalStrength=" + signalStrength);
if (!checkNotifyPermission("notifySignalStrength()")) {
- log("notifySignalStrengthForSubscriber: permission check failure");
return;
}
- toStringLogSSC("notifySignalStrengthForSubscriber");
+ if (VDBG) {
+ log("notifySignalStrengthForSubscriber: subId=" + subId
+ + " signalStrength=" + signalStrength);
+ toStringLogSSC("notifySignalStrengthForSubscriber");
+ }
synchronized (mRecords) {
int phoneId = SubscriptionManager.getPhoneId(subId);
if (validatePhoneId(phoneId)) {
- log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId);
+ if (VDBG) log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId);
mSignalStrength[phoneId] = signalStrength;
for (Record r : mRecords) {
- log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId
- + " phoneId=" + phoneId + " ss=" + signalStrength);
+ if (VDBG) {
+ log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId
+ + " phoneId=" + phoneId + " ss=" + signalStrength);
+ }
if (r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) &&
idMatch(r.subId, subId, phoneId)) {
try {
- log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r
- + " subId=" + subId + " phoneId=" + phoneId
- + " ss=" + signalStrength);
+ if (DBG) {
+ log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r
+ + " subId=" + subId + " phoneId=" + phoneId
+ + " ss=" + signalStrength);
+ }
r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
} catch (RemoteException ex) {
- log("notifySignalStrengthForSubscriber: Exception while calling callback!!");
mRemoveList.add(r.binder);
}
- } else {
- log("notifySignalStrengthForSubscriber: no match for LISTEN_SIGNAL_STRENGTHS");
}
if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) &&
idMatch(r.subId, subId, phoneId)){
try {
int gsmSignalStrength = signalStrength.getGsmSignalStrength();
int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
- log("notifySignalStrengthForSubscriber: callback.onSS r=" + r
- + " subId=" + subId + " phoneId=" + phoneId
- + " gsmSS=" + gsmSignalStrength + " ss=" + ss);
+ if (DBG) {
+ log("notifySignalStrengthForSubscriber: callback.onSS r=" + r
+ + " subId=" + subId + " phoneId=" + phoneId
+ + " gsmSS=" + gsmSignalStrength + " ss=" + ss);
+ }
r.callback.onSignalStrengthChanged(ss);
} catch (RemoteException ex) {
- log("notifySignalStrengthForSubscriber: Exception in deprecated LISTEN_SIGNAL_STRENGTH");
mRemoveList.add(r.binder);
}
}
@@ -807,7 +810,6 @@
} else {
log("notifySignalStrengthForSubscriber: invalid phoneId=" + phoneId);
}
- log("notifySignalStrengthForSubscriber: done with all records");
handleRemoveListLocked();
}
broadcastSignalStrengthChanged(signalStrength, subId);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 999e91b..ac2f5b0 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -54,6 +54,7 @@
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteStatement;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -83,9 +84,12 @@
import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -109,7 +113,9 @@
private static final int TIMEOUT_DELAY_MS = 1000 * 60;
private static final String DATABASE_NAME = "accounts.db";
- private static final int DATABASE_VERSION = 7;
+ private static final int DATABASE_VERSION = 8;
+
+ private static final int MAX_DEBUG_DB_SIZE = 64;
private final Context mContext;
@@ -214,6 +220,9 @@
private final HashMap<Account, AtomicReference<String>> previousNameCache =
new HashMap<Account, AtomicReference<String>>();
+ private int debugDbInsertionPoint = -1;
+ private SQLiteStatement statementForLogging;
+
UserAccounts(Context context, int userId) {
this.userId = userId;
synchronized (cacheLock) {
@@ -320,6 +329,8 @@
UserAccounts accounts = mUsers.get(userId);
if (accounts == null) {
accounts = new UserAccounts(mContext, userId);
+ initializeDebugDbSizeAndCompileSqlStatementForLogging(
+ accounts.openHelper.getWritableDatabase(), accounts);
mUsers.append(userId, accounts);
purgeOldGrants(accounts);
validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
@@ -407,6 +418,10 @@
+ accountType + " no longer has a registered authenticator");
db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null);
accountDeleted = true;
+
+ logRecord(db, DebugDbHelper.ACTION_AUTHENTICATOR_REMOVE, TABLE_ACCOUNTS,
+ accountId, accounts);
+
final Account account = new Account(accountName, accountType);
accounts.userDataCache.remove(account);
accounts.authTokenCache.remove(account);
@@ -666,9 +681,10 @@
UserAccounts accounts = getUserAccountsForCaller();
// fails if the account already exists
+ int uid = getCallingUid();
long identityToken = clearCallingIdentity();
try {
- return addAccountInternal(accounts, account, password, extras, false);
+ return addAccountInternal(accounts, account, password, extras, false, uid);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -811,7 +827,7 @@
}
private boolean addAccountInternal(UserAccounts accounts, Account account, String password,
- Bundle extras, boolean restricted) {
+ Bundle extras, boolean restricted, int callingUid) {
if (account == null) {
return false;
}
@@ -850,6 +866,10 @@
}
}
db.setTransactionSuccessful();
+
+ logRecord(db, DebugDbHelper.ACTION_ACCOUNT_ADD, TABLE_ACCOUNTS, accountId,
+ accounts, callingUid);
+
insertAccountIntoCacheLocked(accounts, account);
} finally {
db.endTransaction();
@@ -983,9 +1003,12 @@
if (accountToRename == null) throw new IllegalArgumentException("account is null");
checkAuthenticateAccountsPermission(accountToRename);
UserAccounts accounts = getUserAccountsForCaller();
+
+ int callingUid = getCallingUid();
long identityToken = clearCallingIdentity();
try {
- Account resultingAccount = renameAccountInternal(accounts, accountToRename, newName);
+ Account resultingAccount = renameAccountInternal(accounts, accountToRename, newName,
+ callingUid);
Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, resultingAccount.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, resultingAccount.type);
@@ -1000,7 +1023,7 @@
}
private Account renameAccountInternal(
- UserAccounts accounts, Account accountToRename, String newName) {
+ UserAccounts accounts, Account accountToRename, String newName, int callingUid) {
Account resultAccount = null;
/*
* Cancel existing notifications. Let authenticators
@@ -1038,6 +1061,8 @@
db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId);
db.setTransactionSuccessful();
isSuccessful = true;
+ logRecord(db, DebugDbHelper.ACTION_ACCOUNT_RENAME, TABLE_ACCOUNTS, accountId,
+ accounts);
}
} finally {
db.endTransaction();
@@ -1131,6 +1156,8 @@
}
}
+ logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE, TABLE_ACCOUNTS);
+
try {
new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind();
} finally {
@@ -1188,6 +1215,8 @@
}
}
+ logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE, TABLE_ACCOUNTS);
+
try {
new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind();
} finally {
@@ -1210,6 +1239,9 @@
if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) {
return false;
}
+
+ logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE, TABLE_ACCOUNTS);
+
long identityToken = clearCallingIdentity();
try {
return removeAccountInternal(accounts, account);
@@ -1275,21 +1307,25 @@
int deleted;
synchronized (accounts.cacheLock) {
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
+ final long accountId = getAccountIdLocked(db, account);
deleted = db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
+ "=?",
new String[]{account.name, account.type});
removeAccountFromCacheLocked(accounts, account);
sendAccountsChangedBroadcast(accounts.userId);
+
+ logRecord(db, DebugDbHelper.ACTION_ACCOUNT_REMOVE, TABLE_ACCOUNTS, accountId, accounts);
}
if (accounts.userId == UserHandle.USER_OWNER) {
// Owner's account was removed, remove from any users that are sharing
// this account.
+ int callingUid = getCallingUid();
long id = Binder.clearCallingIdentity();
try {
List<UserInfo> users = mUserManager.getUsers(true);
for (UserInfo user : users) {
if (!user.isPrimary() && user.isRestricted()) {
- removeSharedAccountAsUser(account, user.id);
+ removeSharedAccountAsUser(account, user.id, callingUid);
}
}
} finally {
@@ -1441,15 +1477,17 @@
if (account == null) throw new IllegalArgumentException("account is null");
checkAuthenticateAccountsPermission(account);
UserAccounts accounts = getUserAccountsForCaller();
+ int callingUid = getCallingUid();
long identityToken = clearCallingIdentity();
try {
- setPasswordInternal(accounts, account, password);
+ setPasswordInternal(accounts, account, password, callingUid);
} finally {
restoreCallingIdentity(identityToken);
}
}
- private void setPasswordInternal(UserAccounts accounts, Account account, String password) {
+ private void setPasswordInternal(UserAccounts accounts, Account account, String password,
+ int callingUid) {
if (account == null) {
return;
}
@@ -1473,6 +1511,11 @@
db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId);
accounts.authTokenCache.remove(account);
db.setTransactionSuccessful();
+
+ String action = (password == null || password.length() == 0) ?
+ DebugDbHelper.ACTION_CLEAR_PASSWORD
+ : DebugDbHelper.ACTION_SET_PASSWORD;
+ logRecord(db, action, TABLE_ACCOUNTS, accountId, accounts, callingUid);
}
} finally {
db.endTransaction();
@@ -1497,9 +1540,11 @@
if (account == null) throw new IllegalArgumentException("account is null");
checkManageAccountsPermission();
UserAccounts accounts = getUserAccountsForCaller();
+
+ int callingUid = getCallingUid();
long identityToken = clearCallingIdentity();
try {
- setPasswordInternal(accounts, account, null);
+ setPasswordInternal(accounts, account, null, callingUid);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -1888,6 +1933,8 @@
options.putInt(AccountManager.KEY_CALLER_UID, uid);
options.putInt(AccountManager.KEY_CALLER_PID, pid);
+ logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_ADD, TABLE_ACCOUNTS);
+
long identityToken = clearCallingIdentity();
try {
new Session(accounts, response, accountType, expectActivityLaunch,
@@ -1964,6 +2011,8 @@
options.putInt(AccountManager.KEY_CALLER_UID, uid);
options.putInt(AccountManager.KEY_CALLER_PID, pid);
+ logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_ADD, TABLE_ACCOUNTS);
+
long identityToken = clearCallingIdentity();
try {
new Session(accounts, response, accountType, expectActivityLaunch,
@@ -2320,7 +2369,8 @@
@Override
public boolean addSharedAccountAsUser(Account account, int userId) {
userId = handleIncomingUser(userId);
- SQLiteDatabase db = getUserAccounts(userId).openHelper.getWritableDatabase();
+ UserAccounts accounts = getUserAccounts(userId);
+ SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(ACCOUNTS_NAME, account.name);
values.put(ACCOUNTS_TYPE, account.type);
@@ -2332,6 +2382,7 @@
+ ", skipping the DB insert failed");
return false;
}
+ logRecord(db, DebugDbHelper.ACTION_ACCOUNT_ADD, TABLE_SHARED_ACCOUNTS, accountId, accounts);
return true;
}
@@ -2340,6 +2391,7 @@
userId = handleIncomingUser(userId);
UserAccounts accounts = getUserAccounts(userId);
SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
+ long sharedTableAccountId = getAccountIdFromSharedTable(db, account);
final ContentValues values = new ContentValues();
values.put(ACCOUNTS_NAME, newName);
values.put(ACCOUNTS_PREVIOUS_NAME, account.name);
@@ -2349,20 +2401,30 @@
ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
new String[] { account.name, account.type });
if (r > 0) {
+ int callingUid = getCallingUid();
+ logRecord(db, DebugDbHelper.ACTION_ACCOUNT_RENAME, TABLE_SHARED_ACCOUNTS,
+ sharedTableAccountId, accounts, callingUid);
// Recursively rename the account.
- renameAccountInternal(accounts, account, newName);
+ renameAccountInternal(accounts, account, newName, callingUid);
}
return r > 0;
}
@Override
public boolean removeSharedAccountAsUser(Account account, int userId) {
+ return removeSharedAccountAsUser(account, userId, getCallingUid());
+ }
+
+ private boolean removeSharedAccountAsUser(Account account, int userId, int callingUid) {
userId = handleIncomingUser(userId);
UserAccounts accounts = getUserAccounts(userId);
SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
+ long sharedTableAccountId = getAccountIdFromSharedTable(db, account);
int r = db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
new String[] {account.name, account.type});
if (r > 0) {
+ logRecord(db, DebugDbHelper.ACTION_ACCOUNT_REMOVE, TABLE_SHARED_ACCOUNTS,
+ sharedTableAccountId, accounts, callingUid);
removeAccountInternal(accounts, account);
}
return r > 0;
@@ -2459,6 +2521,19 @@
}
}
+ private long getAccountIdFromSharedTable(SQLiteDatabase db, Account account) {
+ Cursor cursor = db.query(TABLE_SHARED_ACCOUNTS, new String[]{ACCOUNTS_ID},
+ "name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
+ try {
+ if (cursor.moveToNext()) {
+ return cursor.getLong(0);
+ }
+ return -1;
+ } finally {
+ cursor.close();
+ }
+ }
+
private long getAccountIdLocked(SQLiteDatabase db, Account account) {
Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID},
"name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
@@ -2904,6 +2979,130 @@
return databaseFile.getPath();
}
+ private static class DebugDbHelper{
+ private DebugDbHelper() {
+ }
+
+ private static String TABLE_DEBUG = "debug_table";
+
+ // Columns for the table
+ private static String ACTION_TYPE = "action_type";
+ private static String TIMESTAMP = "time";
+ private static String CALLER_UID = "caller_uid";
+ private static String TABLE_NAME = "table_name";
+ private static String KEY = "primary_key";
+
+ // These actions correspond to the occurrence of real actions. Since
+ // these are called by the authenticators, the uid associated will be
+ // of the authenticator.
+ private static String ACTION_SET_PASSWORD = "action_set_password";
+ private static String ACTION_CLEAR_PASSWORD = "action_clear_password";
+ private static String ACTION_ACCOUNT_ADD = "action_account_add";
+ private static String ACTION_ACCOUNT_REMOVE = "action_account_remove";
+ private static String ACTION_AUTHENTICATOR_REMOVE = "action_authenticator_remove";
+ private static String ACTION_ACCOUNT_RENAME = "action_account_rename";
+
+ // These actions don't necessarily correspond to any action on
+ // accountDb taking place. As an example, there might be a request for
+ // addingAccount, which might not lead to addition of account on grounds
+ // of bad authentication. We will still be logging it to keep track of
+ // who called.
+ private static String ACTION_CALLED_ACCOUNT_ADD = "action_called_account_add";
+ private static String ACTION_CALLED_ACCOUNT_REMOVE = "action_called_account_remove";
+ private static String ACTION_CALLED_ACCOUNT_RENAME = "action_called_account_rename";
+
+ private static SimpleDateFormat dateFromat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ private static String UPDATE_WHERE_CLAUSE = KEY + "=?";
+
+ private static void createDebugTable(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE " + TABLE_DEBUG + " ( "
+ + ACCOUNTS_ID + " INTEGER,"
+ + ACTION_TYPE + " TEXT NOT NULL, "
+ + TIMESTAMP + " DATETIME,"
+ + CALLER_UID + " INTEGER NOT NULL,"
+ + TABLE_NAME + " TEXT NOT NULL,"
+ + KEY + " INTEGER PRIMARY KEY)");
+ db.execSQL("CREATE INDEX timestamp_index ON " + TABLE_DEBUG + " (" + TIMESTAMP + ")");
+ }
+ }
+
+ private void logRecord(UserAccounts accounts, String action, String tableName) {
+ SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
+ logRecord(db, action, tableName, -1, accounts);
+ }
+
+ /*
+ * This function receives an opened writable database.
+ */
+ private void logRecord(SQLiteDatabase db, String action, String tableName, long accountId,
+ UserAccounts userAccount) {
+ logRecord(db, action, tableName, accountId, userAccount, getCallingUid());
+ }
+
+ /*
+ * This function receives an opened writable database.
+ */
+ private void logRecord(SQLiteDatabase db, String action, String tableName, long accountId,
+ UserAccounts userAccount, int callingUid) {
+ SQLiteStatement logStatement = userAccount.statementForLogging;
+ logStatement.bindLong(1, accountId);
+ logStatement.bindString(2, action);
+ logStatement.bindString(3, DebugDbHelper.dateFromat.format(new Date()));
+ logStatement.bindLong(4, callingUid);
+ logStatement.bindString(5, tableName);
+ logStatement.bindLong(6, userAccount.debugDbInsertionPoint);
+ logStatement.execute();
+ logStatement.clearBindings();
+ userAccount.debugDbInsertionPoint = (userAccount.debugDbInsertionPoint + 1)
+ % MAX_DEBUG_DB_SIZE;
+ }
+
+ /*
+ * This should only be called once to compile the sql statement for logging
+ * and to find the insertion point.
+ */
+ private void initializeDebugDbSizeAndCompileSqlStatementForLogging(SQLiteDatabase db,
+ UserAccounts userAccount) {
+ // Initialize the count if not done earlier.
+ int size = (int) getDebugTableRowCount(db);
+ if (size >= MAX_DEBUG_DB_SIZE) {
+ // Table is full, and we need to find the point where to insert.
+ userAccount.debugDbInsertionPoint = (int) getDebugTableInsertionPoint(db);
+ } else {
+ userAccount.debugDbInsertionPoint = size;
+ }
+ compileSqlStatementForLogging(db, userAccount);
+ }
+
+ private void compileSqlStatementForLogging(SQLiteDatabase db, UserAccounts userAccount) {
+ String sql = "INSERT OR REPLACE INTO " + DebugDbHelper.TABLE_DEBUG
+ + " VALUES (?,?,?,?,?,?)";
+ userAccount.statementForLogging = db.compileStatement(sql);
+ }
+
+ private long getDebugTableRowCount(SQLiteDatabase db) {
+ String queryCountDebugDbRows = "SELECT COUNT(*) FROM " + DebugDbHelper.TABLE_DEBUG;
+ return DatabaseUtils.longForQuery(db, queryCountDebugDbRows, null);
+ }
+
+ /*
+ * Finds the row key where the next insertion should take place. This should
+ * be invoked only if the table has reached its full capacity.
+ */
+ private long getDebugTableInsertionPoint(SQLiteDatabase db) {
+ // This query finds the smallest timestamp value (and if 2 records have
+ // same timestamp, the choose the lower id).
+ String queryCountDebugDbRows = new StringBuilder()
+ .append("SELECT ").append(DebugDbHelper.KEY)
+ .append(" FROM ").append(DebugDbHelper.TABLE_DEBUG)
+ .append(" ORDER BY ")
+ .append(DebugDbHelper.TIMESTAMP).append(",").append(DebugDbHelper.KEY)
+ .append(" LIMIT 1")
+ .toString();
+ return DatabaseUtils.longForQuery(db, queryCountDebugDbRows, null);
+ }
+
static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context, int userId) {
@@ -2949,6 +3148,8 @@
createSharedAccountsTable(db);
createAccountsDeletionTrigger(db);
+
+ DebugDbHelper.createDebugTable(db);
}
private void createSharedAccountsTable(SQLiteDatabase db) {
@@ -2968,6 +3169,10 @@
db.execSQL("ALTER TABLE " + TABLE_ACCOUNTS + " ADD COLUMN " + ACCOUNTS_PREVIOUS_NAME);
}
+ private void addDebugTable(SQLiteDatabase db) {
+ DebugDbHelper.createDebugTable(db);
+ }
+
private void createAccountsDeletionTrigger(SQLiteDatabase db) {
db.execSQL(""
+ " CREATE TRIGGER " + TABLE_ACCOUNTS + "Delete DELETE ON " + TABLE_ACCOUNTS
@@ -3028,6 +3233,11 @@
oldVersion++;
}
+ if (oldVersion == 7) {
+ addDebugTable(db);
+ oldVersion++;
+ }
+
if (oldVersion != newVersion) {
Log.e(TAG, "failed to upgrade version " + oldVersion + " to version " + newVersion);
}
@@ -3109,6 +3319,23 @@
fout.println(" " + account);
}
+ // Add debug information.
+ fout.println();
+ Cursor cursor = db.query(DebugDbHelper.TABLE_DEBUG, null,
+ null, null, null, null, DebugDbHelper.TIMESTAMP);
+ fout.println("AccountId, Action_Type, timestamp, UID, TableName, Key");
+ fout.println("Accounts History");
+ try {
+ while (cursor.moveToNext()) {
+ // print type,count
+ fout.println(cursor.getString(0) + "," + cursor.getString(1) + "," +
+ cursor.getString(2) + "," + cursor.getString(3) + ","
+ + cursor.getString(4) + "," + cursor.getString(5));
+ }
+ } finally {
+ cursor.close();
+ }
+
fout.println();
synchronized (mSessions) {
final long now = SystemClock.elapsedRealtime();
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 33f915f..62d70d2 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1331,6 +1331,9 @@
}
} catch(RemoteException e) {
}
+ if (r.state == ActivityState.RESUMED) {
+ noStackActivityResumed = false;
+ }
} else {
// This activity is not currently visible, but is running.
// Tell it to become visible.
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 93d37f1..e15bca6 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -16,6 +16,7 @@
package com.android.server.display;
+import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
@@ -31,13 +32,13 @@
import android.os.PowerManager;
import android.os.SystemClock;
import android.text.format.DateUtils;
+import android.util.EventLog;
import android.util.MathUtils;
import android.util.Spline;
import android.util.Slog;
import android.util.TimeUtils;
import java.io.PrintWriter;
-import java.util.Arrays;
class AutomaticBrightnessController {
private static final String TAG = "AutomaticBrightnessController";
@@ -87,7 +88,12 @@
// well after dusk.
private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2;
+ // Debounce for sampling user-initiated changes in display brightness to ensure
+ // the user is satisfied with the result before storing the sample.
+ private static final int BRIGHTNESS_ADJUSTMENT_SAMPLE_DEBOUNCE_MILLIS = 10000;
+
private static final int MSG_UPDATE_AMBIENT_LUX = 1;
+ private static final int MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE = 2;
// Callbacks for requesting updates to the the display's power state
private final Callbacks mCallbacks;
@@ -179,6 +185,14 @@
// Are we going to adjust brightness while dozing.
private boolean mDozing;
+ // True if we are collecting a brightness adjustment sample, along with some data
+ // for the initial state of the sample.
+ private boolean mBrightnessAdjustmentSamplePending;
+ private float mBrightnessAdjustmentSampleOldAdjustment;
+ private float mBrightnessAdjustmentSampleOldLux;
+ private int mBrightnessAdjustmentSampleOldBrightness;
+ private float mBrightnessAdjustmentSampleOldGamma;
+
public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime,
int brightnessMin, int brightnessMax, float dozeScaleFactor,
@@ -216,7 +230,8 @@
return mScreenAutoBrightness;
}
- public void configure(boolean enable, float adjustment, boolean dozing) {
+ public void configure(boolean enable, float adjustment, boolean dozing,
+ boolean userInitiatedChange) {
// While dozing, the application processor may be suspended which will prevent us from
// receiving new information from the light sensor. On some devices, we may be able to
// switch to a wake-up light sensor instead but for now we will simply disable the sensor
@@ -228,6 +243,9 @@
if (changed) {
updateAutoBrightness(false /*sendUpdate*/);
}
+ if (enable && !dozing && userInitiatedChange) {
+ prepareBrightnessAdjustmentSample();
+ }
}
public void dump(PrintWriter pw) {
@@ -486,7 +504,7 @@
}
int newScreenAutoBrightness =
- clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));
+ clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));
if (mScreenAutoBrightness != newScreenAutoBrightness) {
if (DEBUG) {
Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
@@ -507,6 +525,54 @@
mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
}
+ private void prepareBrightnessAdjustmentSample() {
+ if (!mBrightnessAdjustmentSamplePending) {
+ mBrightnessAdjustmentSamplePending = true;
+ mBrightnessAdjustmentSampleOldAdjustment = mScreenAutoBrightnessAdjustment;
+ mBrightnessAdjustmentSampleOldLux = mAmbientLuxValid ? mAmbientLux : -1;
+ mBrightnessAdjustmentSampleOldBrightness = mScreenAutoBrightness;
+ mBrightnessAdjustmentSampleOldGamma = mLastScreenAutoBrightnessGamma;
+ } else {
+ mHandler.removeMessages(MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE);
+ }
+
+ mHandler.sendEmptyMessageDelayed(MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE,
+ BRIGHTNESS_ADJUSTMENT_SAMPLE_DEBOUNCE_MILLIS);
+ }
+
+ private void cancelBrightnessAdjustmentSample() {
+ if (mBrightnessAdjustmentSamplePending) {
+ mBrightnessAdjustmentSamplePending = false;
+ mHandler.removeMessages(MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE);
+ }
+ }
+
+ private void collectBrightnessAdjustmentSample() {
+ if (mBrightnessAdjustmentSamplePending) {
+ mBrightnessAdjustmentSamplePending = false;
+ if (mAmbientLuxValid && mScreenAutoBrightness >= 0) {
+ if (DEBUG) {
+ Slog.d(TAG, "Auto-brightness adjustment changed by user: "
+ + "adj=" + mScreenAutoBrightnessAdjustment
+ + ", lux=" + mAmbientLux
+ + ", brightness=" + mScreenAutoBrightness
+ + ", gamma=" + mLastScreenAutoBrightnessGamma
+ + ", ring=" + mAmbientLightRingBuffer);
+ }
+
+ EventLog.writeEvent(EventLogTags.AUTO_BRIGHTNESS_ADJ,
+ mBrightnessAdjustmentSampleOldAdjustment,
+ mBrightnessAdjustmentSampleOldLux,
+ mBrightnessAdjustmentSampleOldBrightness,
+ mBrightnessAdjustmentSampleOldGamma,
+ mScreenAutoBrightnessAdjustment,
+ mAmbientLux,
+ mScreenAutoBrightness,
+ mLastScreenAutoBrightnessGamma);
+ }
+ }
+ }
+
private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) {
if (lastSunset < 0 || nextSunrise < 0
|| now < lastSunset || now > nextSunrise) {
@@ -537,6 +603,10 @@
case MSG_UPDATE_AMBIENT_LUX:
updateAmbientLux();
break;
+
+ case MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE:
+ collectBrightnessAdjustmentSample();
+ break;
}
}
}
@@ -584,11 +654,7 @@
private int mCount;
public AmbientLightRingBuffer(long lightSensorRate) {
- this((int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / lightSensorRate));
- }
-
- public AmbientLightRingBuffer(int initialCapacity) {
- mCapacity = initialCapacity;
+ mCapacity = (int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / lightSensorRate);
mRingLux = new float[mCapacity];
mRingTime = new long[mCapacity];
}
@@ -664,10 +730,6 @@
return mCount;
}
- public boolean isEmpty() {
- return mCount == 0;
- }
-
public void clear() {
mStart = 0;
mEnd = 0;
@@ -676,27 +738,20 @@
@Override
public String toString() {
- final int length = mCapacity - mStart;
- float[] lux = new float[mCount];
- long[] time = new long[mCount];
-
- if (mCount <= length) {
- System.arraycopy(mRingLux, mStart, lux, 0, mCount);
- System.arraycopy(mRingTime, mStart, time, 0, mCount);
- } else {
- System.arraycopy(mRingLux, mStart, lux, 0, length);
- System.arraycopy(mRingLux, 0, lux, length, mCount - length);
-
- System.arraycopy(mRingTime, mStart, time, 0, length);
- System.arraycopy(mRingTime, 0, time, length, mCount - length);
+ StringBuffer buf = new StringBuffer();
+ buf.append('[');
+ for (int i = 0; i < mCount; i++) {
+ final long next = i + 1 < mCount ? getTime(i + 1) : SystemClock.uptimeMillis();
+ if (i != 0) {
+ buf.append(", ");
+ }
+ buf.append(getLux(i));
+ buf.append(" / ");
+ buf.append(next - getTime(i));
+ buf.append("ms");
}
- return "AmbientLightRingBuffer{mCapacity=" + mCapacity
- + ", mStart=" + mStart
- + ", mEnd=" + mEnd
- + ", mCount=" + mCount
- + ", mRingLux=" + Arrays.toString(lux)
- + ", mRingTime=" + Arrays.toString(time)
- + "}";
+ buf.append(']');
+ return buf.toString();
}
private int offsetOf(int index) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index f74601e..35fbef6 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -70,12 +70,11 @@
*/
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks {
private static final String TAG = "DisplayPowerController";
+ private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
private static boolean DEBUG = false;
private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
- private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";
-
// If true, uses the color fade on animation.
// We might want to turn this off if we cannot get a guarantee that the screen
// actually turns on and starts showing new content after the call to set the
@@ -599,8 +598,11 @@
autoBrightnessEnabled = mPowerRequest.useAutoBrightness
&& (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
&& brightness < 0;
+ final boolean userInitiatedChange = autoBrightnessAdjustmentChanged
+ && mPowerRequest.brightnessSetByUser;
mAutomaticBrightnessController.configure(autoBrightnessEnabled,
- mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON);
+ mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
+ userInitiatedChange);
}
// Apply brightness boost.
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 53ceb2e..b066d6b 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -68,7 +68,7 @@
private static final int defaultMaxActiveJobsPerService =
ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
/** Amount of time a job is allowed to execute for before being considered timed-out. */
- private static final long EXECUTING_TIMESLICE_MILLIS = 60 * 1000;
+ private static final long EXECUTING_TIMESLICE_MILLIS = 10 * 60 * 1000;
/** Amount of time the JobScheduler will wait for a response from an app for a message. */
private static final long OP_TIMEOUT_MILLIS = 8 * 1000;
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index e106a4a..c9f5bdf 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -112,6 +112,7 @@
+ " / " + idDebugString(baseContext, sbn.getPackageName(), notification.icon));
pw.println(prefix + " pri=" + notification.priority + " score=" + sbn.getScore());
pw.println(prefix + " key=" + sbn.getKey());
+ pw.println(prefix + " seen=" + mIsSeen);
pw.println(prefix + " groupKey=" + getGroupKey());
pw.println(prefix + " contentIntent=" + notification.contentIntent);
pw.println(prefix + " deleteIntent=" + notification.deleteIntent);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f087c33..6c18e25 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -49,6 +49,7 @@
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
+import static android.content.pm.PackageManager.MATCH_ALL;
import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
@@ -2274,6 +2275,13 @@
}
continue;
}
+ if (!pkg.isSystemApp()) {
+ if (logging) {
+ Slog.d(TAG, "No priming domain verifications for a non system package : " +
+ packageName);
+ }
+ continue;
+ }
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
if (hasValidDomains(filter, false)) {
@@ -2281,7 +2289,7 @@
}
}
}
- if (allHosts.size() > 0) {
+ if (allHosts.size() == 0) {
allHosts.add("*");
}
IntentFilterVerificationInfo ivi =
@@ -3939,7 +3947,7 @@
}
result = filterIfNotPrimaryUser(result, userId);
if (result.size() > 1 && hasWebURI(intent)) {
- return filterCandidatesWithDomainPreferedActivitiesLPr(result);
+ return filterCandidatesWithDomainPreferedActivitiesLPr(flags, result);
}
return result;
}
@@ -3984,7 +3992,7 @@
}
private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPr(
- List<ResolveInfo> candidates) {
+ int flags, List<ResolveInfo> candidates) {
if (DEBUG_PREFERRED) {
Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " +
candidates.size());
@@ -4004,6 +4012,11 @@
String packageName = info.activityInfo.packageName;
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null) {
+ // Add to the special match all list (Browser use case)
+ if (info.handleAllWebDataURI) {
+ matchAllList.add(info);
+ continue;
+ }
// Try to get the status from User settings first
int status = getDomainVerificationStatusLPr(ps, userId);
if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
@@ -4013,10 +4026,6 @@
} else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
undefinedList.add(info);
}
- // Add to the special match all list (Browser use case)
- if (info.handleAllWebDataURI) {
- matchAllList.add(info);
- }
}
}
// If there is nothing selected, add all candidates and remove the ones that the User
@@ -4031,7 +4040,30 @@
result.removeAll(matchAllList);
if (result.size() == 0) {
result.addAll(undefinedList);
- result.addAll(matchAllList);
+ if ((flags & MATCH_ALL) != 0) {
+ result.addAll(matchAllList);
+ } else {
+ // Try to add the Default Browser if we can
+ final String defaultBrowserPackageName = getDefaultBrowserPackageName(
+ UserHandle.myUserId());
+ if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
+ boolean defaultBrowserFound = false;
+ final int browserCount = matchAllList.size();
+ for (int n=0; n<browserCount; n++) {
+ ResolveInfo browser = matchAllList.get(n);
+ if (browser.activityInfo.packageName.equals(defaultBrowserPackageName)) {
+ result.add(browser);
+ defaultBrowserFound = true;
+ break;
+ }
+ }
+ if (!defaultBrowserFound) {
+ result.addAll(matchAllList);
+ }
+ } else {
+ result.addAll(matchAllList);
+ }
+ }
}
}
if (DEBUG_PREFERRED) {
@@ -11331,10 +11363,16 @@
verifierUid, userId, verificationId, filter, packageName);
count++;
} else if (!needsFilterVerification) {
- Slog.d(TAG, "No verification needed for IntentFilter:"
- + filter.toString());
+ Slog.d(TAG, "No verification needed for IntentFilter:" + filter.toString());
if (hasValidDomains(filter)) {
- allHosts.addAll(filter.getHostsList());
+ ArrayList<String> hosts = filter.getHostsList();
+ if (hosts.size() > 0) {
+ allHosts.addAll(hosts);
+ } else {
+ if (allHosts.isEmpty()) {
+ allHosts.add("*");
+ }
+ }
}
} else {
Slog.d(TAG, "Verification already done for IntentFilter:"
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index 926090e..01c110f 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -41,11 +41,13 @@
private volatile boolean mSimSecure;
private volatile boolean mInputRestricted;
+ private int mCurrentUserId;
+
private final LockPatternUtils mLockPatternUtils;
public KeyguardStateMonitor(Context context, IKeyguardService service) {
mLockPatternUtils = new LockPatternUtils(context);
- mLockPatternUtils.setCurrentUser(ActivityManager.getCurrentUser());
+ mCurrentUserId = ActivityManager.getCurrentUser();
try {
service.addStateMonitorCallback(this);
} catch (RemoteException e) {
@@ -58,7 +60,7 @@
}
public boolean isSecure() {
- return mLockPatternUtils.isSecure() || mSimSecure;
+ return mLockPatternUtils.isSecure(getCurrentUser()) || mSimSecure;
}
public boolean isInputRestricted() {
@@ -75,8 +77,12 @@
mSimSecure = simSecure;
}
- public void setCurrentUser(int userId) {
- mLockPatternUtils.setCurrentUser(userId);
+ public synchronized void setCurrentUser(int userId) {
+ mCurrentUserId = userId;
+ }
+
+ private synchronized int getCurrentUser() {
+ return mCurrentUserId;
}
@Override // Binder interface
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 6c8959c..f790f75 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1819,6 +1819,7 @@
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
// Determine appropriate screen brightness and auto-brightness adjustments.
+ boolean brightnessSetByUser = true;
int screenBrightness = mScreenBrightnessSettingDefault;
float screenAutoBrightnessAdjustment = 0.0f;
boolean autoBrightness = (mScreenBrightnessModeSetting ==
@@ -1826,6 +1827,7 @@
if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
screenBrightness = mScreenBrightnessOverrideFromWindowManager;
autoBrightness = false;
+ brightnessSetByUser = false;
} else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
screenBrightness = mTemporaryScreenBrightnessSettingOverride;
} else if (isValidBrightness(mScreenBrightnessSetting)) {
@@ -1851,6 +1853,7 @@
mDisplayPowerRequest.screenBrightness = screenBrightness;
mDisplayPowerRequest.screenAutoBrightnessAdjustment =
screenAutoBrightnessAdjustment;
+ mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser;
mDisplayPowerRequest.useAutoBrightness = autoBrightness;
mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
diff --git a/services/core/java/com/android/server/wm/Watermark.java b/services/core/java/com/android/server/wm/Watermark.java
index e226e3d..ba3ce36 100644
--- a/services/core/java/com/android/server/wm/Watermark.java
+++ b/services/core/java/com/android/server/wm/Watermark.java
@@ -84,7 +84,7 @@
int fontSize = WindowManagerService.getPropertyInt(tokens, 1,
TypedValue.COMPLEX_UNIT_DIP, 20, dm);
- mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint = new Paint();
mTextPaint.setTextSize(fontSize);
mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c5bdbb0..d4b3dab 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2345,7 +2345,6 @@
boolean reportNewConfig = false;
WindowState attachedWindow = null;
- WindowState win = null;
long origId;
final int type = attrs.type;
@@ -2482,7 +2481,7 @@
addToken = true;
}
- win = new WindowState(this, session, client, token,
+ WindowState win = new WindowState(this, session, client, token,
attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
if (win.mDeathRecipient == null) {
// Client has apparently died, so there is no reason to
@@ -9941,18 +9940,20 @@
final WindowStateAnimator winAnimator = w.mWinAnimator;
- // If the window has moved due to its containing
- // content frame changing, then we'd like to animate
- // it.
- if (w.mHasSurface && w.shouldAnimateMove()) {
- // Frame has moved, containing content frame
- // has also moved, and we're not currently animating...
- // let's do something.
- Animation a = AnimationUtils.loadAnimation(mContext,
- com.android.internal.R.anim.window_move_from_decor);
- winAnimator.setAnimation(a);
- winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
- winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
+ // If the window has moved due to its containing content frame changing, then
+ // notify the listeners and optionally animate it.
+ if (w.hasMoved()) {
+ // Frame has moved, containing content frame has also moved, and we're not
+ // currently animating... let's do something.
+ final int left = w.mFrame.left;
+ final int top = w.mFrame.top;
+ if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0) {
+ Animation a = AnimationUtils.loadAnimation(mContext,
+ com.android.internal.R.anim.window_move_from_decor);
+ winAnimator.setAnimation(a);
+ winAnimator.mAnimDw = w.mLastFrame.left - left;
+ winAnimator.mAnimDh = w.mLastFrame.top - top;
+ }
//TODO (multidisplay): Accessibility supported only for the default display.
if (mAccessibilityController != null
@@ -9961,7 +9962,7 @@
}
try {
- w.mClient.moved(w.mFrame.left, w.mFrame.top);
+ w.mClient.moved(left, top);
} catch (RemoteException e) {
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ec70879..ad25462 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -20,7 +20,6 @@
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
@@ -1081,16 +1080,14 @@
}
/**
- * Return whether this window is wanting to have a translation
- * animation applied to it for an in-progress move. (Only makes
+ * Return whether this window has moved. (Only makes
* sense to call from performLayoutAndPlaceSurfacesLockedInner().)
*/
- boolean shouldAnimateMove() {
- return mContentChanged && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay()
- && (mFrame.top != mLastFrame.top
+ boolean hasMoved() {
+ return mHasSurface && mContentChanged && !mExiting && !mWinAnimator.mLastHidden
+ && mService.okToDisplay() && (mFrame.top != mLastFrame.top
|| mFrame.left != mLastFrame.left)
- && (mAttrs.privateFlags&PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
- && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove());
+ && (mAttachedWindow == null || !mAttachedWindow.hasMoved());
}
boolean isFullscreen(int screenWidth, int screenHeight) {
@@ -1709,7 +1706,7 @@
pw.println(mWallpaperDisplayOffsetY);
}
if (mDrawLock != null) {
- pw.println("mDrawLock=" + mDrawLock);
+ pw.print(prefix); pw.println("mDrawLock=" + mDrawLock);
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 31d7f74..1d00de9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -182,6 +182,7 @@
private static final String ATTR_PERMISSION_PROVIDER = "permission-provider";
private static final String ATTR_SETUP_COMPLETE = "setup-complete";
private static final String ATTR_PREFERRED_SETUP_ACTIVITY = "setup-activity";
+ private static final String ATTR_PERMISSION_POLICY = "permission-policy";
private static final String ATTR_DELEGATED_CERT_INSTALLER = "delegated-cert-installer";
@@ -300,6 +301,7 @@
int mPasswordOwner = -1;
long mLastMaximumTimeToLock = -1;
boolean mUserSetupComplete = false;
+ int mPermissionPolicy;
final HashMap<ComponentName, ActiveAdmin> mAdminMap = new HashMap<>();
final ArrayList<ActiveAdmin> mAdminList = new ArrayList<>();
@@ -1409,6 +1411,10 @@
out.attribute(null, ATTR_SETUP_COMPLETE,
Boolean.toString(true));
}
+ if (policy.mPermissionPolicy != DevicePolicyManager.PERMISSION_POLICY_PROMPT) {
+ out.attribute(null, ATTR_PERMISSION_POLICY,
+ Integer.toString(policy.mPermissionPolicy));
+ }
if (policy.mDelegatedCertInstallerPackage != null) {
out.attribute(null, ATTR_DELEGATED_CERT_INSTALLER,
policy.mDelegatedCertInstallerPackage);
@@ -1537,6 +1543,10 @@
if (userSetupComplete != null && Boolean.toString(true).equals(userSetupComplete)) {
policy.mUserSetupComplete = true;
}
+ String permissionPolicy = parser.getAttributeValue(null, ATTR_PERMISSION_POLICY);
+ if (!TextUtils.isEmpty(permissionPolicy)) {
+ policy.mPermissionPolicy = Integer.parseInt(permissionPolicy);
+ }
policy.mDelegatedCertInstallerPackage = parser.getAttributeValue(null,
ATTR_DELEGATED_CERT_INSTALLER);
String preferredSetupActivity =
@@ -4253,14 +4263,22 @@
return;
}
UserHandle callingUser = Binder.getCallingUserHandle();
+ int userId = callingUser.getIdentifier();
// Check if this is the profile owner who is calling
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
synchronized (this) {
+ // Reset some of the profile-owner policies
+ DevicePolicyData policy = getUserData(userId);
+ policy.mPermissionPolicy = DevicePolicyManager.PERMISSION_POLICY_PROMPT;
+ policy.mDelegatedCertInstallerPackage = null;
+ policy.mStatusBarEnabledState = true;
+ saveSettingsLocked(userId);
+
long ident = Binder.clearCallingIdentity();
try {
clearUserRestrictions(callingUser);
if (mDeviceOwner != null) {
- mDeviceOwner.removeProfileOwner(callingUser.getIdentifier());
+ mDeviceOwner.removeProfileOwner(userId);
mDeviceOwner.writeOwnerFile();
}
} finally {
@@ -6261,4 +6279,48 @@
}
}
}
+
+ @Override
+ public void setPermissionPolicy(ComponentName admin, int policy) throws RemoteException {
+ int userId = UserHandle.getCallingUserId();
+ synchronized (this) {
+ getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ DevicePolicyData userPolicy = getUserData(userId);
+ if (userPolicy.mPermissionPolicy != policy) {
+ userPolicy.mPermissionPolicy = policy;
+ saveSettingsLocked(userId);
+ }
+ }
+ }
+
+ @Override
+ public int getPermissionPolicy(ComponentName admin) throws RemoteException {
+ int userId = UserHandle.getCallingUserId();
+ synchronized (this) {
+ DevicePolicyData userPolicy = getUserData(userId);
+ return userPolicy.mPermissionPolicy;
+ }
+ }
+
+ @Override
+ public boolean setPermissionGranted(ComponentName admin, String packageName,
+ String permission, boolean granted) throws RemoteException {
+ UserHandle user = Binder.getCallingUserHandle();
+ synchronized (this) {
+ getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ long ident = Binder.clearCallingIdentity();
+ try {
+ if (granted) {
+ mContext.getPackageManager().grantPermission(packageName, permission, user);
+ } else {
+ mContext.getPackageManager().revokePermission(packageName, permission, user);
+ }
+ return true;
+ } catch (SecurityException se) {
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
index fbdb20b..2557974 100644
--- a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
@@ -24,7 +24,6 @@
import android.util.LongSparseArray;
import com.android.internal.util.ArrayUtils;
-import java.lang.reflect.Field;
import java.io.File;
import java.io.IOException;
import java.security.cert.CertificateException;
@@ -43,53 +42,6 @@
"", 1, 0, 0);
}
- public PublicKey getPubKey(long pkId) throws NoSuchFieldException, IllegalAccessException {
- Field pkField = mKsms.getClass().getDeclaredField("mPublicKeys");
- pkField.setAccessible(true);
- LongSparseArray<KeySetManagerService.PublicKeyHandle> mPublicKeys =
- (LongSparseArray<KeySetManagerService.PublicKeyHandle>) pkField.get(mKsms);
- KeySetManagerService.PublicKeyHandle pkh = mPublicKeys.get(pkId);
- if (pkh == null) {
- return null;
- } else {
- return pkh.getKey();
- }
- }
-
- public int getPubKeyRefCount(long pkId) throws NoSuchFieldException, IllegalAccessException {
- Field pkField = mKsms.getClass().getDeclaredField("mPublicKeys");
- pkField.setAccessible(true);
- LongSparseArray<KeySetManagerService.PublicKeyHandle> mPublicKeys =
- (LongSparseArray<KeySetManagerService.PublicKeyHandle>) pkField.get(mKsms);
- KeySetManagerService.PublicKeyHandle pkh = mPublicKeys.get(pkId);
- if (pkh == null) {
- return 0;
- } else {
- return pkh.getRefCountLPr();
- }
- }
-
- public int getKeySetRefCount(long keysetId) throws NoSuchFieldException, IllegalAccessException {
- Field ksField = mKsms.getClass().getDeclaredField("mKeySets");
- ksField.setAccessible(true);
- LongSparseArray<KeySetHandle> mKeySets =
- (LongSparseArray<KeySetHandle>) ksField.get(mKsms);
- KeySetHandle ksh = mKeySets.get(keysetId);
- if (ksh == null) {
- return 0;
- } else {
- return ksh.getRefCountLPr();
- }
- }
-
- public LongSparseArray<ArraySet<Long>> getKeySetMapping()
- throws NoSuchFieldException, IllegalAccessException {
- Field ksField = mKsms.getClass().getDeclaredField("mKeySetMapping");
- ksField.setAccessible(true);
- return (LongSparseArray<ArraySet<Long>>) ksField.get(mKsms);
- }
-
-
@Override
public void setUp() throws Exception {
super.setUp();
@@ -168,10 +120,10 @@
signingKeys.add(keyA);
mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
- assertEquals(1, getKeySetRefCount(1));
- assertEquals(1, getPubKeyRefCount(1));
- assertEquals(keyA, getPubKey(1));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(1, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(1);
assertEquals(1, mapping.size());
@@ -198,10 +150,10 @@
/* add again, to represent upgrade of package */
mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
- assertEquals(1, getKeySetRefCount(1));
- assertEquals(1, getPubKeyRefCount(1));
- assertEquals(keyA, getPubKey(1));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(1, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(1);
assertEquals(1, mapping.size());
@@ -231,12 +183,12 @@
signingKeys.add(keyB);
mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
- assertEquals(0, getKeySetRefCount(1));
- assertEquals(1, getKeySetRefCount(2));
- assertEquals(0, getPubKeyRefCount(1));
- assertEquals(1, getPubKeyRefCount(2));
- assertEquals(keyB, getPubKey(2));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+ assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+ assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(1, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(2);
assertEquals(1, mapping.size());
@@ -269,13 +221,13 @@
signingKeys.add(keyB);
mKsms.addSigningKeySetToPackageLPw(ps1.name, signingKeys);
- assertEquals(1, getKeySetRefCount(1));
- assertEquals(1, getKeySetRefCount(2));
- assertEquals(1, getPubKeyRefCount(1));
- assertEquals(1, getPubKeyRefCount(2));
- assertEquals(keyA, getPubKey(1));
- assertEquals(keyB, getPubKey(2));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+ assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+ assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(2, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(1);
assertEquals(1, mapping.size());
@@ -312,10 +264,10 @@
mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys2);
/* verify first is unchanged */
- assertEquals(1, getKeySetRefCount(1));
- assertEquals(1, getPubKeyRefCount(1));
- assertEquals(keyA, getPubKey(1));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(2, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(1);
assertEquals(1, mapping.size());
@@ -323,9 +275,9 @@
assertEquals(1, ps1.keySetData.getProperSigningKeySet());
/* verify second */
- assertEquals(1, getKeySetRefCount(2));
- assertEquals(1, getPubKeyRefCount(2));
- assertEquals(keyB, getPubKey(2));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+ assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
mapping = ksMapping.get(2);
assertEquals(1, mapping.size());
assertTrue(mapping.contains(new Long(2)));
@@ -353,10 +305,10 @@
/* add again for second package */
mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
- assertEquals(2, getKeySetRefCount(1));
- assertEquals(1, getPubKeyRefCount(1));
- assertEquals(keyA, getPubKey(1));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(2, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(1, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(1);
assertEquals(1, mapping.size());
@@ -388,13 +340,13 @@
signingKeys.add(keyB);
mKsms.addSigningKeySetToPackageLPw(ps2.name, signingKeys);
- assertEquals(1, getKeySetRefCount(1));
- assertEquals(1, getKeySetRefCount(2));
- assertEquals(2, getPubKeyRefCount(1));
- assertEquals(1, getPubKeyRefCount(2));
- assertEquals(keyA, getPubKey(1));
- assertEquals(keyB, getPubKey(2));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+ assertEquals(2, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+ assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+ assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(2, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(1);
assertEquals(1, mapping.size());
@@ -429,16 +381,17 @@
signingKeys.add(keyB);
mKsms.addSigningKeySetToPackageLPw(ps.name, signingKeys);
- assertEquals(0, getKeySetRefCount(1));
- assertEquals(1, getKeySetRefCount(2));
- assertEquals(0, getPubKeyRefCount(1));
- assertEquals(1, getPubKeyRefCount(2));
- assertEquals(1, getPubKeyRefCount(3));
+ assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+ assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 3));
/* the pub key is removed w/prev keyset and may be either 2 or 3 */
- assertTrue(keyA.equals(getPubKey(2)) && keyB.equals(getPubKey(3))
- || keyA.equals(getPubKey(3)) && keyB.equals(getPubKey(2)));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertTrue(keyA.equals(KeySetUtils.getPubKey(mKsms, 2)) || keyA.equals(KeySetUtils.getPubKey(mKsms, 3)));
+ assertTrue(keyB.equals(KeySetUtils.getPubKey(mKsms, 2)) || keyB.equals(KeySetUtils.getPubKey(mKsms, 3)));
+ assertFalse(KeySetUtils.getPubKey(mKsms, 2).equals(KeySetUtils.getPubKey(mKsms, 3)));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(1, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(2);
assertEquals(2, mapping.size());
@@ -462,10 +415,10 @@
definedKS.put("aliasA", keys);
mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
- assertEquals(1, getKeySetRefCount(1));
- assertEquals(1, getPubKeyRefCount(1));
- assertEquals(keyA, getPubKey(1));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(1, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(1);
assertEquals(1, mapping.size());
@@ -490,10 +443,10 @@
definedKS.put("aliasA2", keys);
mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
- assertEquals(2, getKeySetRefCount(1));
- assertEquals(1, getPubKeyRefCount(1));
- assertEquals(keyA, getPubKey(1));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(2, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(1, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(1);
assertEquals(1, mapping.size());
@@ -527,12 +480,12 @@
definedKS.put("aliasB", keys);
mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
- assertEquals(0, getKeySetRefCount(1));
- assertEquals(0, getPubKeyRefCount(1));
- assertEquals(1, getKeySetRefCount(2));
- assertEquals(1, getPubKeyRefCount(2));
- assertEquals(keyB, getPubKey(2));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+ assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(1, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(2);
assertEquals(1, mapping.size());
@@ -566,12 +519,12 @@
definedKS.put("aliasA", keys);
mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
- assertEquals(0, getKeySetRefCount(1));
- assertEquals(0, getPubKeyRefCount(1));
- assertEquals(1, getKeySetRefCount(2));
- assertEquals(1, getPubKeyRefCount(2));
- assertEquals(keyB, getPubKey(2));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+ assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(1, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(2);
assertEquals(1, mapping.size());
@@ -608,10 +561,10 @@
definedKS.put("aliasC", keys1);
mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
- assertEquals(1, getKeySetRefCount(3));
- assertEquals(1, getPubKeyRefCount(3));
- assertEquals(keyC, getPubKey(3));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 3));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 3));
+ assertEquals(keyC, KeySetUtils.getPubKey(mKsms, 3));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(2, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(3);
assertEquals(1, mapping.size());
@@ -619,13 +572,13 @@
assertEquals(new Long(3), ps.keySetData.getAliases().get("aliasC"));
/* either keyset w/keyA or w/keyB was added first, address both cases */
- if (1 == getKeySetRefCount(1)) {
+ if (1 == KeySetUtils.getKeySetRefCount(mKsms, 1)) {
/* keyB was added first and should have keyset 1 and pub-key 1 */
- assertEquals(1, getPubKeyRefCount(1));
- assertEquals(0, getKeySetRefCount(2));
- assertEquals(0, getPubKeyRefCount(2));
- assertEquals(keyB, getPubKey(1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 2));
+ assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+ assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 1));
mapping = ksMapping.get(1);
assertEquals(1, mapping.size());
assertTrue(mapping.contains(new Long(1)));
@@ -633,11 +586,11 @@
} else {
/* keyA was added first and keyB has id 2 */
- assertEquals(1, getKeySetRefCount(2));
- assertEquals(1, getPubKeyRefCount(2));
- assertEquals(0, getKeySetRefCount(1));
- assertEquals(0, getPubKeyRefCount(1));
- assertEquals(keyB, getPubKey(2));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+ assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
mapping = ksMapping.get(2);
assertEquals(1, mapping.size());
assertTrue(mapping.contains(new Long(2)));
@@ -674,14 +627,14 @@
definedKS.put("aliasA", keys1);
mKsms.addDefinedKeySetsToPackageLPw(ps.name, definedKS);
- assertEquals(0, getKeySetRefCount(1));
- assertEquals(0, getKeySetRefCount(2));
- assertEquals(1, getKeySetRefCount(3));
- assertEquals(0, getPubKeyRefCount(1));
- assertEquals(0, getPubKeyRefCount(2));
- assertEquals(1, getPubKeyRefCount(3));
- assertEquals(keyA, getPubKey(3));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 2));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 3));
+ assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 2));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 3));
+ assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 3));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(1, ksMapping.size());
ArraySet<Long> mapping = ksMapping.get(3);
assertEquals(1, mapping.size());
@@ -780,9 +733,9 @@
/* remove its references */
mKsms.removeAppKeySetDataLPw(ps.name);
- assertEquals(0, getKeySetRefCount(1));
- assertEquals(0, getPubKeyRefCount(1));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(0, ksMapping.size());
assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps.keySetData.getProperSigningKeySet());
}
@@ -807,9 +760,9 @@
/* remove references from first package */
mKsms.removeAppKeySetDataLPw(ps1.name);
- assertEquals(1, getKeySetRefCount(1));
- assertEquals(1, getPubKeyRefCount(1));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(1, ksMapping.size());
assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps1.keySetData.getProperSigningKeySet());
assertEquals(1, ps2.keySetData.getProperSigningKeySet());
@@ -840,9 +793,9 @@
mKsms.addUpgradeKeySetsToPackageLPw(ps.name, upgradeKS);
mKsms.removeAppKeySetDataLPw(ps.name);
- assertEquals(0, getKeySetRefCount(1));
- assertEquals(0, getPubKeyRefCount(1));
- LongSparseArray<ArraySet<Long>> ksMapping = getKeySetMapping();
+ assertEquals(0, KeySetUtils.getKeySetRefCount(mKsms, 1));
+ assertEquals(0, KeySetUtils.getPubKeyRefCount(mKsms, 1));
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
assertEquals(0, ksMapping.size());
assertEquals(PackageKeySetData.KEYSET_UNASSIGNED, ps.keySetData.getProperSigningKeySet());
assertEquals(0, ps.keySetData.getAliases().size());
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetUtils.java b/services/tests/servicestests/src/com/android/server/pm/KeySetUtils.java
new file mode 100644
index 0000000..9e1a366
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/KeySetUtils.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.util.ArraySet;
+import android.util.LongSparseArray;
+
+import java.lang.reflect.Field;
+import java.security.PublicKey;
+
+public class KeySetUtils {
+
+ public static PublicKey getPubKey(KeySetManagerService ksms, long pkId)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field pkField = ksms.getClass().getDeclaredField("mPublicKeys");
+ pkField.setAccessible(true);
+ LongSparseArray<KeySetManagerService.PublicKeyHandle> mPublicKeys =
+ (LongSparseArray<KeySetManagerService.PublicKeyHandle>) pkField.get(ksms);
+ KeySetManagerService.PublicKeyHandle pkh = mPublicKeys.get(pkId);
+ if (pkh == null) {
+ return null;
+ } else {
+ return pkh.getKey();
+ }
+ }
+
+ public static int getPubKeyRefCount(KeySetManagerService ksms, long pkId)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field pkField = ksms.getClass().getDeclaredField("mPublicKeys");
+ pkField.setAccessible(true);
+ LongSparseArray<KeySetManagerService.PublicKeyHandle> mPublicKeys =
+ (LongSparseArray<KeySetManagerService.PublicKeyHandle>) pkField.get(ksms);
+ KeySetManagerService.PublicKeyHandle pkh = mPublicKeys.get(pkId);
+ if (pkh == null) {
+ return 0;
+ } else {
+ return pkh.getRefCountLPr();
+ }
+ }
+
+ public static int getKeySetRefCount(KeySetManagerService ksms, long keysetId)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field ksField = ksms.getClass().getDeclaredField("mKeySets");
+ ksField.setAccessible(true);
+ LongSparseArray<KeySetHandle> mKeySets =
+ (LongSparseArray<KeySetHandle>) ksField.get(ksms);
+ KeySetHandle ksh = mKeySets.get(keysetId);
+ if (ksh == null) {
+ return 0;
+ } else {
+ return ksh.getRefCountLPr();
+ }
+ }
+
+ public static LongSparseArray<ArraySet<Long>> getKeySetMapping(KeySetManagerService ksms)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field ksField = ksms.getClass().getDeclaredField("mKeySetMapping");
+ ksField.setAccessible(true);
+ return (LongSparseArray<ArraySet<Long>>) ksField.get(ksms);
+ }
+
+ public static Long getLastIssuedKeyId(KeySetManagerService ksms)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field ksField = ksms.getClass().getDeclaredField("lastIssuedKeyId");
+ ksField.setAccessible(true);
+ return (Long) ksField.get(ksms);
+ }
+
+ public static Long getLastIssuedKeySetId(KeySetManagerService ksms)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field ksField = ksms.getClass().getDeclaredField("lastIssuedKeySetId");
+ ksField.setAccessible(true);
+ return (Long) ksField.get(ksms);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index a3f3a5d..ed1db6f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -21,15 +21,21 @@
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import android.content.Context;
+import android.content.pm.PackageParser;
import android.test.AndroidTestCase;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
+import android.util.LongSparseArray;
import com.android.internal.os.AtomicFile;
+import java.lang.reflect.Constructor;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.security.PublicKey;
public class PackageManagerSettingsTests extends AndroidTestCase {
private static final String PACKAGE_NAME_2 = "com.google.app2";
@@ -67,18 +73,24 @@
+ "</permissions>"
+ "<package name=\"com.google.app1\" codePath=\"/system/app/app1.apk\" nativeLibraryPath=\"/data/data/com.google.app1/lib\" flags=\"1\" ft=\"1360e2caa70\" it=\"135f2f80d08\" ut=\"1360e2caa70\" version=\"1109\" sharedUserId=\"11000\">"
+ "<sigs count=\"1\">"
- + "<cert index=\"0\" key=\"308886\" />"
+ + "<cert index=\"0\" key=\"" + KeySetStrings.ctsKeySetCertA + "\" />"
+ "</sigs>"
+ + "<proper-signing-keyset identifier=\"1\" />"
+ "</package>"
+ "<package name=\"com.google.app2\" codePath=\"/system/app/app2.apk\" nativeLibraryPath=\"/data/data/com.google.app2/lib\" flags=\"1\" ft=\"1360e578718\" it=\"135f2f80d08\" ut=\"1360e578718\" version=\"15\" enabled=\"3\" userId=\"11001\">"
+ "<sigs count=\"1\">"
+ "<cert index=\"0\" />"
+ "</sigs>"
+ + "<proper-signing-keyset identifier=\"1\" />"
+ + "<defined-keyset alias=\"AB\" identifier=\"4\" />"
+ "</package>"
+ "<package name=\"com.android.app3\" codePath=\"/system/app/app3.apk\" nativeLibraryPath=\"/data/data/com.android.app3/lib\" flags=\"1\" ft=\"1360e577b60\" it=\"135f2f80d08\" ut=\"1360e577b60\" version=\"15\" userId=\"11030\">"
+ "<sigs count=\"1\">"
- + "<cert index=\"1\" key=\"308366\" />"
+ + "<cert index=\"1\" key=\"" + KeySetStrings.ctsKeySetCertB + "\" />"
+ "</sigs>"
+ + "<proper-signing-keyset identifier=\"2\" />"
+ + "<upgrade-keyset identifier=\"3\" />"
+ + "<defined-keyset alias=\"C\" identifier=\"3\" />"
+ "</package>"
+ "<shared-user name=\"com.android.shared1\" userId=\"11000\">"
+ "<sigs count=\"1\">"
@@ -88,6 +100,30 @@
+ "<item name=\"android.permission.REBOOT\" />"
+ "</perms>"
+ "</shared-user>"
+ + "<keyset-settings version=\"1\">"
+ + "<keys>"
+ + "<public-key identifier=\"1\" value=\"" + KeySetStrings.ctsKeySetPublicKeyA + "\" />"
+ + "<public-key identifier=\"2\" value=\"" + KeySetStrings.ctsKeySetPublicKeyB + "\" />"
+ + "<public-key identifier=\"3\" value=\"" + KeySetStrings.ctsKeySetPublicKeyC + "\" />"
+ + "</keys>"
+ + "<keysets>"
+ + "<keyset identifier=\"1\">"
+ + "<key-id identifier=\"1\" />"
+ + "</keyset>"
+ + "<keyset identifier=\"2\">"
+ + "<key-id identifier=\"2\" />"
+ + "</keyset>"
+ + "<keyset identifier=\"3\">"
+ + "<key-id identifier=\"3\" />"
+ + "</keyset>"
+ + "<keyset identifier=\"4\">"
+ + "<key-id identifier=\"1\" />"
+ + "<key-id identifier=\"2\" />"
+ + "</keyset>"
+ + "</keysets>"
+ + "<lastIssuedKeyId value=\"3\" />"
+ + "<lastIssuedKeySetId value=\"4\" />"
+ + "</keyset-settings>"
+ "</packages>").getBytes());
}
@@ -131,6 +167,104 @@
writePackagesList();
}
+ private void createUserManagerServiceRef() throws ReflectiveOperationException {
+ Constructor<UserManagerService> umsc =
+ UserManagerService.class.getDeclaredConstructor(
+ Context.class,
+ PackageManagerService.class,
+ Object.class,
+ Object.class,
+ File.class,
+ File.class);
+ umsc.setAccessible(true);
+ UserManagerService ums = umsc.newInstance(getContext(), null,
+ new Object(), new Object(), getContext().getFilesDir(),
+ new File(getContext().getFilesDir(), "user"));
+ }
+
+ private void verifyKeySetMetaData(Settings settings)
+ throws ReflectiveOperationException, IllegalAccessException {
+ ArrayMap<String, PackageSetting> packages = settings.mPackages;
+ KeySetManagerService ksms = settings.mKeySetManagerService;
+
+ /* verify keyset and public key ref counts */
+ assertEquals(2, KeySetUtils.getKeySetRefCount(ksms, 1));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(ksms, 2));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(ksms, 3));
+ assertEquals(1, KeySetUtils.getKeySetRefCount(ksms, 4));
+ assertEquals(2, KeySetUtils.getPubKeyRefCount(ksms, 1));
+ assertEquals(2, KeySetUtils.getPubKeyRefCount(ksms, 2));
+ assertEquals(1, KeySetUtils.getPubKeyRefCount(ksms, 3));
+
+ /* verify public keys properly read */
+ PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
+ PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
+ PublicKey keyC = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyC);
+ assertEquals(keyA, KeySetUtils.getPubKey(ksms, 1));
+ assertEquals(keyB, KeySetUtils.getPubKey(ksms, 2));
+ assertEquals(keyC, KeySetUtils.getPubKey(ksms, 3));
+
+ /* verify mapping is correct (ks -> pub keys) */
+ LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(ksms);
+ ArraySet<Long> mapping = ksMapping.get(1);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ mapping = ksMapping.get(2);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(2)));
+ mapping = ksMapping.get(3);
+ assertEquals(1, mapping.size());
+ assertTrue(mapping.contains(new Long(3)));
+ mapping = ksMapping.get(4);
+ assertEquals(2, mapping.size());
+ assertTrue(mapping.contains(new Long(1)));
+ assertTrue(mapping.contains(new Long(2)));
+
+ /* verify lastIssuedIds are consistent */
+ assertEquals(new Long(3), KeySetUtils.getLastIssuedKeyId(ksms));
+ assertEquals(new Long(4), KeySetUtils.getLastIssuedKeySetId(ksms));
+
+ /* verify packages have been given the appropriat information */
+ PackageSetting ps = packages.get("com.google.app1");
+ assertEquals(1, ps.keySetData.getProperSigningKeySet());
+ ps = packages.get("com.google.app2");
+ assertEquals(1, ps.keySetData.getProperSigningKeySet());
+ assertEquals(new Long(4), ps.keySetData.getAliases().get("AB"));
+ ps = packages.get("com.android.app3");
+ assertEquals(2, ps.keySetData.getProperSigningKeySet());
+ assertEquals(new Long(3), ps.keySetData.getAliases().get("C"));
+ assertEquals(1, ps.keySetData.getUpgradeKeySets().length);
+ assertEquals(3, ps.keySetData.getUpgradeKeySets()[0]);
+ }
+
+ /* make sure our initialized keysetmanagerservice metadata matches packages.xml */
+ public void testReadKeySetSettings()
+ throws ReflectiveOperationException, IllegalAccessException {
+
+ /* write out files and read */
+ writeOldFiles();
+ createUserManagerServiceRef();
+ Settings settings = new Settings(getContext().getFilesDir(), new Object());
+ assertEquals(true, settings.readLPw(null, null, 0, false));
+ verifyKeySetMetaData(settings);
+ }
+
+ /* read in data, write it out, and read it back in. Verify same. */
+ public void testWriteKeySetSettings()
+ throws ReflectiveOperationException, IllegalAccessException {
+
+ /* write out files and read */
+ writeOldFiles();
+ createUserManagerServiceRef();
+ Settings settings = new Settings(getContext().getFilesDir(), new Object());
+ assertEquals(true, settings.readLPw(null, null, 0, false));
+
+ /* write out, read back in and verify the same */
+ settings.writeLPr();
+ assertEquals(true, settings.readLPw(null, null, 0, false));
+ verifyKeySetMetaData(settings);
+ }
+
public void testSettingsReadOld() {
// Write the package files and make sure they're parsed properly the first time
writeOldFiles();
@@ -149,9 +283,11 @@
assertEquals(COMPONENT_ENABLED_STATE_DEFAULT, ps.getEnabled(1));
}
- public void testNewPackageRestrictionsFile() {
+ public void testNewPackageRestrictionsFile() throws ReflectiveOperationException {
+
// Write the package files and make sure they're parsed properly the first time
writeOldFiles();
+ createUserManagerServiceRef();
Settings settings = new Settings(getContext().getFilesDir(), new Object());
assertEquals(true, settings.readLPw(null, null, 0, false));
settings.writeLPr();
diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java
index 93823d1..b5d566a 100644
--- a/telecomm/java/android/telecom/DefaultDialerManager.java
+++ b/telecomm/java/android/telecom/DefaultDialerManager.java
@@ -14,7 +14,6 @@
package android.telecom;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -52,13 +51,12 @@
}
// Only make the change if the new package belongs to a valid phone application
- List<ComponentName> componentNames = getInstalledDialerApplications(context);
- final ComponentName foundComponent = getComponentName(componentNames, packageName);
+ List<String> packageNames = getInstalledDialerApplications(context);
- if (foundComponent != null) {
+ if (packageNames.contains(packageName)) {
// Update the secure setting.
Settings.Secure.putString(context.getContentResolver(),
- Settings.Secure.DIALER_DEFAULT_APPLICATION, foundComponent.getPackageName());
+ Settings.Secure.DIALER_DEFAULT_APPLICATION, packageName);
}
}
@@ -73,29 +71,31 @@
*
* @hide
* */
- public static ComponentName getDefaultDialerApplication(Context context) {
+ public static String getDefaultDialerApplication(Context context) {
String defaultPackageName = Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.DIALER_DEFAULT_APPLICATION);
- final List<ComponentName> componentNames = getInstalledDialerApplications(context);
- if (!TextUtils.isEmpty(defaultPackageName)) {
- final ComponentName defaultDialer =
- getComponentName(componentNames, defaultPackageName);
- if (defaultDialer != null) {
- return defaultDialer;
- }
+
+ final List<String> packageNames = getInstalledDialerApplications(context);
+
+ // Verify that the default dialer has not been disabled or uninstalled.
+ if (packageNames.contains(defaultPackageName)) {
+ return defaultPackageName;
}
// No user-set dialer found, fallback to system dialer
- String systemDialer = getTelecomManager(context).getSystemDialerPackage();
+ String systemDialerPackageName = getTelecomManager(context).getSystemDialerPackage();
- if (TextUtils.isEmpty(systemDialer)) {
+ if (TextUtils.isEmpty(systemDialerPackageName)) {
// No system dialer configured at build time
return null;
}
- // Verify that the system dialer has not been disabled.
- return getComponentName(componentNames, systemDialer);
+ if (packageNames.contains(systemDialerPackageName)) {
+ return systemDialerPackageName;
+ } else {
+ return null;
+ }
}
/**
@@ -109,44 +109,25 @@
*
* @hide
**/
- public static List<ComponentName> getInstalledDialerApplications(Context context) {
+ public static List<String> getInstalledDialerApplications(Context context) {
PackageManager packageManager = context.getPackageManager();
// Get the list of apps registered for the DIAL intent with empty scheme
Intent intent = new Intent(Intent.ACTION_DIAL);
List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
- List<ComponentName> componentNames = new ArrayList<ComponentName> ();
+ List<String> packageNames = new ArrayList<>();
for (ResolveInfo resolveInfo : resolveInfoList) {
final ActivityInfo activityInfo = resolveInfo.activityInfo;
if (activityInfo == null) {
continue;
}
- final ComponentName componentName =
- new ComponentName(activityInfo.packageName, activityInfo.name);
- componentNames.add(componentName);
+ packageNames.add(activityInfo.packageName);
}
// TODO: Filter for apps that don't handle DIAL intent with tel scheme
- return componentNames;
- }
-
- /**
- * Returns the {@link ComponentName} for the installed dialer application for a given package
- * name.
- *
- * @param context A valid context.
- * @param packageName to retrieve the {@link ComponentName} for.
- *
- * @return The {@link ComponentName} for the installed dialer application corresponding to the
- * package name, or null if none is found.
- *
- * @hide
- */
- public static ComponentName getDialerApplicationForPackageName(Context context,
- String packageName) {
- return getComponentName(getInstalledDialerApplications(context), packageName);
+ return packageNames;
}
/**
@@ -170,25 +151,6 @@
|| packageName.equals(tm.getSystemDialerPackage());
}
- /**
- * Returns the component from a list of application components that corresponds to the package
- * name.
- *
- * @param componentNames A list of component names
- * @param packageName The package name to look for
- * @return The {@link ComponentName} that matches the provided packageName, or null if not
- * found.
- */
- private static ComponentName getComponentName(List<ComponentName> componentNames,
- String packageName) {
- for (ComponentName componentName : componentNames) {
- if (TextUtils.equals(packageName, componentName.getPackageName())) {
- return componentName;
- }
- }
- return null;
- }
-
private static TelecomManager getTelecomManager(Context context) {
return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
}