diff options
108 files changed, 2898 insertions, 1281 deletions
diff --git a/api/current.txt b/api/current.txt index 9434419..61f907e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -23,8 +23,10 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android.app.admin { 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 @@ package android.app.admin { 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 @@ package android.app.admin { 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 @@ package android.content.pm { 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 @@ -30433,7 +30441,6 @@ package android.telecom { 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); @@ -30444,6 +30451,7 @@ package android.telecom { 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 { diff --git a/api/system-current.txt b/api/system-current.txt index 6ac12aa..3bbfb8a 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -351,7 +351,7 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android.app.admin { 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 @@ package android.app.admin { 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 @@ package android.app.admin { 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 @@ package android.content.pm { 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 @@ -32550,7 +32556,6 @@ package android.telecom { 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); @@ -32561,6 +32566,7 @@ package android.telecom { 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 { 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 class DevicePolicyManager { 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 @@ public class DevicePolicyManager { 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 @@ interface IDevicePolicyManager { 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/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 @@ public abstract class PackageManager { * 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 @@ public abstract class PackageManager { * {@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 @@ public abstract class PackageManager { * {@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 341fb18..19e821c 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -603,10 +603,9 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri /** * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri /** * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri /** * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri /** * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * </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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * 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> * @@ -1734,12 +1730,13 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * </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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <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 @@ -2707,8 +2704,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <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> - diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index 2d9f61d..ca9439b 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -461,19 +461,17 @@ public abstract class CameraMetadata<TKey> { * <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> @@ -571,26 +569,25 @@ public abstract class CameraMetadata<TKey> { * 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>{@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 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>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> @@ -612,11 +609,13 @@ public abstract class CameraMetadata<TKey> { * <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> @@ -631,13 +630,14 @@ public abstract class CameraMetadata<TKey> { * <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 @@ -711,7 +711,7 @@ public abstract class CameraMetadata<TKey> { /** * <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 @@ -870,7 +870,7 @@ public abstract class CameraMetadata<TKey> { /** * <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 9106060..ab6ce91 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -2040,8 +2040,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * 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 @@ -2050,21 +2050,19 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * <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 @@ -2072,7 +2070,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * 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> diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index 8c8f0dc..3dc8970 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -2886,8 +2886,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * 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 @@ -2896,21 +2896,19 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <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 @@ -2918,7 +2916,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * 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> @@ -2980,11 +2978,10 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * 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> @@ -3142,7 +3139,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <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 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 @@ public class TransitionInflater { sConstructors.put(className, constructor); } } - + constructor.setAccessible(true); return constructor.newInstance(mContext, attrs); } } catch (InstantiationException e) { 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 @@ public class DisplayListCanvas extends Canvas { * 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { 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 5ecda87..fa74797 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2592,7 +2592,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@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; @@ -15540,7 +15540,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, 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 @@ class DayPickerPagerAdapter extends PagerAdapter { 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 @@ class DayPickerView extends ViewGroup { }); } + 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 @@ class DayPickerView extends ViewGroup { 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 @@ class DayPickerView extends ViewGroup { 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 @@ class DayPickerView extends ViewGroup { 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 @@ class DayPickerView extends ViewGroup { @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 @@ public class Editor { 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 @@ public class Editor { } 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 @@ public class Editor { 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 @@ public class Editor { 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 @@ public class Editor { // 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 @@ public class Editor { 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 @@ public class Editor { 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 @@ public class Editor { } // 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 @@ public class Editor { * 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 @@ public class Editor { 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 @@ public class Editor { } 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 @@ public class Editor { 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.TextPaint; 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 @@ class SimpleMonthView extends View { int stateMask = 0; - if (day >= mEnabledDayStart && day <= mEnabledDayEnd) { + final boolean isDayEnabled = isDayEnabled(day); + if (isDayEnabled) { stateMask |= StateSet.VIEW_STATE_ENABLED; } @@ -435,8 +437,11 @@ class SimpleMonthView extends View { } 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 @@ class SimpleMonthView extends View { } } + 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 @@ class SimpleMonthView extends View { 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 @@ class SimpleMonthView extends View { } } + mEnabledDayStart = MathUtils.constrain(enabledDayStart, 1, mDaysInMonth); + mEnabledDayEnd = MathUtils.constrain(enabledDayEnd, mEnabledDayStart, mDaysInMonth); + // Invalidate the old title. mTitle = null; @@ -694,7 +703,7 @@ class SimpleMonthView extends View { 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 @@ class SimpleMonthView extends View { * @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 @@ class SimpleMonthView extends View { * @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 @@ class SimpleMonthView extends View { @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 @@ class SimpleMonthView extends View { 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 @@ class SimpleMonthView extends View { * @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 @@ class SimpleMonthView extends View { * @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 class Switch extends CompoundButton { 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class ChooserActivity extends ResolverActivity { 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/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 @@ public class ImageUtils { 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 @@ public class LockPatternUtils { 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 class LockPatternUtils { 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 @@ public class LockPatternUtils { 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 @@ public class LockPatternUtils { * @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 @@ public class LockPatternUtils { * @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 @@ public class LockPatternUtils { * @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 @@ public class LockPatternUtils { * @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 @@ public class LockPatternUtils { * 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 @@ public class LockPatternUtils { * @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 @@ public class LockPatternUtils { } // 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 @@ public class LockPatternUtils { * * @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 @@ public class LockPatternUtils { return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; } - public void clearLock() { - clearLock(getCurrentOrCallingUserId()); - } - /** * Clear any lock pattern or password. */ @@ -479,16 +414,6 @@ public class LockPatternUtils { } /** - * 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 @@ public class LockPatternUtils { * * @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 @@ public class LockPatternUtils { 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 @@ public class LockPatternUtils { 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 @@ public class LockPatternUtils { /** * 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 @@ public class LockPatternUtils { } /** - * 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 @@ public class LockPatternUtils { } /** - * @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 @@ public class LockPatternUtils { 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 @@ public class LockPatternUtils { /** * @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 @@ public class LockPatternUtils { /** * @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 @@ public class LockPatternUtils { * 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 @@ public class LockPatternUtils { * 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 class LockPatternUtils { } } - public void setPowerButtonInstantlyLocks(boolean enabled) { - setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, getCurrentOrCallingUserId()); - } - - public boolean getPowerButtonInstantlyLocks() { - return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true, - getCurrentOrCallingUserId()); - } - - public void setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents) { - setEnabledTrustAgents(activeTrustAgents, getCurrentOrCallingUserId()); + public void setPowerButtonInstantlyLocks(boolean enabled, int userId) { + setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, userId); } - 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 @@ public class LockPatternUtils { 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 class LockPatternUtils { } 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_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 @@ static void report_exception(JNIEnv* env, jthrowable excep, const char* msg) * 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_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 @@ static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobje 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 jlong android_view_DisplayListCanvas_createDisplayListCanvas(JNIEnv* env, } 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 @@ static JNINativeMethod gMethods[] = { { "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_inverse_when_activated_material.xml index f1b742a..0f7f9cdf 100644 --- a/core/res/res/color/primary_text_activated_material_dark.xml +++ b/core/res/res/color/primary_text_inverse_when_activated_material.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2014 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. @@ -15,7 +15,18 @@ --> <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"/> + <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/primary_text_activated_material_light.xml b/core/res/res/color/secondary_text_inverse_when_activated_material.xml index d92da63..5b259de 100644 --- a/core/res/res/color/primary_text_activated_material_light.xml +++ b/core/res/res/color/secondary_text_inverse_when_activated_material.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2014 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. @@ -15,7 +15,18 @@ --> <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"/> + <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 @@ please see themes_device_defaults.xml. <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 @@ please see themes_device_defaults.xml. <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 @@ please see themes_device_defaults.xml. 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 @@ please see themes_device_defaults.xml. <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 @@ please see themes_device_defaults.xml. <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 @@ public class WifiStressTest extends ConnectivityManagerTestBase { 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 @@ public class WifiStressTest extends ConnectivityManagerTestBase { 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/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 @@ such as sending a message to the wearable to start an activity.</p> <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 @@ class.</p> <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 @@ public class GradientDrawable extends Drawable { 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 @@ public class GradientDrawable extends Drawable { 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 @@ public class GradientDrawable extends Drawable { 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/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 @@ public class ShapeDrawable extends Drawable { 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 @@ public class ShapeDrawable extends Drawable { 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::interrupt() { 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 @@ bool DisplayListCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) { 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 @@ public: // 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 @@ class DrawRenderNodeOp : public DrawBoundedOp { 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 @@ public: } 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 @@ public: 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 @@ class ShadowGridAnimation : public TreeContentAnimation { 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 @@ class RectGridAnimation : public TreeContentAnimation { 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 @@ class OvalAnimation : public TreeContentAnimation { 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 @@ public class EmergencyButton extends Button { KeyguardUpdateMonitor.getInstance(mContext).reportEmergencyCallAction( true /* bypassHandler */); getContext().startActivityAsUser(INTENT_EMERGENCY_DIAL, - new UserHandle(mLockPatternUtils.getCurrentUser())); + new UserHandle(KeyguardUpdateMonitor.getCurrentUser())); } } @@ -138,7 +138,7 @@ public class EmergencyButton extends Button { 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 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout // 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 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout 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 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout 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 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback { @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 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit 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 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit 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 class KeyguardPatternView extends LinearLayout implements KeyguardSecurit } 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 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit 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 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe 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 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0; } monitor.reportFailedUnlockAttempt(); - mLockPatternUtils.reportFailedPasswordAttempt(); + mLockPatternUtils.reportFailedPasswordAttempt(KeyguardUpdateMonitor.getCurrentUser()); if (showTimeout) { showTimeoutDialog(); } @@ -321,7 +321,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe 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 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe 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 @@ public class KeyguardSecurityModel { 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 @@ public class KeyguardStatusView extends GridLayout { 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 1eec532..b8d9053 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -244,6 +244,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { 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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { cb.onScreenTurnedOn(); } } - startListeningForFingerprint(); + updateFingerprintListeningState(); } protected void handleScreenTurnedOff(int arg1) { @@ -681,7 +691,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { cb.onScreenTurnedOff(arg1); } } - stopListeningForFingerprint(); + updateFingerprintListeningState(); } /** @@ -754,14 +764,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { 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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { 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 class KeyguardUpdateMonitor implements TrustManager.TrustListener { } } - public void stopListeningForFingerprint() { + private void stopListeningForFingerprint() { if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()"); if (isFingerprintDetectionRunning()) { mFingerprintCancelSignal.cancel(); @@ -1052,6 +1075,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { 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 @@ class DatabaseHelper extends SQLiteOpenHelper { 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 @@ public class SettingsBackupAgent extends BackupAgentHelper { */ 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 @@ public class SettingsBackupAgent extends BackupAgentHelper { } 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 @@ public class BatteryMeterView extends View implements DemoMode, 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 @@ public class BatteryMeterView extends View implements DemoMode, 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 @@ public class KeyguardViewMediator extends SystemUI { 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 @@ public class KeyguardViewMediator extends SystemUI { // 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 @@ public class KeyguardViewMediator extends SystemUI { // From DevicePolicyAdmin final long policyTimeout = mLockPatternUtils.getDevicePolicyManager() - .getMaximumTimeToLock(null, mLockPatternUtils.getCurrentUser()); + .getMaximumTimeToLock(null, KeyguardUpdateMonitor.getCurrentUser()); long timeout; if (policyTimeout > 0) { @@ -719,7 +722,8 @@ public class KeyguardViewMediator extends SystemUI { } 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 class KeyguardViewMediator extends SystemUI { */ public void onDreamingStarted() { synchronized (this) { - if (mScreenOn && mLockPatternUtils.isSecure()) { + if (mScreenOn && mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) { doKeyguardLaterLocked(); } } @@ -974,12 +978,13 @@ public class KeyguardViewMediator extends SystemUI { 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 class KeyguardViewMediator extends SystemUI { } public boolean isSecure() { - return mLockPatternUtils.isSecure() + return mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser()) || KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure(); } @@ -1083,7 +1088,7 @@ public class KeyguardViewMediator extends SystemUI { * @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 @@ public class KeyguardViewMediator extends SystemUI { 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 @@ public class KeyguardViewMediator extends SystemUI { 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 92bd0df..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.StatusBarIcon; 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 @@ public abstract class BaseStatusBar extends SystemUI implements 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); @@ -783,7 +784,8 @@ public abstract class BaseStatusBar extends SystemUI implements 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) { @@ -808,8 +810,9 @@ public abstract class BaseStatusBar extends SystemUI implements 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 @@ -1133,9 +1136,9 @@ public abstract class BaseStatusBar extends SystemUI implements } /** - * 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. @@ -1336,8 +1339,8 @@ public abstract class BaseStatusBar extends SystemUI implements 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); @@ -1444,9 +1447,7 @@ public abstract class BaseStatusBar extends SystemUI implements 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); @@ -1535,12 +1536,13 @@ public abstract class BaseStatusBar extends SystemUI implements // 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); } } @@ -1882,15 +1884,14 @@ public abstract class BaseStatusBar extends SystemUI implements 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) { @@ -1911,7 +1912,7 @@ public abstract class BaseStatusBar extends SystemUI implements 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); } } @@ -1935,11 +1936,12 @@ public abstract class BaseStatusBar extends SystemUI implements // 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(); } @@ -1950,7 +1952,7 @@ public abstract class BaseStatusBar extends SystemUI implements 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 @@ -1963,7 +1965,8 @@ public abstract class BaseStatusBar extends SystemUI implements } /** - * @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; @@ -1981,15 +1984,15 @@ public abstract class BaseStatusBar extends SystemUI implements 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()) @@ -2021,12 +2024,12 @@ public abstract class BaseStatusBar extends SystemUI implements : 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); } @@ -2049,7 +2052,7 @@ public abstract class BaseStatusBar extends SystemUI implements } 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 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { private ExpansionLogger mLogger; private String mLoggingKey; private boolean mWasReset; - private NotificationGuts mGuts; private StatusBarNotification mStatusBarNotification; private boolean mIsHeadsUp; @@ -102,6 +101,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { 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 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { !mChildrenExpanded); } }; - private boolean mInShade; public NotificationContentView getPrivateLayout() { return mPrivateLayout; @@ -284,12 +283,18 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { 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 android.widget.FrameLayout; 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 @@ public class NotificationContentView extends FrameLayout { return true; } }; - private boolean mIsHeadsUp; public NotificationContentView(Context context, AttributeSet attrs) { super(context, attrs); @@ -105,9 +101,9 @@ public class NotificationContentView extends FrameLayout { // 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 @@ public class NotificationContentView extends FrameLayout { mContractedChild = null; mExpandedChild = null; mHeadsUpChild = null; - mVisibleView = CONTRACTED; + mVisibleType = VISIBLE_TYPE_CONTRACTED; if (resetActualHeight) { mContentHeight = mSmallHeight; } @@ -263,30 +259,32 @@ public class NotificationContentView extends FrameLayout { 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 @@ public class NotificationContentView extends FrameLayout { 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 @@ public class NotificationContentView extends FrameLayout { .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 class NotificationData { 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 @@ public class NotificationData { 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 class NotificationData { 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 class NotificationData { */ 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.policy.HeadsUpManager; 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 @@ public class HeadsUpTouchHelper implements Gefingerpoken { 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 @@ public class HeadsUpTouchHelper implements Gefingerpoken { 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 @@ public class HeadsUpTouchHelper implements Gefingerpoken { 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 @@ public class HeadsUpTouchHelper implements Gefingerpoken { 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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private KeyguardAffordanceView mCameraImageView; private KeyguardAffordanceView mPhoneImageView; - private KeyguardAffordanceView mLockIcon; + private LockIcon mLockIcon; private TextView mIndicationText; private ViewGroup mPreviewContainer; @@ -102,11 +102,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL 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 class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL 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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL 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 class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL public void setAccessibilityController(AccessibilityController accessibilityController) { mAccessibilityController = accessibilityController; + mLockIcon.setAccessibilityController(accessibilityController); accessibilityController.addStateChangedCallback(this); } @@ -233,9 +229,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL 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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL } 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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL 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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL 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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL 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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL 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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL @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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL @Override public void onUnlockMethodStateChanged() { - updateLockIcon(); + mLockIcon.update(); updateCameraVisibility(); } @@ -563,9 +488,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private final Runnable mTransientFpErrorClearRunnable = new Runnable() { @Override public void run() { - mTransientFpError = false; + mLockIcon.setTransientFpError(false); mIndicationController.hideTransientIndication(); - updateLockIcon(); } }; @@ -578,17 +502,17 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL @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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL @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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL 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 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements } @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 @@ public class NotificationPanelView extends PanelView implements mOnlyAffordanceInThisMotion = false; mQsTouchAboveFalsingThreshold = mQsFullyExpanded; mDozingOnDown = isDozing(); + mCollapsedOnDown = isFullyCollapsed(); } } @@ -695,7 +695,7 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements mInitialTouchY = event.getX(); mInitialTouchX = event.getY(); } - if (!isShadeCollapsed()) { + if (!isFullyCollapsed()) { handleQsDown(event); } if (!mQsExpandImmediate && mQsTracking) { @@ -731,7 +731,7 @@ public class NotificationPanelView extends PanelView implements || 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 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements * @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 @@ public class NotificationPanelView extends PanelView implements updateHeader(); updateUnlockIcon(); updateNotificationTranslucency(); - mHeadsUpManager.setIsExpanded(!isShadeCollapsed()); - mNotificationStackScroller.setShadeExpanded(!isShadeCollapsed()); + mHeadsUpManager.setIsExpanded(!isFullyCollapsed()); + mNotificationStackScroller.setShadeExpanded(!isFullyCollapsed()); if (DEBUG) { invalidate(); } @@ -1535,21 +1535,19 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements } 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 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements @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 @@ public class NotificationPanelView extends PanelView implements } @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) { - mNotificationStackScroller.generateHeadsUpAnimation(entry.row, isHeadsUp); + public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) { } @Override - protected boolean isShadeCollapsed() { - return mExpandedHeight == 0; + public void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) { + mNotificationStackScroller.generateHeadsUpAnimation(entry.row, isHeadsUp); } @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 4452dd7..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 @@ import java.io.PrintWriter; 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 @@ public abstract class PanelView extends FrameLayout { 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 @@ public abstract class PanelView extends FrameLayout { || mPeekPending || mPeekAnimator != null; onTrackingStarted(); } - if (isShadeCollapsed()) { + if (isFullyCollapsed()) { schedulePeek(); } break; @@ -472,7 +472,7 @@ public abstract class PanelView extends FrameLayout { mTouchSlopExceeded = false; mJustPeeked = false; mMotionAborted = false; - mPanelClosedOnDown = isShadeCollapsed(); + mPanelClosedOnDown = isFullyCollapsed(); mHasLayoutedSinceDown = false; mUpdateFlingOnLayout = false; mTouchAboveFalsingThreshold = false; @@ -707,7 +707,7 @@ public abstract class PanelView extends FrameLayout { // 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 @@ public abstract class PanelView extends FrameLayout { */ 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 bf85ed5..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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, @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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } }; - 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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override - public void escalateHeadsUp() { + public void maybeEscalateHeadsUp() { TreeSet<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getSortedEntries(); for (HeadsUpManager.HeadsUpEntry entry : entries) { final StatusBarNotification sbn = entry.entry.notification; 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 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, 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 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, } @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 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, 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 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, 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 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, } } + /** + * 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 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, } 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.provider.MediaStore; 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 @@ public class SecureCameraLaunchManager { // 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 @@ public class SecureCameraLaunchManager { // 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 @@ public class UnlockMethodCache { } 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 com.android.systemui.statusbar.phone.PhoneStatusBar; 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL @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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL if (alert) { HeadsUpEntry headsUpEntry = mHeadsUpEntries.get(headsUp.key); headsUpEntry.updateEntry(); - setEntryToShade(headsUpEntry, mIsExpanded, false /* justAdded */, false); + setEntryPinned(headsUpEntry, !mIsExpanded /* isPinned */); } } @@ -165,22 +167,23 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL releaseImmediately(key); return true; } else { - getHeadsUpEntry(key).hideAsSoonAsPossible(); + getHeadsUpEntry(key).removeAsSoonAsPossible(); return false; } } @@ -245,14 +247,13 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL } 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL } /** + * 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 class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL } 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 class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL } 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL if (isExpanded != mIsExpanded) { mIsExpanded = isExpanded; if (isExpanded) { - releaseAllToShade(); + unpinAll(); } } } @@ -430,6 +428,12 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL : -1; } - public void removeAutoCancelCallbacks() { + public void removeAutoRemovalCallbacks() { mHandler.removeCallbacks(mRemoveHeadsUpRunnable); } @@ -495,11 +504,17 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL 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 class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL } 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.LayoutInflater; 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 @@ public class PreviewInflater { 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 @@ public class NotificationStackScrollLayout extends ViewGroup private ViewGroup mScrollView; private boolean mInterceptDelegateEnabled; private boolean mDelegateToScrollView; - private boolean mDisallowScrollingInThisMotion; private long mGoToFullShadeDelay; private ViewTreeObserver.OnPreDrawListener mChildrenUpdater @@ -487,9 +486,9 @@ public class NotificationStackScrollLayout extends ViewGroup 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 @@ public class NotificationStackScrollLayout extends ViewGroup 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 @@ public class NotificationStackScrollLayout extends ViewGroup 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 @@ public class NotificationStackScrollLayout extends ViewGroup 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 @@ public class NotificationStackScrollLayout extends ViewGroup } handleEmptySpaceClick(ev); boolean expandWantsIt = false; - if (!mSwipingInProgress && !mOnlyScrollingInThisMotion && isScrollingEnabled()) { + if (mIsExpanded && !mSwipingInProgress && !mOnlyScrollingInThisMotion + && isScrollingEnabled()) { if (isCancelOrUp) { mExpandHelper.onlyObserveMovements(false); } @@ -824,7 +824,8 @@ public class NotificationStackScrollLayout extends ViewGroup } } boolean scrollerWantsIt = false; - if (!mSwipingInProgress && !mExpandingNotification && !mDisallowScrollingInThisMotion) { + if (mIsExpanded && !mSwipingInProgress && !mExpandingNotification + && !mDisallowScrollingInThisMotion) { scrollerWantsIt = onScrollTouch(ev); } boolean horizontalSwipeWantsIt = false; @@ -1872,15 +1873,15 @@ public class NotificationStackScrollLayout extends ViewGroup 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 class NotificationStackScrollLayout extends ViewGroup } } - 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 @@ public class StackScrollAlgorithm { 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 @@ public class StackScrollAlgorithm { } } - 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 @@ public class StackScrollAlgorithm { /** * 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 @@ public class StackScrollAlgorithm { } 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.AnimatorListenerAdapter; 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 @@ public class StackStateAnimator { 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 @@ public class StackStateAnimator { private ValueAnimator mTopOverScrollAnimator; private ValueAnimator mBottomOverScrollAnimator; private ExpandableNotificationRow mChildExpandingView; - private StackViewState mTmpState = new StackViewState(); private int mHeadsUpAppearHeightBottom; private boolean mShadeExpanded; @@ -106,25 +104,7 @@ public class StackStateAnimator { 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 @@ public class TvStatusBar extends BaseStatusBar { } @Override - public void escalateHeadsUp() { + public void maybeEscalateHeadsUp() { } @Override 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 @@ class MountService extends IMountService.Stub 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/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.Cursor; 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 com.google.android.collect.Sets; 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService + 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService } 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 @@ public class AccountManagerService } } db.setTransactionSuccessful(); + + logRecord(db, DebugDbHelper.ACTION_ACCOUNT_ADD, TABLE_ACCOUNTS, accountId, + accounts, callingUid); + insertAccountIntoCacheLocked(accounts, account); } finally { db.endTransaction(); @@ -983,9 +1003,12 @@ public class AccountManagerService 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 @@ public class AccountManagerService } 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService } } + logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE, TABLE_ACCOUNTS); + try { new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind(); } finally { @@ -1188,6 +1215,8 @@ public class AccountManagerService } } + logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE, TABLE_ACCOUNTS); + try { new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind(); } finally { @@ -1210,6 +1239,9 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService @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 @@ public class AccountManagerService + ", skipping the DB insert failed"); return false; } + logRecord(db, DebugDbHelper.ACTION_ACCOUNT_ADD, TABLE_SHARED_ACCOUNTS, accountId, accounts); return true; } @@ -2340,6 +2391,7 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService } } + 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService createSharedAccountsTable(db); createAccountsDeletionTrigger(db); + + DebugDbHelper.createDebugTable(db); } private void createSharedAccountsTable(SQLiteDatabase db) { @@ -2968,6 +3169,10 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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/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 @@ public class JobServiceContext extends IJobCallback.Stub implements ServiceConne 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/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_VERIFICATIO 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 @@ public class PackageManagerService extends IPackageManager.Stub { } 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 @@ public class PackageManagerService extends IPackageManager.Stub { } } } - if (allHosts.size() > 0) { + if (allHosts.size() == 0) { allHosts.add("*"); } IntentFilterVerificationInfo ivi = @@ -3939,7 +3947,7 @@ public class PackageManagerService extends IPackageManager.Stub { } result = filterIfNotPrimaryUser(result, userId); if (result.size() > 1 && hasWebURI(intent)) { - return filterCandidatesWithDomainPreferedActivitiesLPr(result); + return filterCandidatesWithDomainPreferedActivitiesLPr(flags, result); } return result; } @@ -3984,7 +3992,7 @@ public class PackageManagerService extends IPackageManager.Stub { } 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { } 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { 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 class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { } public boolean isSecure() { - return mLockPatternUtils.isSecure() || mSimSecure; + return mLockPatternUtils.isSecure(getCurrentUser()) || mSimSecure; } public boolean isInputRestricted() { @@ -75,8 +77,12 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { 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/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 @@ class Watermark { 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 d7542ee..d4b3dab 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -9940,18 +9940,20 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ -9960,7 +9962,7 @@ public class WindowManagerService extends IWindowManager.Stub } 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 c50974c..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.FIRST_SUB_WINDOW; 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 @@ final class WindowState implements WindowManagerPolicy.WindowState { } /** - * 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) { 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } + + @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.ArraySet; 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { "", 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { /* 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { /* 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { } 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { /* 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { /* 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 @@ public class KeySetManagerServiceTest extends AndroidTestCase { 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 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 @@ public class PackageManagerSettingsTests extends AndroidTestCase { + "</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 @@ public class PackageManagerSettingsTests extends AndroidTestCase { + "<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 @@ public class PackageManagerSettingsTests extends AndroidTestCase { 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 @@ public class PackageManagerSettingsTests extends AndroidTestCase { 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(); |
