diff options
349 files changed, 5561 insertions, 4291 deletions
diff --git a/Android.mk b/Android.mk index 4a97c28fadaf..b41923173f5a 100644 --- a/Android.mk +++ b/Android.mk @@ -350,8 +350,8 @@ LOCAL_SRC_FILES += \ media/java/android/media/tv/ITvInputServiceCallback.aidl \ media/java/android/media/tv/ITvInputSession.aidl \ media/java/android/media/tv/ITvInputSessionCallback.aidl \ - telecomm/java/com/android/internal/telecomm/IVideoCallCallback.aidl \ - telecomm/java/com/android/internal/telecomm/IVideoCallProvider.aidl \ + telecomm/java/com/android/internal/telecomm/IVideoCallback.aidl \ + telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl \ telecomm/java/com/android/internal/telecomm/IConnectionService.aidl \ telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl \ telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl \ diff --git a/api/current.txt b/api/current.txt index de305b6cbded..584246ba6d95 100644 --- a/api/current.txt +++ b/api/current.txt @@ -114,7 +114,6 @@ package android { field public static final java.lang.String RECEIVE_SMS = "android.permission.RECEIVE_SMS"; field public static final java.lang.String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH"; field public static final java.lang.String RECORD_AUDIO = "android.permission.RECORD_AUDIO"; - field public static final java.lang.String RECOVERY = "android.permission.RECOVERY"; field public static final java.lang.String REORDER_TASKS = "android.permission.REORDER_TASKS"; field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES"; field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE"; @@ -272,14 +271,14 @@ package android { field public static final int action = 16842797; // 0x101002d field public static final int actionBarDivider = 16843675; // 0x101039b field public static final int actionBarItemBackground = 16843676; // 0x101039c - field public static final int actionBarPopupTheme = 16843919; // 0x101048f + field public static final int actionBarPopupTheme = 16843917; // 0x101048d field public static final int actionBarSize = 16843499; // 0x10102eb field public static final int actionBarSplitStyle = 16843656; // 0x1010388 field public static final int actionBarStyle = 16843470; // 0x10102ce field public static final int actionBarTabBarStyle = 16843508; // 0x10102f4 field public static final int actionBarTabStyle = 16843507; // 0x10102f3 field public static final int actionBarTabTextStyle = 16843509; // 0x10102f5 - field public static final int actionBarTheme = 16843827; // 0x1010433 + field public static final int actionBarTheme = 16843825; // 0x1010431 field public static final int actionBarWidgetTheme = 16843671; // 0x1010397 field public static final int actionButtonStyle = 16843480; // 0x10102d8 field public static final int actionDropDownStyle = 16843479; // 0x10102d7 @@ -291,15 +290,15 @@ package android { field public static final int actionModeCloseDrawable = 16843484; // 0x10102dc field public static final int actionModeCopyDrawable = 16843538; // 0x1010312 field public static final int actionModeCutDrawable = 16843537; // 0x1010311 - field public static final int actionModeFindDrawable = 16843900; // 0x101047c + field public static final int actionModeFindDrawable = 16843898; // 0x101047a field public static final int actionModePasteDrawable = 16843539; // 0x1010313 field public static final int actionModeSelectAllDrawable = 16843646; // 0x101037e - field public static final int actionModeShareDrawable = 16843899; // 0x101047b + field public static final int actionModeShareDrawable = 16843897; // 0x1010479 field public static final int actionModeSplitBackground = 16843677; // 0x101039d field public static final int actionModeStyle = 16843668; // 0x1010394 - field public static final int actionModeWebSearchDrawable = 16843901; // 0x101047d + field public static final int actionModeWebSearchDrawable = 16843899; // 0x101047b field public static final int actionOverflowButtonStyle = 16843510; // 0x10102f6 - field public static final int actionOverflowMenuStyle = 16843846; // 0x1010446 + field public static final int actionOverflowMenuStyle = 16843844; // 0x1010444 field public static final int actionProviderClass = 16843657; // 0x1010389 field public static final int actionViewClass = 16843516; // 0x10102fc field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd @@ -326,8 +325,8 @@ package android { field public static final int alphabeticShortcut = 16843235; // 0x10101e3 field public static final int alwaysDrawnWithCache = 16842991; // 0x10100ef field public static final int alwaysRetainTaskState = 16843267; // 0x1010203 - field public static final int amPmBackgroundColor = 16843944; // 0x10104a8 - field public static final int amPmTextColor = 16843943; // 0x10104a7 + field public static final int amPmBackgroundColor = 16843942; // 0x10104a6 + field public static final int amPmTextColor = 16843941; // 0x10104a5 field public static final int angle = 16843168; // 0x10101a0 field public static final int animateFirstView = 16843477; // 0x10102d5 field public static final int animateLayoutChanges = 16843506; // 0x10102f2 @@ -347,7 +346,7 @@ package android { field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b field public static final int autoLink = 16842928; // 0x10100b0 field public static final int autoMirrored = 16843754; // 0x10103ea - field public static final int autoRemoveFromRecents = 16843849; // 0x1010449 + field public static final int autoRemoveFromRecents = 16843847; // 0x1010447 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 @@ -356,8 +355,8 @@ package android { field public static final int backgroundDimEnabled = 16843295; // 0x101021f field public static final int backgroundSplit = 16843659; // 0x101038b field public static final int backgroundStacked = 16843658; // 0x101038a - field public static final int backgroundTint = 16843885; // 0x101046d - field public static final int backgroundTintMode = 16843886; // 0x101046e + field public static final int backgroundTint = 16843883; // 0x101046b + field public static final int backgroundTintMode = 16843884; // 0x101046c field public static final int backupAgent = 16843391; // 0x101027f field public static final int banner = 16843762; // 0x10103f2 field public static final int baseline = 16843548; // 0x101031c @@ -377,18 +376,18 @@ package android { field public static final int bufferType = 16843086; // 0x101014e field public static final int button = 16843015; // 0x1010107 field public static final int buttonBarButtonStyle = 16843567; // 0x101032f - field public static final int buttonBarNegativeButtonStyle = 16843917; // 0x101048d - field public static final int buttonBarNeutralButtonStyle = 16843916; // 0x101048c - field public static final int buttonBarPositiveButtonStyle = 16843915; // 0x101048b + field public static final int buttonBarNegativeButtonStyle = 16843915; // 0x101048b + field public static final int buttonBarNeutralButtonStyle = 16843914; // 0x101048a + field public static final int buttonBarPositiveButtonStyle = 16843913; // 0x1010489 field public static final int buttonBarStyle = 16843566; // 0x101032e field public static final int buttonStyle = 16842824; // 0x1010048 field public static final int buttonStyleInset = 16842826; // 0x101004a field public static final int buttonStyleSmall = 16842825; // 0x1010049 field public static final int buttonStyleToggle = 16842827; // 0x101004b - field public static final int buttonTint = 16843889; // 0x1010471 - field public static final int buttonTintMode = 16843890; // 0x1010472 + field public static final int buttonTint = 16843887; // 0x101046f + field public static final int buttonTintMode = 16843888; // 0x1010470 field public static final int cacheColorHint = 16843009; // 0x1010101 - field public static final int calendarTextColor = 16843933; // 0x101049d + field public static final int calendarTextColor = 16843931; // 0x101049b field public static final int calendarViewShown = 16843596; // 0x101034c field public static final int calendarViewStyle = 16843613; // 0x101035d field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8 @@ -406,8 +405,8 @@ package android { field public static final int centerY = 16843171; // 0x10101a3 field public static final int checkBoxPreferenceStyle = 16842895; // 0x101008f field public static final int checkMark = 16843016; // 0x1010108 - field public static final int checkMarkTint = 16843946; // 0x10104aa - field public static final int checkMarkTintMode = 16843947; // 0x10104ab + field public static final int checkMarkTint = 16843944; // 0x10104a8 + field public static final int checkMarkTintMode = 16843945; // 0x10104a9 field public static final int checkable = 16843237; // 0x10101e5 field public static final int checkableBehavior = 16843232; // 0x10101e0 field public static final int checkboxStyle = 16842860; // 0x101006c @@ -426,31 +425,31 @@ package android { field public static final int clipChildren = 16842986; // 0x10100ea field public static final int clipOrientation = 16843274; // 0x101020a field public static final int clipToPadding = 16842987; // 0x10100eb - field public static final int closeIcon = 16843907; // 0x1010483 + field public static final int closeIcon = 16843905; // 0x1010481 field public static final int codes = 16843330; // 0x1010242 field public static final int collapseColumns = 16843083; // 0x101014b field public static final int color = 16843173; // 0x10101a5 - field public static final int colorAccent = 16843831; // 0x1010437 + field public static final int colorAccent = 16843829; // 0x1010435 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 colorButtonNormal = 16843821; // 0x101042d - field public static final int colorControlActivated = 16843820; // 0x101042c - field public static final int colorControlHighlight = 16843822; // 0x101042e - field public static final int colorControlNormal = 16843819; // 0x101042b + field public static final int colorButtonNormal = 16843819; // 0x101042b + field public static final int colorControlActivated = 16843818; // 0x101042a + field public static final int colorControlHighlight = 16843820; // 0x101042c + field public static final int colorControlNormal = 16843817; // 0x1010429 field public static final int colorFocusedHighlight = 16843663; // 0x101038f field public static final int colorForeground = 16842800; // 0x1010030 field public static final int colorForegroundInverse = 16843270; // 0x1010206 field public static final int colorLongPressedHighlight = 16843662; // 0x101038e field public static final int colorMultiSelectHighlight = 16843665; // 0x1010391 field public static final int colorPressedHighlight = 16843661; // 0x101038d - field public static final int colorPrimary = 16843829; // 0x1010435 - field public static final int colorPrimaryDark = 16843830; // 0x1010436 + field public static final int colorPrimary = 16843827; // 0x1010433 + field public static final int colorPrimaryDark = 16843828; // 0x1010434 field public static final int columnCount = 16843639; // 0x1010377 field public static final int columnDelay = 16843215; // 0x10101cf field public static final int columnOrderPreserved = 16843640; // 0x1010378 field public static final int columnWidth = 16843031; // 0x1010117 - field public static final int commitIcon = 16843911; // 0x1010487 + field public static final int commitIcon = 16843909; // 0x1010485 field public static final int compatibleWidthLimitDp = 16843621; // 0x1010365 field public static final int completionHint = 16843122; // 0x1010172 field public static final int completionHintView = 16843123; // 0x1010173 @@ -461,11 +460,10 @@ package android { field public static final int content = 16843355; // 0x101025b field public static final int contentAuthority = 16843408; // 0x1010290 field public static final int contentDescription = 16843379; // 0x1010273 - field public static final int contentInsetEnd = 16843862; // 0x1010456 - field public static final int contentInsetLeft = 16843863; // 0x1010457 - field public static final int contentInsetRight = 16843864; // 0x1010458 - field public static final int contentInsetStart = 16843861; // 0x1010455 - field public static final int contentRatingSystemXml = 16843957; // 0x10104b5 + field public static final int contentInsetEnd = 16843860; // 0x1010454 + field public static final int contentInsetLeft = 16843861; // 0x1010455 + field public static final int contentInsetRight = 16843862; // 0x1010456 + field public static final int contentInsetStart = 16843859; // 0x1010453 field public static final int controlX1 = 16843798; // 0x1010416 field public static final int controlX2 = 16843800; // 0x1010418 field public static final int controlY1 = 16843799; // 0x1010417 @@ -478,12 +476,12 @@ package android { field public static final int dashGap = 16843175; // 0x10101a7 field public static final int dashWidth = 16843174; // 0x10101a6 field public static final int data = 16842798; // 0x101002e - field public static final int datePickerDialogTheme = 16843951; // 0x10104af - field public static final int datePickerMode = 16843958; // 0x10104b6 + field public static final int datePickerDialogTheme = 16843949; // 0x10104ad + field public static final int datePickerMode = 16843956; // 0x10104b4 field public static final int datePickerStyle = 16843612; // 0x101035c field public static final int dateTextAppearance = 16843593; // 0x1010349 - field public static final int dayOfWeekBackgroundColor = 16843926; // 0x1010496 - field public static final int dayOfWeekTextAppearance = 16843927; // 0x1010497 + field public static final int dayOfWeekBackgroundColor = 16843924; // 0x1010494 + field public static final int dayOfWeekTextAppearance = 16843925; // 0x1010495 field public static final int debuggable = 16842767; // 0x101000f field public static final int defaultValue = 16843245; // 0x10101ed field public static final int delay = 16843212; // 0x10101cc @@ -514,7 +512,7 @@ package android { field public static final int dividerHorizontal = 16843564; // 0x101032c field public static final int dividerPadding = 16843562; // 0x101032a field public static final int dividerVertical = 16843530; // 0x101030a - field public static final int documentLaunchMode = 16843847; // 0x1010447 + field public static final int documentLaunchMode = 16843845; // 0x1010445 field public static final int drawSelectorOnTop = 16843004; // 0x10100fc field public static final int drawable = 16843161; // 0x1010199 field public static final int drawableBottom = 16843118; // 0x101016e @@ -543,8 +541,8 @@ package android { field public static final int editTextStyle = 16842862; // 0x101006e field public static final deprecated int editable = 16843115; // 0x101016b field public static final int editorExtras = 16843300; // 0x1010224 - field public static final int elegantTextHeight = 16843871; // 0x101045f - field public static final int elevation = 16843842; // 0x1010442 + field public static final int elegantTextHeight = 16843869; // 0x101045d + field public static final int elevation = 16843840; // 0x1010440 field public static final int ellipsize = 16842923; // 0x10100ab field public static final int ems = 16843096; // 0x1010158 field public static final int enabled = 16842766; // 0x101000e @@ -554,10 +552,10 @@ package android { field public static final int entries = 16842930; // 0x10100b2 field public static final int entryValues = 16843256; // 0x10101f8 field public static final int eventsInterceptionEnabled = 16843389; // 0x101027d - field public static final int excludeClass = 16843844; // 0x1010444 + field public static final int excludeClass = 16843842; // 0x1010442 field public static final int excludeFromRecents = 16842775; // 0x1010017 - field public static final int excludeId = 16843843; // 0x1010443 - field public static final int excludeName = 16843856; // 0x1010450 + field public static final int excludeId = 16843841; // 0x1010441 + field public static final int excludeName = 16843854; // 0x101044e field public static final int exitFadeDuration = 16843533; // 0x101030d field public static final int expandableListPreferredChildIndicatorLeft = 16842834; // 0x1010052 field public static final int expandableListPreferredChildIndicatorRight = 16842835; // 0x1010053 @@ -588,7 +586,7 @@ package android { field public static final int fastScrollTrackDrawable = 16843577; // 0x1010339 field public static final int fillAfter = 16843197; // 0x10101bd field public static final int fillBefore = 16843196; // 0x10101bc - field public static final int fillColor = 16843807; // 0x101041f + field public static final int fillColor = 16843806; // 0x101041e field public static final int fillEnabled = 16843343; // 0x101024f field public static final int fillViewport = 16843130; // 0x101017a field public static final int filter = 16843035; // 0x101011b @@ -602,12 +600,12 @@ package android { field public static final int focusableInTouchMode = 16842971; // 0x10100db field public static final int focusedMonthDateColor = 16843587; // 0x1010343 field public static final int fontFamily = 16843692; // 0x10103ac - field public static final int fontFeatureSettings = 16843962; // 0x10104ba + field public static final int fontFeatureSettings = 16843960; // 0x10104b8 field public static final int footerDividersEnabled = 16843311; // 0x101022f field public static final int foreground = 16843017; // 0x1010109 field public static final int foregroundGravity = 16843264; // 0x1010200 - field public static final int foregroundTint = 16843887; // 0x101046f - field public static final int foregroundTintMode = 16843888; // 0x1010470 + field public static final int foregroundTint = 16843885; // 0x101046d + field public static final int foregroundTintMode = 16843886; // 0x101046e field public static final int format = 16843013; // 0x1010105 field public static final int format12Hour = 16843722; // 0x10103ca field public static final int format24Hour = 16843723; // 0x10103cb @@ -621,13 +619,13 @@ package android { field public static final int freezesText = 16843116; // 0x101016c field public static final int fromAlpha = 16843210; // 0x10101ca field public static final int fromDegrees = 16843187; // 0x10101b3 - field public static final int fromId = 16843852; // 0x101044c + field public static final int fromId = 16843850; // 0x101044a field public static final int fromScene = 16843741; // 0x10103dd field public static final int fromXDelta = 16843206; // 0x10101c6 field public static final int fromXScale = 16843202; // 0x10101c2 field public static final int fromYDelta = 16843208; // 0x10101c8 field public static final int fromYScale = 16843204; // 0x10101c4 - field public static final int fullBackupOnly = 16843893; // 0x1010475 + field public static final int fullBackupOnly = 16843891; // 0x1010473 field public static final int fullBright = 16842954; // 0x10100ca field public static final int fullDark = 16842950; // 0x10100c6 field public static final int functionalTest = 16842787; // 0x1010023 @@ -640,7 +638,7 @@ package android { field public static final int gestureStrokeType = 16843385; // 0x1010279 field public static final int gestureStrokeWidth = 16843380; // 0x1010274 field public static final int glEsVersion = 16843393; // 0x1010281 - field public static final int goIcon = 16843908; // 0x1010484 + field public static final int goIcon = 16843906; // 0x1010482 field public static final int gradientRadius = 16843172; // 0x10101a4 field public static final int grantUriPermissions = 16842779; // 0x101001b field public static final int gravity = 16842927; // 0x10100af @@ -653,16 +651,16 @@ package android { field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e field public static final int hardwareAccelerated = 16843475; // 0x10102d3 field public static final int hasCode = 16842764; // 0x101000c - field public static final int headerAmPmTextAppearance = 16843938; // 0x10104a2 + field public static final int headerAmPmTextAppearance = 16843936; // 0x10104a0 field public static final int headerBackground = 16843055; // 0x101012f - field public static final int headerBackgroundColor = 16843939; // 0x10104a3 - field public static final int headerDayOfMonthTextAppearance = 16843929; // 0x1010499 + field public static final int headerBackgroundColor = 16843937; // 0x10104a1 + field public static final int headerDayOfMonthTextAppearance = 16843927; // 0x1010497 field public static final int headerDividersEnabled = 16843310; // 0x101022e - field public static final int headerMonthTextAppearance = 16843928; // 0x1010498 - field public static final int headerTimeTextAppearance = 16843937; // 0x10104a1 - field public static final int headerYearTextAppearance = 16843930; // 0x101049a + field public static final int headerMonthTextAppearance = 16843926; // 0x1010496 + field public static final int headerTimeTextAppearance = 16843935; // 0x101049f + field public static final int headerYearTextAppearance = 16843928; // 0x1010498 field public static final int height = 16843093; // 0x1010155 - field public static final int hideOnContentScroll = 16843845; // 0x1010445 + field public static final int hideOnContentScroll = 16843843; // 0x1010443 field public static final int hint = 16843088; // 0x1010150 field public static final int homeAsUpIndicator = 16843531; // 0x101030b field public static final int homeLayout = 16843549; // 0x101031d @@ -698,8 +696,8 @@ package android { field public static final int indeterminateDuration = 16843069; // 0x101013d field public static final int indeterminateOnly = 16843066; // 0x101013a field public static final int indeterminateProgressStyle = 16843544; // 0x1010318 - field public static final int indeterminateTint = 16843883; // 0x101046b - field public static final int indeterminateTintMode = 16843884; // 0x101046c + field public static final int indeterminateTint = 16843881; // 0x1010469 + field public static final int indeterminateTintMode = 16843882; // 0x101046a field public static final int indicatorEnd = 16843730; // 0x10103d2 field public static final int indicatorLeft = 16843021; // 0x101010d field public static final int indicatorRight = 16843022; // 0x101010e @@ -712,7 +710,7 @@ package android { field public static final int innerRadiusRatio = 16843163; // 0x101019b field public static final deprecated int inputMethod = 16843112; // 0x1010168 field public static final int inputType = 16843296; // 0x1010220 - field public static final int inset = 16843960; // 0x10104b8 + field public static final int inset = 16843958; // 0x10104b6 field public static final int insetBottom = 16843194; // 0x10101ba field public static final int insetLeft = 16843191; // 0x10101b7 field public static final int insetRight = 16843192; // 0x10101b8 @@ -786,8 +784,8 @@ package android { field public static final int largeScreens = 16843398; // 0x1010286 field public static final int largestWidthLimitDp = 16843622; // 0x1010366 field public static final int launchMode = 16842781; // 0x101001d - field public static final int launchTaskBehindBackgroundAnimation = 16843923; // 0x1010493 - field public static final int launchTaskBehindSourceAnimation = 16843924; // 0x1010494 + field public static final int launchTaskBehindBackgroundAnimation = 16843921; // 0x1010491 + field public static final int launchTaskBehindSourceAnimation = 16843922; // 0x1010492 field public static final int layerType = 16843604; // 0x1010354 field public static final int layout = 16842994; // 0x10100f2 field public static final int layoutAnimation = 16842988; // 0x10100ec @@ -814,7 +812,7 @@ package android { field public static final int layout_centerVertical = 16843153; // 0x1010191 field public static final int layout_column = 16843084; // 0x101014c field public static final int layout_columnSpan = 16843645; // 0x101037d - field public static final int layout_columnWeight = 16843867; // 0x101045b + field public static final int layout_columnWeight = 16843865; // 0x1010459 field public static final int layout_gravity = 16842931; // 0x10100b3 field public static final int layout_height = 16842997; // 0x10100f5 field public static final int layout_margin = 16842998; // 0x10100f6 @@ -826,7 +824,7 @@ package android { field public static final int layout_marginTop = 16843000; // 0x10100f8 field public static final int layout_row = 16843643; // 0x101037b field public static final int layout_rowSpan = 16843644; // 0x101037c - field public static final int layout_rowWeight = 16843866; // 0x101045a + field public static final int layout_rowWeight = 16843864; // 0x1010458 field public static final int layout_scale = 16843155; // 0x1010193 field public static final int layout_span = 16843085; // 0x101014d field public static final int layout_toEndOf = 16843704; // 0x10103b8 @@ -838,7 +836,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 letterSpacing = 16843961; // 0x10104b9 + field public static final int letterSpacing = 16843959; // 0x10104b7 field public static final int lineSpacingExtra = 16843287; // 0x1010217 field public static final int lineSpacingMultiplier = 16843288; // 0x1010218 field public static final int lines = 16843092; // 0x1010154 @@ -866,7 +864,7 @@ package android { field public static final int manageSpaceActivity = 16842756; // 0x1010004 field public static final int mapViewStyle = 16842890; // 0x101008a field public static final int marqueeRepeatLimit = 16843293; // 0x101021d - field public static final int matchOrder = 16843857; // 0x1010451 + field public static final int matchOrder = 16843855; // 0x101044f field public static final int max = 16843062; // 0x1010136 field public static final int maxDate = 16843584; // 0x1010340 field public static final int maxEms = 16843095; // 0x1010157 @@ -875,11 +873,11 @@ package android { field public static final int maxLength = 16843104; // 0x1010160 field public static final int maxLevel = 16843186; // 0x10101b2 field public static final int maxLines = 16843091; // 0x1010153 - field public static final int maxRecents = 16843848; // 0x1010448 + field public static final int maxRecents = 16843846; // 0x1010446 field public static final int maxRows = 16843059; // 0x1010133 field public static final int maxSdkVersion = 16843377; // 0x1010271 field public static final int maxWidth = 16843039; // 0x101011f - field public static final int maximumAngle = 16843905; // 0x1010481 + field public static final int maximumAngle = 16843903; // 0x101047f field public static final int measureAllChildren = 16843018; // 0x101010a field public static final int measureWithLargestChild = 16843476; // 0x10102d4 field public static final int mediaRouteButtonStyle = 16843693; // 0x10103ad @@ -895,19 +893,19 @@ package android { field public static final int minResizeWidth = 16843669; // 0x1010395 field public static final int minSdkVersion = 16843276; // 0x101020c field public static final int minWidth = 16843071; // 0x101013f - field public static final int minimumHorizontalAngle = 16843903; // 0x101047f - field public static final int minimumVerticalAngle = 16843904; // 0x1010480 + field public static final int minimumHorizontalAngle = 16843901; // 0x101047d + field public static final int minimumVerticalAngle = 16843902; // 0x101047e field public static final int mipMap = 16843725; // 0x10103cd field public static final int mirrorForRtl = 16843726; // 0x10103ce field public static final int mode = 16843134; // 0x101017e field public static final int moreIcon = 16843061; // 0x1010135 - field public static final int multiArch = 16843920; // 0x1010490 + field public static final int multiArch = 16843918; // 0x101048e field public static final int multiprocess = 16842771; // 0x1010013 field public static final int name = 16842755; // 0x1010003 - field public static final int navigationBarColor = 16843860; // 0x1010454 + field public static final int navigationBarColor = 16843858; // 0x1010452 field public static final int navigationMode = 16843471; // 0x10102cf field public static final int negativeButtonText = 16843254; // 0x10101f6 - field public static final int nestedScrollingEnabled = 16843832; // 0x1010438 + field public static final int nestedScrollingEnabled = 16843830; // 0x1010436 field public static final int nextFocusDown = 16842980; // 0x10100e4 field public static final int nextFocusForward = 16843580; // 0x101033c field public static final int nextFocusLeft = 16842977; // 0x10100e1 @@ -918,9 +916,9 @@ package android { field public static final int notificationTimeout = 16843651; // 0x1010383 field public static final int numColumns = 16843032; // 0x1010118 field public static final int numStars = 16843076; // 0x1010144 - field public static final int numbersBackgroundColor = 16843941; // 0x10104a5 - field public static final int numbersSelectorColor = 16843942; // 0x10104a6 - field public static final int numbersTextColor = 16843940; // 0x10104a4 + field public static final int numbersBackgroundColor = 16843939; // 0x10104a3 + field public static final int numbersSelectorColor = 16843940; // 0x10104a4 + field public static final int numbersTextColor = 16843938; // 0x10104a2 field public static final deprecated int numeric = 16843109; // 0x1010165 field public static final int numericShortcut = 16843236; // 0x10101e4 field public static final int onClick = 16843375; // 0x101026f @@ -935,14 +933,14 @@ 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 overlapAnchor = 16843876; // 0x1010464 + field public static final int overlapAnchor = 16843874; // 0x1010462 field public static final int overridesImplicitlyEnabledSubtype = 16843682; // 0x10103a2 field public static final int packageNames = 16843649; // 0x1010381 field public static final int padding = 16842965; // 0x10100d5 field public static final int paddingBottom = 16842969; // 0x10100d9 field public static final int paddingEnd = 16843700; // 0x10103b4 field public static final int paddingLeft = 16842966; // 0x10100d6 - field public static final int paddingMode = 16843865; // 0x1010459 + field public static final int paddingMode = 16843863; // 0x1010457 field public static final int paddingRight = 16842968; // 0x10100d8 field public static final int paddingStart = 16843699; // 0x10103b3 field public static final int paddingTop = 16842967; // 0x10100d7 @@ -954,14 +952,14 @@ package android { field public static final int parentActivityName = 16843687; // 0x10103a7 field public static final deprecated int password = 16843100; // 0x101015c field public static final int path = 16842794; // 0x101002a - field public static final int pathData = 16843808; // 0x1010420 + field public static final int pathData = 16843807; // 0x101041f field public static final int pathPattern = 16842796; // 0x101002c field public static final int pathPrefix = 16842795; // 0x101002b field public static final int permission = 16842758; // 0x1010006 field public static final int permissionFlags = 16843719; // 0x10103c7 field public static final int permissionGroup = 16842762; // 0x101000a field public static final int permissionGroupFlags = 16843717; // 0x10103c5 - field public static final int persistableMode = 16843823; // 0x101042f + field public static final int persistableMode = 16843821; // 0x101042d field public static final int persistent = 16842765; // 0x101000d field public static final int persistentDrawingCache = 16842990; // 0x10100ee field public static final deprecated int phoneNumber = 16843111; // 0x1010167 @@ -970,11 +968,11 @@ package android { field public static final int popupAnimationStyle = 16843465; // 0x10102c9 field public static final int popupBackground = 16843126; // 0x1010176 field public static final int popupCharacters = 16843332; // 0x1010244 - field public static final int popupElevation = 16843918; // 0x101048e + field public static final int popupElevation = 16843916; // 0x101048c field public static final int popupKeyboard = 16843331; // 0x1010243 field public static final int popupLayout = 16843323; // 0x101023b field public static final int popupMenuStyle = 16843520; // 0x1010300 - field public static final int popupTheme = 16843948; // 0x10104ac + field public static final int popupTheme = 16843946; // 0x10104aa field public static final int popupWindowStyle = 16842870; // 0x1010076 field public static final int port = 16842793; // 0x1010029 field public static final int positiveButtonText = 16843253; // 0x10101f5 @@ -989,8 +987,8 @@ package android { field public static final int privateImeOptions = 16843299; // 0x1010223 field public static final int process = 16842769; // 0x1010011 field public static final int progress = 16843063; // 0x1010137 - field public static final int progressBackgroundTint = 16843879; // 0x1010467 - field public static final int progressBackgroundTintMode = 16843880; // 0x1010468 + field public static final int progressBackgroundTint = 16843877; // 0x1010465 + field public static final int progressBackgroundTintMode = 16843878; // 0x1010466 field public static final int progressBarPadding = 16843545; // 0x1010319 field public static final int progressBarStyle = 16842871; // 0x1010077 field public static final int progressBarStyleHorizontal = 16842872; // 0x1010078 @@ -1001,17 +999,17 @@ package android { field public static final int progressBarStyleSmallInverse = 16843400; // 0x1010288 field public static final int progressBarStyleSmallTitle = 16843279; // 0x101020f field public static final int progressDrawable = 16843068; // 0x101013c - field public static final int progressTint = 16843877; // 0x1010465 - field public static final int progressTintMode = 16843878; // 0x1010466 + field public static final int progressTint = 16843875; // 0x1010463 + field public static final int progressTintMode = 16843876; // 0x1010464 field public static final int prompt = 16843131; // 0x101017b field public static final int propertyName = 16843489; // 0x10102e1 - field public static final int propertyXName = 16843894; // 0x1010476 - field public static final int propertyYName = 16843895; // 0x1010477 + field public static final int propertyXName = 16843892; // 0x1010474 + field public static final int propertyYName = 16843893; // 0x1010475 field public static final int protectionLevel = 16842761; // 0x1010009 field public static final int publicKey = 16843686; // 0x10103a6 field public static final int queryActionMsg = 16843227; // 0x10101db field public static final int queryAfterZeroResults = 16843394; // 0x1010282 - field public static final int queryBackground = 16843913; // 0x1010489 + field public static final int queryBackground = 16843911; // 0x1010487 field public static final int queryHint = 16843608; // 0x1010358 field public static final int quickContactBadgeStyleSmallWindowLarge = 16843443; // 0x10102b3 field public static final int quickContactBadgeStyleSmallWindowMedium = 16843442; // 0x10102b2 @@ -1026,8 +1024,8 @@ package android { field public static final int ratingBarStyleIndicator = 16843280; // 0x1010210 field public static final int ratingBarStyleSmall = 16842877; // 0x101007d field public static final int readPermission = 16842759; // 0x1010007 - field public static final int recognitionService = 16843934; // 0x101049e - field public static final int relinquishTaskIdentity = 16843896; // 0x1010478 + field public static final int recognitionService = 16843932; // 0x101049c + field public static final int relinquishTaskIdentity = 16843894; // 0x1010476 field public static final int repeatCount = 16843199; // 0x10101bf field public static final int repeatMode = 16843200; // 0x10101c0 field public static final int reqFiveWayNav = 16843314; // 0x1010232 @@ -1039,7 +1037,7 @@ package android { field public static final int required = 16843406; // 0x101028e field public static final int requiredAccountType = 16843734; // 0x10103d6 field public static final int requiredForAllUsers = 16843728; // 0x10103d0 - field public static final int requiredForProfile = 16843818; // 0x101042a + field public static final int requiredForProfile = 16843816; // 0x1010428 field public static final int requiresFadingEdge = 16843685; // 0x10103a5 field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364 field public static final int resizeMode = 16843619; // 0x1010363 @@ -1048,8 +1046,8 @@ package android { field public static final int restoreAnyVersion = 16843450; // 0x10102ba field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d field public static final int restrictedAccountType = 16843733; // 0x10103d5 - field public static final int restrictionType = 16843925; // 0x1010495 - field public static final int reversible = 16843853; // 0x101044d + field public static final int restrictionType = 16843923; // 0x1010493 + field public static final int reversible = 16843851; // 0x101044b field public static final int right = 16843183; // 0x10101af field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093 field public static final int ringtoneType = 16843257; // 0x10101f9 @@ -1089,7 +1087,7 @@ package android { field public static final int scrollbars = 16842974; // 0x10100de field public static final int scrollingCache = 16843006; // 0x10100fe field public static final deprecated int searchButtonText = 16843269; // 0x1010205 - field public static final int searchIcon = 16843909; // 0x1010485 + field public static final int searchIcon = 16843907; // 0x1010483 field public static final int searchMode = 16843221; // 0x10101d5 field public static final int searchSettingsDescription = 16843402; // 0x101028a field public static final int searchSuggestAuthority = 16843222; // 0x10101d6 @@ -1098,19 +1096,19 @@ package android { field public static final int searchSuggestPath = 16843223; // 0x10101d7 field public static final int searchSuggestSelection = 16843224; // 0x10101d8 field public static final int searchSuggestThreshold = 16843373; // 0x101026d - field public static final int searchViewStyle = 16843906; // 0x1010482 + field public static final int searchViewStyle = 16843904; // 0x1010480 field public static final int secondaryProgress = 16843064; // 0x1010138 - field public static final int secondaryProgressTint = 16843881; // 0x1010469 - field public static final int secondaryProgressTintMode = 16843882; // 0x101046a + field public static final int secondaryProgressTint = 16843879; // 0x1010467 + field public static final int secondaryProgressTintMode = 16843880; // 0x1010468 field public static final int seekBarStyle = 16842875; // 0x101007b field public static final int segmentedButtonStyle = 16843568; // 0x1010330 field public static final int selectAllOnFocus = 16843102; // 0x101015e field public static final int selectable = 16843238; // 0x10101e6 field public static final int selectableItemBackground = 16843534; // 0x101030e - field public static final int selectableItemBackgroundBorderless = 16843870; // 0x101045e + field public static final int selectableItemBackgroundBorderless = 16843868; // 0x101045c field public static final int selectedDateVerticalBar = 16843591; // 0x1010347 field public static final int selectedWeekBackgroundColor = 16843586; // 0x1010342 - field public static final int sessionService = 16843839; // 0x101043f + field public static final int sessionService = 16843837; // 0x101043d field public static final int settingsActivity = 16843301; // 0x1010225 field public static final int setupActivity = 16843766; // 0x10103f6 field public static final int shadowColor = 16843105; // 0x1010161 @@ -1127,13 +1125,13 @@ package android { field public static final int showDividers = 16843561; // 0x1010329 field public static final int showOnLockScreen = 16843721; // 0x10103c9 field public static final int showSilent = 16843259; // 0x10101fb - field public static final int showText = 16843952; // 0x10104b0 + field public static final int showText = 16843950; // 0x10104ae field public static final int showWeekNumber = 16843582; // 0x101033e field public static final int shownWeekCount = 16843585; // 0x1010341 field public static final int shrinkColumns = 16843082; // 0x101014a field public static final deprecated int singleLine = 16843101; // 0x101015d field public static final int singleUser = 16843711; // 0x10103bf - field public static final int slideEdge = 16843826; // 0x1010432 + field public static final int slideEdge = 16843824; // 0x1010430 field public static final int smallIcon = 16843422; // 0x101029e field public static final int smallScreens = 16843396; // 0x1010284 field public static final int smoothScrollbar = 16843313; // 0x1010231 @@ -1145,19 +1143,19 @@ package android { field public static final int spinnerStyle = 16842881; // 0x1010081 field public static final int spinnersShown = 16843595; // 0x101034b field public static final int splitMotionEvents = 16843503; // 0x10102ef - field public static final int splitTrack = 16843854; // 0x101044e + field public static final int splitTrack = 16843852; // 0x101044c field public static final int src = 16843033; // 0x1010119 field public static final int ssp = 16843747; // 0x10103e3 field public static final int sspPattern = 16843749; // 0x10103e5 field public static final int sspPrefix = 16843748; // 0x10103e4 field public static final int stackFromBottom = 16843005; // 0x10100fd - field public static final int stackViewStyle = 16843840; // 0x1010440 + field public static final int stackViewStyle = 16843838; // 0x101043e field public static final int starStyle = 16842882; // 0x1010082 field public static final int startColor = 16843165; // 0x101019d field public static final int startDelay = 16843746; // 0x10103e2 field public static final int startOffset = 16843198; // 0x10101be field public static final deprecated int startYear = 16843132; // 0x101017c - field public static final int stateListAnimator = 16843850; // 0x101044a + field public static final int stateListAnimator = 16843848; // 0x1010448 field public static final int stateNotNeeded = 16842774; // 0x1010016 field public static final int state_above_anchor = 16842922; // 0x10100aa field public static final int state_accelerated = 16843547; // 0x101031b @@ -1182,27 +1180,27 @@ package android { field public static final int state_single = 16842915; // 0x10100a3 field public static final int state_window_focused = 16842909; // 0x101009d field public static final int staticWallpaperPreview = 16843569; // 0x1010331 - field public static final int statusBarColor = 16843859; // 0x1010453 + field public static final int statusBarColor = 16843857; // 0x1010451 field public static final int stepSize = 16843078; // 0x1010146 field public static final int stopWithTask = 16843626; // 0x101036a field public static final int streamType = 16843273; // 0x1010209 field public static final int stretchColumns = 16843081; // 0x1010149 field public static final int stretchMode = 16843030; // 0x1010116 - field public static final int strokeColor = 16843809; // 0x1010421 - field public static final int strokeLineCap = 16843815; // 0x1010427 - field public static final int strokeLineJoin = 16843816; // 0x1010428 - field public static final int strokeMiterLimit = 16843817; // 0x1010429 - field public static final int strokeWidth = 16843811; // 0x1010423 - field public static final int submitBackground = 16843914; // 0x101048a + field public static final int strokeColor = 16843808; // 0x1010420 + field public static final int strokeLineCap = 16843813; // 0x1010425 + field public static final int strokeLineJoin = 16843814; // 0x1010426 + field public static final int strokeMiterLimit = 16843815; // 0x1010427 + field public static final int strokeWidth = 16843809; // 0x1010421 + field public static final int submitBackground = 16843912; // 0x1010488 field public static final int subtitle = 16843473; // 0x10102d1 - field public static final int subtitleTextAppearance = 16843825; // 0x1010431 + field public static final int subtitleTextAppearance = 16843823; // 0x101042f field public static final int subtitleTextStyle = 16843513; // 0x10102f9 field public static final int subtypeExtraValue = 16843674; // 0x101039a field public static final int subtypeId = 16843713; // 0x10103c1 field public static final int subtypeLocale = 16843673; // 0x1010399 field public static final int suggestActionMsg = 16843228; // 0x10101dc field public static final int suggestActionMsgColumn = 16843229; // 0x10101dd - field public static final int suggestionRowLayout = 16843912; // 0x1010488 + field public static final int suggestionRowLayout = 16843910; // 0x1010486 field public static final int summary = 16843241; // 0x10101e9 field public static final int summaryColumn = 16843426; // 0x10102a2 field public static final int summaryOff = 16843248; // 0x10101f0 @@ -1213,7 +1211,7 @@ package android { field public static final int switchMinWidth = 16843632; // 0x1010370 field public static final int switchPadding = 16843633; // 0x1010371 field public static final int switchPreferenceStyle = 16843629; // 0x101036d - field public static final int switchStyle = 16843841; // 0x1010441 + field public static final int switchStyle = 16843839; // 0x101043f field public static final int switchTextAppearance = 16843630; // 0x101036e field public static final int switchTextOff = 16843628; // 0x101036c field public static final int switchTextOn = 16843627; // 0x101036b @@ -1227,7 +1225,7 @@ package android { field public static final int targetClass = 16842799; // 0x101002f field public static final int targetDescriptions = 16843680; // 0x10103a0 field public static final int targetId = 16843740; // 0x10103dc - field public static final int targetName = 16843855; // 0x101044f + field public static final int targetName = 16843853; // 0x101044d field public static final int targetPackage = 16842785; // 0x1010021 field public static final int targetSdkVersion = 16843376; // 0x1010270 field public static final int taskAffinity = 16842770; // 0x1010012 @@ -1251,7 +1249,7 @@ package android { field public static final int textAppearanceLargeInverse = 16842819; // 0x1010043 field public static final int textAppearanceLargePopupMenu = 16843521; // 0x1010301 field public static final int textAppearanceListItem = 16843678; // 0x101039e - field public static final int textAppearanceListItemSecondary = 16843828; // 0x1010434 + field public static final int textAppearanceListItemSecondary = 16843826; // 0x1010432 field public static final int textAppearanceListItemSmall = 16843679; // 0x101039f field public static final int textAppearanceMedium = 16842817; // 0x1010041 field public static final int textAppearanceMediumInverse = 16842820; // 0x1010044 @@ -1308,38 +1306,38 @@ package android { field public static final int thumb = 16843074; // 0x1010142 field public static final int thumbOffset = 16843075; // 0x1010143 field public static final int thumbTextPadding = 16843634; // 0x1010372 - field public static final int thumbTint = 16843891; // 0x1010473 - field public static final int thumbTintMode = 16843892; // 0x1010474 + field public static final int thumbTint = 16843889; // 0x1010471 + field public static final int thumbTintMode = 16843890; // 0x1010472 field public static final int thumbnail = 16843429; // 0x10102a5 field public static final int tileMode = 16843265; // 0x1010201 - field public static final int tileModeX = 16843897; // 0x1010479 - field public static final int tileModeY = 16843898; // 0x101047a - field public static final int timePickerDialogTheme = 16843936; // 0x10104a0 - field public static final int timePickerMode = 16843959; // 0x10104b7 - field public static final int timePickerStyle = 16843935; // 0x101049f + field public static final int tileModeX = 16843895; // 0x1010477 + field public static final int tileModeY = 16843896; // 0x1010478 + field public static final int timePickerDialogTheme = 16843934; // 0x101049e + field public static final int timePickerMode = 16843957; // 0x10104b5 + field public static final int timePickerStyle = 16843933; // 0x101049d field public static final int timeZone = 16843724; // 0x10103cc field public static final int tint = 16843041; // 0x1010121 field public static final int tintMode = 16843797; // 0x1010415 field public static final int title = 16843233; // 0x10101e1 field public static final int titleCondensed = 16843234; // 0x10101e2 - field public static final int titleTextAppearance = 16843824; // 0x1010430 + field public static final int titleTextAppearance = 16843822; // 0x101042e field public static final int titleTextStyle = 16843512; // 0x10102f8 field public static final int toAlpha = 16843211; // 0x10101cb field public static final int toDegrees = 16843188; // 0x10101b4 - field public static final int toId = 16843851; // 0x101044b + field public static final int toId = 16843849; // 0x1010449 field public static final int toScene = 16843742; // 0x10103de field public static final int toXDelta = 16843207; // 0x10101c7 field public static final int toXScale = 16843203; // 0x10101c3 field public static final int toYDelta = 16843209; // 0x10101c9 field public static final int toYScale = 16843205; // 0x10101c5 - field public static final int toolbarStyle = 16843949; // 0x10104ad + field public static final int toolbarStyle = 16843947; // 0x10104ab field public static final int top = 16843182; // 0x10101ae field public static final int topBright = 16842955; // 0x10100cb field public static final int topDark = 16842951; // 0x10100c7 field public static final int topLeftRadius = 16843177; // 0x10101a9 field public static final int topOffset = 16843352; // 0x1010258 field public static final int topRightRadius = 16843178; // 0x10101aa - field public static final int touchscreenBlocksFocus = 16843921; // 0x1010491 + field public static final int touchscreenBlocksFocus = 16843919; // 0x101048f field public static final int track = 16843631; // 0x101036f field public static final int transcriptMode = 16843008; // 0x1010100 field public static final int transformPivotX = 16843552; // 0x1010320 @@ -1348,14 +1346,15 @@ package android { field public static final int transitionGroup = 16843803; // 0x101041b field public static final int transitionName = 16843802; // 0x101041a field public static final int transitionOrdering = 16843744; // 0x10103e0 - field public static final int translateX = 16843868; // 0x101045c - field public static final int translateY = 16843869; // 0x101045d + field public static final int translateX = 16843866; // 0x101045a + field public static final int translateY = 16843867; // 0x101045b field public static final int translationX = 16843554; // 0x1010322 field public static final int translationY = 16843555; // 0x1010323 field public static final int translationZ = 16843796; // 0x1010414 - field public static final int trimPathEnd = 16843813; // 0x1010425 - field public static final int trimPathOffset = 16843814; // 0x1010426 - field public static final int trimPathStart = 16843812; // 0x1010424 + field public static final int trimPathEnd = 16843811; // 0x1010423 + field public static final int trimPathOffset = 16843812; // 0x1010424 + field public static final int trimPathStart = 16843810; // 0x1010422 + field public static final int tvContentRatingDescription = 16843955; // 0x10104b3 field public static final int type = 16843169; // 0x10101a1 field public static final int typeface = 16842902; // 0x1010096 field public static final int uiOptions = 16843672; // 0x1010398 @@ -1383,10 +1382,10 @@ package android { field public static final int viewportHeight = 16843805; // 0x101041d field public static final int viewportWidth = 16843804; // 0x101041c field public static final int visibility = 16842972; // 0x10100dc - field public static final int visibilityMode = 16843902; // 0x101047e + field public static final int visibilityMode = 16843900; // 0x101047c field public static final int visible = 16843156; // 0x1010194 field public static final int vmSafeMode = 16843448; // 0x10102b8 - field public static final int voiceIcon = 16843910; // 0x1010486 + field public static final int voiceIcon = 16843908; // 0x1010484 field public static final int voiceLanguage = 16843349; // 0x1010255 field public static final int voiceLanguageModel = 16843347; // 0x1010253 field public static final int voiceMaxResults = 16843350; // 0x1010256 @@ -1412,23 +1411,23 @@ package android { field public static final int windowActionBar = 16843469; // 0x10102cd field public static final int windowActionBarOverlay = 16843492; // 0x10102e4 field public static final int windowActionModeOverlay = 16843485; // 0x10102dd - field public static final int windowAllowEnterTransitionOverlap = 16843838; // 0x101043e - field public static final int windowAllowExitTransitionOverlap = 16843837; // 0x101043d + field public static final int windowAllowEnterTransitionOverlap = 16843836; // 0x101043c + field public static final int windowAllowExitTransitionOverlap = 16843835; // 0x101043b field public static final int windowAnimationStyle = 16842926; // 0x10100ae field public static final int windowBackground = 16842836; // 0x1010054 - field public static final int windowClipToOutline = 16843950; // 0x10104ae + field public static final int windowClipToOutline = 16843948; // 0x10104ac field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b field public static final int windowContentOverlay = 16842841; // 0x1010059 field public static final int windowContentTransitionManager = 16843795; // 0x1010413 field public static final int windowContentTransitions = 16843794; // 0x1010412 field public static final int windowDisablePreview = 16843298; // 0x1010222 - field public static final int windowDrawsSystemBarBackgrounds = 16843858; // 0x1010452 - field public static final int windowElevation = 16843922; // 0x1010492 + field public static final int windowDrawsSystemBarBackgrounds = 16843856; // 0x1010450 + field public static final int windowElevation = 16843920; // 0x1010490 field public static final int windowEnableSplitTouch = 16843543; // 0x1010317 field public static final int windowEnterAnimation = 16842932; // 0x10100b4 - field public static final int windowEnterTransition = 16843833; // 0x1010439 + field public static final int windowEnterTransition = 16843831; // 0x1010437 field public static final int windowExitAnimation = 16842933; // 0x10100b5 - field public static final int windowExitTransition = 16843834; // 0x101043a + 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 windowHideAnimation = 16842935; // 0x10100b7 @@ -1439,12 +1438,12 @@ package android { field public static final int windowNoDisplay = 16843294; // 0x101021e field public static final int windowNoTitle = 16842838; // 0x1010056 field public static final int windowOverscan = 16843727; // 0x10103cf - field public static final int windowReenterTransition = 16843954; // 0x10104b2 - field public static final int windowReturnTransition = 16843953; // 0x10104b1 - field public static final int windowSharedElementEnterTransition = 16843835; // 0x101043b - field public static final int windowSharedElementExitTransition = 16843836; // 0x101043c - field public static final int windowSharedElementReenterTransition = 16843956; // 0x10104b4 - field public static final int windowSharedElementReturnTransition = 16843955; // 0x10104b3 + field public static final int windowReenterTransition = 16843952; // 0x10104b0 + field public static final int windowReturnTransition = 16843951; // 0x10104af + field public static final int windowSharedElementEnterTransition = 16843833; // 0x1010439 + field public static final int windowSharedElementExitTransition = 16843834; // 0x101043a + field public static final int windowSharedElementReenterTransition = 16843954; // 0x10104b2 + field public static final int windowSharedElementReturnTransition = 16843953; // 0x10104b1 field public static final int windowShowAnimation = 16842934; // 0x10100b6 field public static final int windowShowWallpaper = 16843410; // 0x1010292 field public static final int windowSoftInputMode = 16843307; // 0x101022b @@ -1452,15 +1451,15 @@ package android { field public static final int windowTitleBackgroundStyle = 16842844; // 0x101005c field public static final int windowTitleSize = 16842842; // 0x101005a field public static final int windowTitleStyle = 16842843; // 0x101005b - field public static final int windowTransitionBackgroundFadeDuration = 16843875; // 0x1010463 + field public static final int windowTransitionBackgroundFadeDuration = 16843873; // 0x1010461 field public static final int windowTranslucentNavigation = 16843760; // 0x10103f0 field public static final int windowTranslucentStatus = 16843759; // 0x10103ef field public static final int writePermission = 16842760; // 0x1010008 field public static final int x = 16842924; // 0x10100ac field public static final int xlargeScreens = 16843455; // 0x10102bf field public static final int y = 16842925; // 0x10100ad - field public static final int yearListItemTextAppearance = 16843931; // 0x101049b - field public static final int yearListSelectorColor = 16843932; // 0x101049c + field public static final int yearListItemTextAppearance = 16843929; // 0x1010499 + field public static final int yearListSelectorColor = 16843930; // 0x101049a field public static final int yesNoPreferenceStyle = 16842896; // 0x1010090 field public static final int zAdjustment = 16843201; // 0x10101c1 } @@ -3438,7 +3437,6 @@ package android.app { method public void onAttachFragment(android.app.Fragment); method public void onAttachedToWindow(); method public void onBackPressed(); - method public void onBackgroundMediaPlayingChanged(boolean); method protected void onChildTitleChanged(android.app.Activity, java.lang.CharSequence); method public void onConfigurationChanged(android.content.res.Configuration); method public void onContentChanged(); @@ -3495,13 +3493,13 @@ package android.app { method public boolean onSearchRequested(); method protected void onStart(); method protected void onStop(); - method public void onStopMediaPlaying(); method protected void onTitleChanged(java.lang.CharSequence, int); method public boolean onTouchEvent(android.view.MotionEvent); method public boolean onTrackballEvent(android.view.MotionEvent); method public void onTrimMemory(int); method public void onUserInteraction(); method protected void onUserLeaveHint(); + method public void onVisibleBehindCancelled(); method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams); method public void onWindowFocusChanged(boolean); method public android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback); @@ -3513,6 +3511,7 @@ package android.app { method public void registerForContextMenu(android.view.View); method public final deprecated void removeDialog(int); method public void reportFullyDrawn(); + method public boolean requestVisibleBehind(boolean); method public final boolean requestWindowFeature(int); method public final void runOnUiThread(java.lang.Runnable); method public void setActionBar(android.widget.Toolbar); @@ -3531,7 +3530,6 @@ package android.app { method public void setImmersive(boolean); method public void setIntent(android.content.Intent); method public final void setMediaController(android.media.session.MediaController); - method public boolean setMediaPlaying(boolean); method public final void setProgress(int); method public final void setProgressBarIndeterminate(boolean); method public final void setProgressBarIndeterminateVisibility(boolean); @@ -3772,20 +3770,11 @@ package android.app { method public void update(android.app.ActivityOptions); } - public class AlarmClockInfo implements android.os.Parcelable { - ctor public AlarmClockInfo(long, android.app.PendingIntent); - method public int describeContents(); - method public android.app.PendingIntent getShowIntent(); - method public long getTriggerTime(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator CREATOR; - } - public class AlarmManager { method public void cancel(android.app.PendingIntent); - method public android.app.AlarmClockInfo getNextAlarmClock(); + method public android.app.AlarmManager.AlarmClockInfo getNextAlarmClock(); method public void set(int, long, android.app.PendingIntent); - method public void setAlarmClock(android.app.AlarmClockInfo, android.app.PendingIntent); + method public void setAlarmClock(android.app.AlarmManager.AlarmClockInfo, android.app.PendingIntent); method public void setExact(int, long, android.app.PendingIntent); method public void setInexactRepeating(int, long, long, android.app.PendingIntent); method public void setRepeating(int, long, long, android.app.PendingIntent); @@ -3804,6 +3793,15 @@ package android.app { field public static final int RTC_WAKEUP = 0; // 0x0 } + public static final class AlarmManager.AlarmClockInfo implements android.os.Parcelable { + ctor public AlarmManager.AlarmClockInfo(long, android.app.PendingIntent); + method public int describeContents(); + method public android.app.PendingIntent getShowIntent(); + method public long getTriggerTime(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + } + public class AlertDialog extends android.app.Dialog implements android.content.DialogInterface { ctor protected AlertDialog(android.content.Context); ctor protected AlertDialog(android.content.Context, int); @@ -5238,8 +5236,8 @@ package android.app { field public static java.lang.String ACTION_EXIT_CAR_MODE; field public static java.lang.String ACTION_EXIT_DESK_MODE; field public static final int DISABLE_CAR_MODE_GO_HOME = 1; // 0x1 + field public static final int ENABLE_CAR_MODE_ALLOW_SLEEP = 2; // 0x2 field public static final int ENABLE_CAR_MODE_GO_CAR_HOME = 1; // 0x1 - field public static final int ENABLE_CAR_MODE_NO_WAKE_LOCK = 2; // 0x2 field public static final int MODE_NIGHT_AUTO = 0; // 0x0 field public static final int MODE_NIGHT_NO = 1; // 0x1 field public static final int MODE_NIGHT_YES = 2; // 0x2 @@ -13588,7 +13586,7 @@ package android.inputmethodservice { public class InputMethodService extends android.inputmethodservice.AbstractInputMethodService { ctor public InputMethodService(); - method public boolean enableHardwareAcceleration(); + method public deprecated boolean enableHardwareAcceleration(); method public int getBackDisposition(); method public int getCandidatesHiddenVisibility(); method public android.view.inputmethod.InputBinding getCurrentInputBinding(); @@ -15762,11 +15760,12 @@ package android.media { } public class Ringtone { - method public int getStreamType(); + method public deprecated int getStreamType(); method public java.lang.String getTitle(android.content.Context); method public boolean isPlaying(); method public void play(); - method public void setStreamType(int); + method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException; + method public deprecated void setStreamType(int); method public void stop(); } @@ -16718,6 +16717,7 @@ package android.media.session { method public void onPlaybackStateChanged(android.media.session.PlaybackState); method public void onQueueChanged(java.util.List<android.media.session.MediaSession.Track>); method public void onQueueTitleChanged(java.lang.CharSequence); + method public void onSessionDestroyed(); method public void onSessionEvent(java.lang.String, android.os.Bundle); method public void onVolumeInfoChanged(android.media.session.MediaController.VolumeInfo); } @@ -22810,7 +22810,6 @@ package android.os { field public static final deprecated int FULL_WAKE_LOCK = 26; // 0x1a field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000 field public static final int PARTIAL_WAKE_LOCK = 1; // 0x1 - field public static final java.lang.String REBOOT_RECOVERY = "recovery"; field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6 } @@ -25886,8 +25885,10 @@ package android.provider { field public static final java.lang.String ACTION_SHOW_REGULATORY_INFO = "android.settings.SHOW_REGULATORY_INFO"; field public static final java.lang.String ACTION_SOUND_SETTINGS = "android.settings.SOUND_SETTINGS"; field public static final java.lang.String ACTION_SYNC_SETTINGS = "android.settings.SYNC_SETTINGS"; + field public static final java.lang.String ACTION_USAGE_ACCESS_SETTINGS = "android.settings.USAGE_ACCESS_SETTINGS"; field public static final java.lang.String ACTION_USER_DICTIONARY_SETTINGS = "android.settings.USER_DICTIONARY_SETTINGS"; field public static final java.lang.String ACTION_VOICE_CONTROL_AIRPLANE_MODE = "android.settings.VOICE_CONTROL_AIRPLANE_MODE"; + field public static final java.lang.String ACTION_VOICE_INPUT_SETTINGS = "android.settings.VOICE_INPUT_SETTINGS"; field public static final java.lang.String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS"; field public static final java.lang.String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS"; field public static final java.lang.String ACTION_WIRELESS_SETTINGS = "android.settings.WIRELESS_SETTINGS"; @@ -28812,70 +28813,7 @@ package android.system { package android.telecomm { - public final class Call { - method public void addListener(android.telecomm.Call.Listener); - method public void answer(int); - method public void conference(android.telecomm.Call); - method public void disconnect(); - method public java.util.List<java.lang.String> getCannedTextResponses(); - method public java.util.List<android.telecomm.Call> getChildren(); - method public java.util.List<android.telecomm.Call> getConferenceableCalls(); - method public android.telecomm.Call.Details getDetails(); - method public android.telecomm.Call getParent(); - method public java.lang.String getRemainingPostDialSequence(); - method public int getState(); - method public android.telecomm.InCallService.VideoCall getVideoCall(); - method public void hold(); - method public void phoneAccountClicked(); - method public void phoneAccountSelected(android.telecomm.PhoneAccountHandle); - method public void playDtmfTone(char); - method public void postDialContinue(boolean); - method public void reject(boolean, java.lang.String); - method public void removeListener(android.telecomm.Call.Listener); - method public void splitFromConference(); - method public void stopDtmfTone(); - method public void swapWithBackgroundCall(); - method public void unhold(); - field public static final int STATE_ACTIVE = 4; // 0x4 - field public static final int STATE_CONNECTING = 9; // 0x9 - field public static final int STATE_DIALING = 1; // 0x1 - field public static final int STATE_DISCONNECTED = 7; // 0x7 - field public static final int STATE_HOLDING = 3; // 0x3 - field public static final int STATE_NEW = 0; // 0x0 - field public static final int STATE_PRE_DIAL_WAIT = 8; // 0x8 - field public static final int STATE_RINGING = 2; // 0x2 - } - - public static class Call.Details { - method public android.telecomm.PhoneAccountHandle getAccountHandle(); - method public int getCallCapabilities(); - method public java.lang.String getCallerDisplayName(); - method public int getCallerDisplayNamePresentation(); - method public long getConnectTimeMillis(); - method public int getDisconnectCauseCode(); - method public java.lang.String getDisconnectCauseMsg(); - method public android.telecomm.GatewayInfo getGatewayInfo(); - method public android.net.Uri getHandle(); - method public int getHandlePresentation(); - method public android.telecomm.StatusHints getStatusHints(); - method public int getVideoState(); - } - - public static abstract class Call.Listener { - ctor public Call.Listener(); - method public void onCallDestroyed(android.telecomm.Call); - method public void onCannedTextResponsesLoaded(android.telecomm.Call, java.util.List<java.lang.String>); - method public void onChildrenChanged(android.telecomm.Call, java.util.List<android.telecomm.Call>); - method public void onConferenceableCallsChanged(android.telecomm.Call, java.util.List<android.telecomm.Call>); - method public void onDetailsChanged(android.telecomm.Call, android.telecomm.Call.Details); - method public void onParentChanged(android.telecomm.Call, android.telecomm.Call); - method public void onPostDialWait(android.telecomm.Call, java.lang.String); - method public void onStartActivity(android.telecomm.Call, android.app.PendingIntent); - method public void onStateChanged(android.telecomm.Call, int); - method public void onVideoCallChanged(android.telecomm.Call, android.telecomm.InCallService.VideoCall); - } - - public final class CallAudioState implements android.os.Parcelable { + public final class AudioState implements android.os.Parcelable { method public int describeContents(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; @@ -28890,8 +28828,8 @@ package android.telecomm { field public final int supportedRouteMask; } - public final class CallCameraCapabilities implements android.os.Parcelable { - ctor public CallCameraCapabilities(boolean, float, int, int); + public final class CameraCapabilities implements android.os.Parcelable { + ctor public CameraCapabilities(boolean, float, int, int); method public int describeContents(); method public int getHeight(); method public float getMaxZoom(); @@ -28901,55 +28839,18 @@ package android.telecomm { field public static final android.os.Parcelable.Creator CREATOR; } - public final class CallCapabilities { - method public static java.lang.String toString(int); - field public static final int ADD_CALL = 16; // 0x10 - field public static final int ALL = 3327; // 0xcff - field public static final int GENERIC_CONFERENCE = 128; // 0x80 - field public static final int HOLD = 1; // 0x1 - field public static final int MERGE_CALLS = 4; // 0x4 - field public static final int MUTE = 64; // 0x40 - field public static final int RESPOND_VIA_TEXT = 32; // 0x20 - field public static final int SUPPORTS_VT_LOCAL = 256; // 0x100 - field public static final int SUPPORTS_VT_REMOTE = 512; // 0x200 - field public static final int SUPPORT_HOLD = 2; // 0x2 - field public static final int SWAP_CALLS = 8; // 0x8 - field public static final int VoLTE = 1024; // 0x400 - field public static final int VoWIFI = 2048; // 0x800 - } - - public class CallPropertyPresentation { - ctor public CallPropertyPresentation(); - field public static final int ALLOWED = 1; // 0x1 - field public static final int PAYPHONE = 4; // 0x4 - field public static final int RESTRICTED = 2; // 0x2 - field public static final int UNKNOWN = 3; // 0x3 - } - - public final class CallState extends java.lang.Enum { - method public static android.telecomm.CallState valueOf(java.lang.String); - method public static final android.telecomm.CallState[] values(); - enum_constant public static final android.telecomm.CallState ACTIVE; - enum_constant public static final android.telecomm.CallState CONNECTING; - enum_constant public static final android.telecomm.CallState DIALING; - enum_constant public static final android.telecomm.CallState DISCONNECTED; - enum_constant public static final android.telecomm.CallState NEW; - enum_constant public static final android.telecomm.CallState ON_HOLD; - enum_constant public static final android.telecomm.CallState PRE_DIAL_WAIT; - enum_constant public static final android.telecomm.CallState RINGING; - } - public abstract class Connection { ctor public Connection(); + method public static android.telecomm.Connection createCanceledConnection(); + method public static android.telecomm.Connection createFailedConnection(int, java.lang.String); method public final void destroy(); method public final boolean getAudioModeIsVoip(); - method public final android.telecomm.CallAudioState getCallAudioState(); + method public final android.telecomm.AudioState getAudioState(); method public final int getCallCapabilities(); method public final java.lang.String getCallerDisplayName(); method public final int getCallerDisplayNamePresentation(); - method public static android.telecomm.Connection getCanceledConnection(); method public final java.util.List<android.telecomm.Connection> getChildConnections(); - method public static android.telecomm.Connection getFailedConnection(int, java.lang.String); + method public final java.util.List<android.telecomm.Connection> getConferenceableConnections(); method public final int getFailureCode(); method public final java.lang.String getFailureMessage(); method public final android.net.Uri getHandle(); @@ -28957,7 +28858,7 @@ package android.telecomm { method public final android.telecomm.Connection getParentConnection(); method public final int getState(); method public final android.telecomm.StatusHints getStatusHints(); - method public final android.telecomm.ConnectionService.VideoCallProvider getVideoCallProvider(); + method public final android.telecomm.Connection.VideoProvider getVideoProvider(); method public final int getVideoState(); method public final boolean isConferenceConnection(); method public final boolean isRequestingRingback(); @@ -28972,10 +28873,9 @@ package android.telecomm { method public void onPostDialContinue(boolean); method public void onReject(); method public void onSeparate(); - method public void onSetAudioState(android.telecomm.CallAudioState); + method public void onSetAudioState(android.telecomm.AudioState); method public void onSetState(int); method public void onStopDtmfTone(); - method public void onSwapWithBackgroundCall(); method public void onUnhold(); method public final void setActive(); method public final void setAudioModeIsVoip(boolean); @@ -28994,31 +28894,55 @@ package android.telecomm { method public final void setPostDialWait(java.lang.String); method public final void setRequestingRingback(boolean); method public final void setRinging(); - method public final void setSignal(android.os.Bundle); method public final void setStatusHints(android.telecomm.StatusHints); - method public final void setVideoCallProvider(android.telecomm.ConnectionService.VideoCallProvider); + method public final void setVideoProvider(android.telecomm.Connection.VideoProvider); method public final void setVideoState(int); method public final void startActivityFromInCall(android.app.PendingIntent); method public static java.lang.String stateToString(int); + field public static final int STATE_ACTIVE = 4; // 0x4 + field public static final int STATE_CANCELED = 8; // 0x8 + field public static final int STATE_DIALING = 3; // 0x3 + field public static final int STATE_DISCONNECTED = 6; // 0x6 + field public static final int STATE_FAILED = 7; // 0x7 + field public static final int STATE_HOLDING = 5; // 0x5 + field public static final int STATE_INITIALIZING = 0; // 0x0 + field public static final int STATE_NEW = 1; // 0x1 + field public static final int STATE_RINGING = 2; // 0x2 } - public final class Connection.State { - field public static final int ACTIVE = 4; // 0x4 - field public static final int CANCELED = 8; // 0x8 - field public static final int DIALING = 3; // 0x3 - field public static final int DISCONNECTED = 6; // 0x6 - field public static final int FAILED = 7; // 0x7 - field public static final int HOLDING = 5; // 0x5 - field public static final int INITIALIZING = 0; // 0x0 - field public static final int NEW = 1; // 0x1 - field public static final int RINGING = 2; // 0x2 + public static abstract class Connection.VideoProvider { + ctor public Connection.VideoProvider(); + method public void changeCallDataUsage(int); + method public void changeCameraCapabilities(android.telecomm.CameraCapabilities); + method public void changePeerDimensions(int, int); + method public void handleCallSessionEvent(int); + method public abstract void onRequestCallDataUsage(); + method public abstract void onRequestCameraCapabilities(); + method public abstract void onSendSessionModifyRequest(android.telecomm.VideoProfile); + method public abstract void onSendSessionModifyResponse(android.telecomm.VideoProfile); + method public abstract void onSetCamera(java.lang.String); + method public abstract void onSetDeviceOrientation(int); + method public abstract void onSetDisplaySurface(android.view.Surface); + method public abstract void onSetPauseImage(java.lang.String); + method public abstract void onSetPreviewSurface(android.view.Surface); + method public abstract void onSetZoom(float); + method public void receiveSessionModifyRequest(android.telecomm.VideoProfile); + method public void receiveSessionModifyResponse(int, android.telecomm.VideoProfile, android.telecomm.VideoProfile); + field public static final int SESSION_EVENT_CAMERA_FAILURE = 5; // 0x5 + field public static final int SESSION_EVENT_CAMERA_READY = 6; // 0x6 + field public static final int SESSION_EVENT_RX_PAUSE = 1; // 0x1 + field public static final int SESSION_EVENT_RX_RESUME = 2; // 0x2 + field public static final int SESSION_EVENT_TX_START = 3; // 0x3 + field public static final int SESSION_EVENT_TX_STOP = 4; // 0x4 + field public static final int SESSION_MODIFY_REQUEST_FAIL = 2; // 0x2 + field public static final int SESSION_MODIFY_REQUEST_INVALID = 3; // 0x3 + field public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1; // 0x1 } public final class ConnectionRequest implements android.os.Parcelable { - ctor public ConnectionRequest(android.telecomm.PhoneAccountHandle, java.lang.String, android.net.Uri, int, android.os.Bundle, int); + ctor public ConnectionRequest(android.telecomm.PhoneAccountHandle, android.net.Uri, int, android.os.Bundle, int); method public int describeContents(); method public android.telecomm.PhoneAccountHandle getAccountHandle(); - method public java.lang.String getCallId(); method public android.os.Bundle getExtras(); method public android.net.Uri getHandle(); method public int getHandlePresentation(); @@ -29041,32 +28965,6 @@ package android.telecomm { field public static final java.lang.String SERVICE_INTERFACE = "android.telecomm.ConnectionService"; } - public static abstract interface ConnectionService.CreateConnectionResponse { - method public abstract void onCancel(android.telecomm.ConnectionRequest); - method public abstract void onFailure(android.telecomm.ConnectionRequest, int, java.lang.String); - method public abstract void onSuccess(android.telecomm.ConnectionRequest, CONNECTION); - } - - public static abstract class ConnectionService.VideoCallProvider { - ctor public ConnectionService.VideoCallProvider(); - method public void changeCallDataUsage(int); - method public void changeCameraCapabilities(android.telecomm.CallCameraCapabilities); - method public void changePeerDimensions(int, int); - method public void handleCallSessionEvent(int); - method public void onRequestCallDataUsage(); - method public void onRequestCameraCapabilities(); - method public void onSendSessionModifyRequest(android.telecomm.VideoCallProfile); - method public void onSendSessionModifyResponse(android.telecomm.VideoCallProfile); - method public void onSetCamera(java.lang.String); - method public void onSetDeviceOrientation(int); - method public void onSetDisplaySurface(android.view.Surface); - method public void onSetPauseImage(java.lang.String); - method public void onSetPreviewSurface(android.view.Surface); - method public void onSetZoom(float); - method public void receiveSessionModifyRequest(android.telecomm.VideoCallProfile); - method public void receiveSessionModifyResponse(int, android.telecomm.VideoCallProfile, android.telecomm.VideoCallProfile); - } - public class GatewayInfo implements android.os.Parcelable { method public int describeContents(); method public android.net.Uri getGatewayHandle(); @@ -29077,87 +28975,8 @@ package android.telecomm { field public static final android.os.Parcelable.Creator CREATOR; } - public final class InCallAdapter { - method public void answerCall(java.lang.String, int); - method public void disconnectCall(java.lang.String); - method public void holdCall(java.lang.String); - method public void mute(boolean); - method public void phoneAccountClicked(java.lang.String); - method public void phoneAccountSelected(java.lang.String, android.telecomm.PhoneAccountHandle); - method public void playDtmfTone(java.lang.String, char); - method public void postDialContinue(java.lang.String, boolean); - method public void rejectCall(java.lang.String, boolean, java.lang.String); - method public void setAudioRoute(int); - method public void stopDtmfTone(java.lang.String); - method public void swapWithBackgroundCall(java.lang.String); - method public void turnProximitySensorOff(boolean); - method public void turnProximitySensorOn(); - method public void unholdCall(java.lang.String); - } - - public abstract class InCallService extends android.app.Service { - ctor public InCallService(); - method public android.telecomm.Phone getPhone(); - method public android.os.IBinder onBind(android.content.Intent); - method public void onPhoneCreated(android.telecomm.Phone); - method public void onPhoneDestroyed(android.telecomm.Phone); - } - - public static abstract class InCallService.VideoCall { - ctor public InCallService.VideoCall(); - method public abstract void requestCallDataUsage(); - method public abstract void requestCameraCapabilities(); - method public abstract void sendSessionModifyRequest(android.telecomm.VideoCallProfile); - method public abstract void sendSessionModifyResponse(android.telecomm.VideoCallProfile); - method public abstract void setCamera(java.lang.String); - method public abstract void setDeviceOrientation(int); - method public abstract void setDisplaySurface(android.view.Surface); - method public abstract void setPauseImage(java.lang.String); - method public abstract void setPreviewSurface(android.view.Surface); - method public abstract void setVideoCallListener(android.telecomm.InCallService.VideoCall.Listener); - method public abstract void setZoom(float); - field public static final int SESSION_EVENT_CAMERA_FAILURE = 5; // 0x5 - field public static final int SESSION_EVENT_CAMERA_READY = 6; // 0x6 - field public static final int SESSION_EVENT_RX_PAUSE = 1; // 0x1 - field public static final int SESSION_EVENT_RX_RESUME = 2; // 0x2 - field public static final int SESSION_EVENT_TX_START = 3; // 0x3 - field public static final int SESSION_EVENT_TX_STOP = 4; // 0x4 - field public static final int SESSION_MODIFY_REQUEST_FAIL = 2; // 0x2 - field public static final int SESSION_MODIFY_REQUEST_INVALID = 3; // 0x3 - field public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1; // 0x1 - } - - public static abstract class InCallService.VideoCall.Listener { - ctor public InCallService.VideoCall.Listener(); - method public abstract void onCallDataUsageChanged(int); - method public abstract void onCallSessionEvent(int); - method public abstract void onCameraCapabilitiesChanged(android.telecomm.CallCameraCapabilities); - method public abstract void onPeerDimensionsChanged(int, int); - method public abstract void onSessionModifyRequestReceived(android.telecomm.VideoCallProfile); - method public abstract void onSessionModifyResponseReceived(int, android.telecomm.VideoCallProfile, android.telecomm.VideoCallProfile); - } - - public final class Phone { - method public final void addListener(android.telecomm.Phone.Listener); - method public final android.telecomm.CallAudioState getAudioState(); - method public final java.util.List<android.telecomm.Call> getCalls(); - method public final void removeListener(android.telecomm.Phone.Listener); - method public final void setAudioRoute(int); - method public final void setMuted(boolean); - method public final void setProximitySensorOff(boolean); - method public final void setProximitySensorOn(); - } - - public static abstract class Phone.Listener { - ctor public Phone.Listener(); - method public void onAudioStateChanged(android.telecomm.Phone, android.telecomm.CallAudioState); - method public void onBringToForeground(android.telecomm.Phone, boolean); - method public void onCallAdded(android.telecomm.Phone, android.telecomm.Call); - method public void onCallRemoved(android.telecomm.Phone, android.telecomm.Call); - } - public class PhoneAccount implements android.os.Parcelable { - ctor public PhoneAccount(android.telecomm.PhoneAccountHandle, android.net.Uri, java.lang.String, int, int, java.lang.CharSequence, java.lang.CharSequence); + method public static android.telecomm.PhoneAccount.Builder builder(); method public int describeContents(); method public android.telecomm.PhoneAccountHandle getAccountHandle(); method public int getCapabilities(); @@ -29174,6 +28993,17 @@ package android.telecomm { field public static final android.os.Parcelable.Creator CREATOR; } + public static class PhoneAccount.Builder { + method public android.telecomm.PhoneAccount build(); + method public android.telecomm.PhoneAccount.Builder withAccountHandle(android.telecomm.PhoneAccountHandle); + method public android.telecomm.PhoneAccount.Builder withCapabilities(int); + method public android.telecomm.PhoneAccount.Builder withHandle(android.net.Uri); + method public android.telecomm.PhoneAccount.Builder withIconResId(int); + method public android.telecomm.PhoneAccount.Builder withLabel(java.lang.CharSequence); + method public android.telecomm.PhoneAccount.Builder withShortDescription(java.lang.CharSequence); + method public android.telecomm.PhoneAccount.Builder withSubscriptionNumber(java.lang.String); + } + public class PhoneAccountHandle implements android.os.Parcelable { ctor public PhoneAccountHandle(android.content.ComponentName, java.lang.String); method public int describeContents(); @@ -29183,6 +29013,31 @@ package android.telecomm { field public static final android.os.Parcelable.Creator CREATOR; } + public final class PhoneCapabilities { + method public static java.lang.String toString(int); + field public static final int ADD_CALL = 16; // 0x10 + field public static final int ALL = 3327; // 0xcff + field public static final int GENERIC_CONFERENCE = 128; // 0x80 + field public static final int HOLD = 1; // 0x1 + field public static final int MERGE_CALLS = 4; // 0x4 + field public static final int MUTE = 64; // 0x40 + field public static final int RESPOND_VIA_TEXT = 32; // 0x20 + field public static final int SUPPORTS_VT_LOCAL = 256; // 0x100 + field public static final int SUPPORTS_VT_REMOTE = 512; // 0x200 + field public static final int SUPPORT_HOLD = 2; // 0x2 + field public static final int SWAP_CALLS = 8; // 0x8 + field public static final int VoLTE = 1024; // 0x400 + field public static final int VoWIFI = 2048; // 0x800 + } + + public class PropertyPresentation { + ctor public PropertyPresentation(); + field public static final int ALLOWED = 1; // 0x1 + field public static final int PAYPHONE = 4; // 0x4 + field public static final int RESTRICTED = 2; // 0x2 + field public static final int UNKNOWN = 3; // 0x3 + } + public final class RemoteConnection { method public void abort(); method public void addListener(android.telecomm.RemoteConnection.Listener); @@ -29209,9 +29064,8 @@ package android.telecomm { method public void postDialContinue(boolean); method public void reject(); method public void removeListener(android.telecomm.RemoteConnection.Listener); - method public void setAudioState(android.telecomm.CallAudioState); + method public void setAudioState(android.telecomm.AudioState); method public void stopDtmfTone(); - method public void swapWithBackgroundCall(); method public void unhold(); } @@ -29239,18 +29093,13 @@ package android.telecomm { method public abstract void onResult(IN, OUT...); } - public abstract interface SimpleResponse { - method public abstract void onError(IN); - method public abstract void onResult(IN, OUT); - } - public final class StatusHints implements android.os.Parcelable { ctor public StatusHints(android.content.ComponentName, java.lang.CharSequence, int, android.os.Bundle); method public int describeContents(); method public android.content.ComponentName getComponentName(); method public android.os.Bundle getExtras(); method public android.graphics.drawable.Drawable getIcon(android.content.Context); - method public int getIconId(); + method public int getIconResId(); method public java.lang.CharSequence getLabel(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; @@ -29278,23 +29127,9 @@ package android.telecomm { field public static final java.lang.String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.intent.extra.START_CALL_WITH_VIDEO_STATE"; } - public class VideoCallImpl extends android.telecomm.InCallService.VideoCall { - method public void requestCallDataUsage(); - method public void requestCameraCapabilities(); - method public void sendSessionModifyRequest(android.telecomm.VideoCallProfile); - method public void sendSessionModifyResponse(android.telecomm.VideoCallProfile); - method public void setCamera(java.lang.String); - method public void setDeviceOrientation(int); - method public void setDisplaySurface(android.view.Surface); - method public void setPauseImage(java.lang.String); - method public void setPreviewSurface(android.view.Surface); - method public void setVideoCallListener(android.telecomm.InCallService.VideoCall.Listener); - method public void setZoom(float); - } - - public class VideoCallProfile implements android.os.Parcelable { - ctor public VideoCallProfile(int); - ctor public VideoCallProfile(int, int); + public class VideoProfile implements android.os.Parcelable { + ctor public VideoProfile(int); + ctor public VideoProfile(int, int); method public int describeContents(); method public int getQuality(); method public int getVideoState(); @@ -29306,8 +29141,8 @@ package android.telecomm { field public static final int QUALITY_MEDIUM = 2; // 0x2 } - public static class VideoCallProfile.VideoState { - ctor public VideoCallProfile.VideoState(); + public static class VideoProfile.VideoState { + ctor public VideoProfile.VideoState(); method public static boolean isAudioOnly(int); method public static boolean isBidirectional(int); method public static boolean isPaused(int); @@ -30813,6 +30648,7 @@ package android.text { public static class InputFilter.LengthFilter implements android.text.InputFilter { ctor public InputFilter.LengthFilter(int); method public java.lang.CharSequence filter(java.lang.CharSequence, int, int, android.text.Spanned, int, int); + method public int getMax(); } public abstract interface InputType { @@ -32621,6 +32457,7 @@ package android.util { method public void setTo(android.util.DisplayMetrics); method public void setToDefaults(); field public static final int DENSITY_400 = 400; // 0x190 + field public static final int DENSITY_560 = 560; // 0x230 field public static final int DENSITY_DEFAULT = 160; // 0xa0 field public static final int DENSITY_HIGH = 240; // 0xf0 field public static final int DENSITY_LOW = 120; // 0x78 @@ -36046,6 +35883,7 @@ package android.view.accessibility { method public android.view.accessibility.AccessibilityNodeInfo getLabelFor(); method public android.view.accessibility.AccessibilityNodeInfo getLabeledBy(); method public int getLiveRegion(); + method public int getMaxTextLength(); method public int getMovementGranularities(); method public java.lang.CharSequence getPackageName(); method public android.view.accessibility.AccessibilityNodeInfo getParent(); @@ -36109,6 +35947,7 @@ package android.view.accessibility { method public void setLabeledBy(android.view.View, int); method public void setLiveRegion(int); method public void setLongClickable(boolean); + method public void setMaxTextLength(int); method public void setMovementGranularities(int); method public void setMultiLine(boolean); method public void setPackageName(java.lang.CharSequence); diff --git a/cmds/media/src/com/android/commands/media/Media.java b/cmds/media/src/com/android/commands/media/Media.java index d9faf4c5980d..b13b0093db36 100644 --- a/cmds/media/src/com/android/commands/media/Media.java +++ b/cmds/media/src/com/android/commands/media/Media.java @@ -178,6 +178,13 @@ public class Media extends BaseCommand { public ControllerMonitor(ISessionController controller) { mController = controller; } + + @Override + public void onSessionDestroyed() { + System.out.println("onSessionDestroyed. Enter q to quit."); + + } + @Override public void onEvent(String event, Bundle extras) { System.out.println("onSessionEvent event=" + event + ", extras=" + extras); diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index c5e91e34160f..15152e522036 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -1703,6 +1703,10 @@ public final class Pm { throw new IllegalArgumentException("Missing ABI argument"); } + if ("-".equals(abi)) { + return abi; + } + final String[] supportedAbis = Build.SUPPORTED_ABIS; for (String supportedAbi : supportedAbis) { if (supportedAbi.equals(abi)) { diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index fcfeddd68820..21c8b7575ce1 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -31,6 +31,7 @@ import com.android.internal.policy.PolicyManager; import android.annotation.IntDef; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.app.admin.DevicePolicyManager; import android.content.ComponentCallbacks2; import android.content.ComponentName; @@ -747,8 +748,8 @@ public class Activity extends ContextThemeWrapper } }; - // Most recent call to setMediaPlaying(). - boolean mMediaPlaying; + // Most recent call to requestVisibleBehind(). + boolean mVisibleBehind; ArrayMap<String, LoaderManagerImpl> mAllLoaderManagers; LoaderManagerImpl mLoaderManager; @@ -5314,6 +5315,7 @@ public class Activity extends ContextThemeWrapper * * @hide */ + @SystemApi public void convertFromTranslucent() { try { mTranslucentCallback = null; @@ -5350,6 +5352,7 @@ public class Activity extends ContextThemeWrapper * * @hide */ + @SystemApi public boolean convertToTranslucent(TranslucentConversionListener callback, ActivityOptions options) { boolean drawComplete; @@ -5406,12 +5409,13 @@ public class Activity extends ContextThemeWrapper } /** - * Activities that want to show media behind a translucent activity above them must call this - * method anytime before a return from {@link #onPause()}. If this call is successful - * then the activity should continue to play media when {@link #onPause()} is called, but must - * stop playing and release resources prior to or within the call to - * {@link #onStopMediaPlaying()}. If this call returns false the activity must stop - * playing and release resources immediately. + * Activities that want to remain visible behind a translucent activity above them must call + * this method anytime before a return from {@link #onPause()}. If this call is successful + * then the activity will remain visible when {@link #onPause()} is called, and can continue to + * play media in the background, but it must stop playing and release resources prior to or + * within the call to {@link #onVisibleBehindCancelled()}. If this call returns false, the + * activity will not be visible in the background, and must release any media resources + * immediately. * * <p>Only fullscreen opaque activities may make this call. I.e. this call is a nop * for dialog and translucent activities. @@ -5419,85 +5423,86 @@ public class Activity extends ContextThemeWrapper * <p>False will be returned any time this method is call between the return of onPause and * the next call to onResume. * - * @param playing true to notify the system that media is starting or continuing playing, - * false to indicate that media has stopped or is stopping. Resources must - * be released when passing false to this method. - * @return the resulting play state. If true the activity may continue playing media beyond - * {@link #onPause()}, if false then the caller must stop playing and immediately - * release all media resources. Returning false may occur in lieu of a call to - * onReleaseMediaResources() so the return value must be checked. + * @param visible true to notify the system that the activity wishes to be visible behind other + * translucent activities, false to indicate otherwise. Resources must be + * released when passing false to this method. + * @return the resulting visibiity state. If true the activity may remain visible beyond + * {@link #onPause()}. If false then the activity may not count on being visible behind + * other translucent activities, and must stop any media playback and release resources. + * Returning false may occur in lieu of a call to onVisibleBehindCancelled() so the return + * value must be checked. * - * @see #isBackgroundMediaPlaying() - * @see #onStopMediaPlaying() - * @see #onBackgroundMediaPlayingChanged(boolean) + * @see #onVisibleBehindCancelled() + * @see #onBackgroundVisibleBehindChanged(boolean) */ - public boolean setMediaPlaying(boolean playing) { + public boolean requestVisibleBehind(boolean visible) { if (!mResumed) { - // Do not permit paused or stopped activities to start playing. - playing = false; + // Do not permit paused or stopped activities to do this. + visible = false; } try { - mMediaPlaying = ActivityManagerNative.getDefault().setMediaPlaying(mToken, playing) && - playing; + mVisibleBehind = ActivityManagerNative.getDefault() + .requestVisibleBehind(mToken, visible) && visible; } catch (RemoteException e) { - mMediaPlaying = false; + mVisibleBehind = false; } - return mMediaPlaying; + return mVisibleBehind; } /** - * Called when a translucent activity over playing media is becoming opaque or another - * activity is being launched. Activities that call {@link #setMediaPlaying(boolean)} - * must implement this method to at the minimum call - * <code>super.onStopMediaPlayback()</code>. + * Called when a translucent activity over this activity is becoming opaque or another + * activity is being launched. Activities that override this method must call + * <code>super.onVisibleBehindCancelled()</code> or a SuperNotCalledException will be thrown. * - * <p>When this method is called the activity has 500 msec to release the media resources. + * <p>When this method is called the activity has 500 msec to release any resources it may be + * using while visible in the background. * If the activity has not returned from this method in 500 msec the system will destroy - * the activity and kill the process in order to recover the media resources for another + * the activity and kill the process in order to recover the resources for another * process. Otherwise {@link #onStop()} will be called following return. * - * @see #setMediaPlaying(boolean) - * @see #isBackgroundMediaPlaying() - * @see #onBackgroundMediaPlayingChanged(boolean) + * @see #requestVisibleBehind(boolean) + * @see #onBackgroundVisibleBehindChanged(boolean) */ - public void onStopMediaPlaying() { + public void onVisibleBehindCancelled() { mCalled = true; } /** - * Translucent activities may call this to determine if there is an activity below it that - * is playing media. + * Translucent activities may call this to determine if there is an activity below them that + * is currently set to be visible in the background. * - * @return true if media is playing according to the most recent call to - * {@link #setMediaPlaying(boolean)}, false otherwise. + * @return true if an activity below is set to visible according to the most recent call to + * {@link #requestVisibleBehind(boolean)}, false otherwise. * - * @see #setMediaPlaying(boolean) - * @see #onStopMediaPlaying() - * @see #onBackgroundMediaPlayingChanged(boolean) + * @see #requestVisibleBehind(boolean) + * @see #onVisibleBehindCancelled() + * @see #onBackgroundVisibleBehindChanged(boolean) * @hide */ - public boolean isBackgroundMediaPlaying() { + @SystemApi + public boolean isBackgroundVisibleBehind() { try { - return ActivityManagerNative.getDefault().isBackgroundMediaPlaying(mToken); + return ActivityManagerNative.getDefault().isBackgroundVisibleBehind(mToken); } catch (RemoteException e) { } return false; } /** - * The topmost foreground activity will receive this call when an activity below it either - * starts or stops playing media. + * The topmost foreground activity will receive this call when the background visibility state + * of the activity below it changes. * - * This call may be a consequence of {@link #setMediaPlaying(boolean)} or might be + * This call may be a consequence of {@link #requestVisibleBehind(boolean)} or might be * due to a background activity finishing itself. * - * @param playing true if media playback is starting, false if it is stopping. + * @param visible true if a background activity is visible, false otherwise. * - * @see #setMediaPlaying(boolean) - * @see #isBackgroundMediaPlaying() - * @see #onStopMediaPlaying() + * @see #requestVisibleBehind(boolean) + * @see #onVisibleBehindCancelled() + * @hide */ - public void onBackgroundMediaPlayingChanged(boolean playing) { + @SystemApi + public void onBackgroundVisibleBehindChanged(boolean visible) { } /** @@ -6114,6 +6119,7 @@ public class Activity extends ContextThemeWrapper * * @hide */ + @SystemApi public interface TranslucentConversionListener { /** * Callback made following {@link Activity#convertToTranslucent} once all visible Activities diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 311a8f55769d..31cb4d6435f0 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1942,9 +1942,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } - case DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION: { + case KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); - dismissKeyguardOnNextActivity(); + keyguardWaitingForActivityDrawn(); reply.writeNoException(); return true; } @@ -2197,29 +2197,29 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } - case SET_MEDIA_PLAYING_TRANSACTION: { + case REQUEST_VISIBLE_BEHIND_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); boolean enable = data.readInt() > 0; - boolean success = setMediaPlaying(token, enable); + boolean success = requestVisibleBehind(token, enable); reply.writeNoException(); reply.writeInt(success ? 1 : 0); return true; } - case IS_BG_MEDIA_PLAYING_TRANSACTION: { + case IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); - final boolean enabled = isBackgroundMediaPlaying(token); + final boolean enabled = isBackgroundVisibleBehind(token); reply.writeNoException(); reply.writeInt(enabled ? 1 : 0); return true; } - case MEDIA_RESOURCES_RELEASED_TRANSACTION: { + case BACKGROUND_RESOURCES_RELEASED_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); - mediaResourcesReleased(token); + backgroundResourcesReleased(token); reply.writeNoException(); return true; } @@ -4738,11 +4738,11 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } - public void dismissKeyguardOnNextActivity() throws RemoteException { + public void keyguardWaitingForActivityDrawn() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); - mRemote.transact(DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION, data, reply, 0); + mRemote.transact(KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -5101,13 +5101,13 @@ class ActivityManagerProxy implements IActivityManager } @Override - public boolean setMediaPlaying(IBinder token, boolean playing) throws RemoteException { + public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); - data.writeInt(playing ? 1 : 0); - mRemote.transact(SET_MEDIA_PLAYING_TRANSACTION, data, reply, 0); + data.writeInt(visible ? 1 : 0); + mRemote.transact(REQUEST_VISIBLE_BEHIND_TRANSACTION, data, reply, 0); reply.readException(); boolean success = reply.readInt() > 0; data.recycle(); @@ -5116,26 +5116,27 @@ class ActivityManagerProxy implements IActivityManager } @Override - public boolean isBackgroundMediaPlaying(IBinder token) throws RemoteException { + public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); - mRemote.transact(IS_BG_MEDIA_PLAYING_TRANSACTION, data, reply, 0); + mRemote.transact(IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION, data, reply, 0); reply.readException(); - final boolean playing = reply.readInt() > 0; + final boolean visible = reply.readInt() > 0; data.recycle(); reply.recycle(); - return playing; + return visible; } @Override - public void mediaResourcesReleased(IBinder token) throws RemoteException { + public void backgroundResourcesReleased(IBinder token) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); - mRemote.transact(MEDIA_RESOURCES_RELEASED_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); + mRemote.transact(BACKGROUND_RESOURCES_RELEASED_TRANSACTION, data, reply, + IBinder.FLAG_ONEWAY); reply.readException(); data.recycle(); reply.recycle(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 3a764fa9c797..1b82d8e9cc5b 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1155,13 +1155,13 @@ public final class ActivityThread { } @Override - public void scheduleStopMediaPlaying(IBinder token) { - sendMessage(H.STOP_MEDIA_PLAYING, token); + public void scheduleCancelVisibleBehind(IBinder token) { + sendMessage(H.CANCEL_VISIBLE_BEHIND, token); } @Override - public void scheduleBackgroundMediaPlayingChanged(IBinder token, boolean playing) { - sendMessage(H.BACKGROUND_MEDIA_PLAYING_CHANGED, token, playing ? 1 : 0); + public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean visible) { + sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0); } public void scheduleEnterAnimationComplete(IBinder token) { @@ -1217,8 +1217,8 @@ public final class ActivityThread { public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144; public static final int INSTALL_PROVIDER = 145; public static final int ON_NEW_ACTIVITY_OPTIONS = 146; - public static final int STOP_MEDIA_PLAYING = 147; - public static final int BACKGROUND_MEDIA_PLAYING_CHANGED = 148; + public static final int CANCEL_VISIBLE_BEHIND = 147; + public static final int BACKGROUND_VISIBLE_BEHIND_CHANGED = 148; public static final int ENTER_ANIMATION_COMPLETE = 149; String codeToString(int code) { @@ -1270,8 +1270,8 @@ public final class ActivityThread { case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE"; case INSTALL_PROVIDER: return "INSTALL_PROVIDER"; case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS"; - case STOP_MEDIA_PLAYING: return "STOP_MEDIA_PLAYING"; - case BACKGROUND_MEDIA_PLAYING_CHANGED: return "BACKGROUND_MEDIA_PLAYING_CHANGED"; + case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND"; + case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED"; case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE"; } } @@ -1491,11 +1491,11 @@ public final class ActivityThread { Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj; onNewActivityOptions(pair.first, pair.second); break; - case STOP_MEDIA_PLAYING: - handleStopMediaPlaying((IBinder) msg.obj); + case CANCEL_VISIBLE_BEHIND: + handleCancelVisibleBehind((IBinder) msg.obj); break; - case BACKGROUND_MEDIA_PLAYING_CHANGED: - handleOnBackgroundMediaPlayingChanged((IBinder) msg.obj, msg.arg1 > 0); + case BACKGROUND_VISIBLE_BEHIND_CHANGED: + handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0); break; case ENTER_ANIMATION_COMPLETE: handleEnterAnimationComplete((IBinder) msg.obj); @@ -2488,31 +2488,31 @@ public final class ActivityThread { } } - public void handleStopMediaPlaying(IBinder token) { + public void handleCancelVisibleBehind(IBinder token) { ActivityClientRecord r = mActivities.get(token); if (r != null) { final Activity activity = r.activity; - if (activity.mMediaPlaying) { + if (activity.mVisibleBehind) { activity.mCalled = false; - activity.onStopMediaPlaying(); + activity.onVisibleBehindCancelled(); // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed. if (!activity.mCalled) { throw new SuperNotCalledException("Activity " + activity.getLocalClassName() + - " did not call through to super.onStopMediaPlayback()"); + " did not call through to super.onVisibleBehindCancelled()"); } - activity.mMediaPlaying = false; + activity.mVisibleBehind = false; } } try { - ActivityManagerNative.getDefault().mediaResourcesReleased(token); + ActivityManagerNative.getDefault().backgroundResourcesReleased(token); } catch (RemoteException e) { } } - public void handleOnBackgroundMediaPlayingChanged(IBinder token, boolean playing) { + public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) { ActivityClientRecord r = mActivities.get(token); if (r != null) { - r.activity.onBackgroundMediaPlayingChanged(playing); + r.activity.onBackgroundVisibleBehindChanged(visible); } } diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java index f7c0d23f9494..7d2f677dbcc8 100644 --- a/core/java/android/app/ActivityTransitionCoordinator.java +++ b/core/java/android/app/ActivityTransitionCoordinator.java @@ -239,7 +239,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { return mWindow; } - protected ViewGroup getDecor() { + public ViewGroup getDecor() { return (mWindow == null) ? null : (ViewGroup) mWindow.getDecorView(); } diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java index 4f3b02c0a86e..613e24854dbd 100644 --- a/core/java/android/app/ActivityTransitionState.java +++ b/core/java/android/app/ActivityTransitionState.java @@ -17,9 +17,11 @@ package android.app; import android.os.Bundle; import android.os.ResultReceiver; +import android.transition.Transition; import android.util.ArrayMap; import android.util.SparseArray; import android.view.View; +import android.view.ViewGroup; import android.view.Window; import java.lang.ref.WeakReference; @@ -245,13 +247,23 @@ class ActivityTransitionState { } else { if (!mHasExited) { mHasExited = true; + Transition enterViewsTransition = null; + ViewGroup decor = null; if (mEnterTransitionCoordinator != null) { + enterViewsTransition = mEnterTransitionCoordinator.getEnterViewsTransition(); + decor = mEnterTransitionCoordinator.getDecor(); mEnterTransitionCoordinator.cancelEnter(); mEnterTransitionCoordinator = null; + if (enterViewsTransition != null && decor != null) { + enterViewsTransition.pause(decor); + } } ExitTransitionCoordinator exitCoordinator = new ExitTransitionCoordinator(activity, mEnteringNames, null, null, true); + if (enterViewsTransition != null && decor != null) { + enterViewsTransition.resume(decor); + } exitCoordinator.startExit(activity.mResultCode, activity.mResultData); } return true; diff --git a/core/java/android/app/AlarmClockInfo.java b/core/java/android/app/AlarmClockInfo.java deleted file mode 100644 index 0ccaf02995ae..000000000000 --- a/core/java/android/app/AlarmClockInfo.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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 - */ - -package android.app; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * An immutable description of an alarm clock. - * - * @see AlarmManager#setAlarmClock - * @see AlarmManager#getNextAlarmClock - */ -public class AlarmClockInfo implements Parcelable { - - private final long mTriggerTime; - private final PendingIntent mShowIntent; - - /** - * Creates a new alarm clock description. - * - * @param triggerTime time at which the underlying alarm is triggered in wall time milliseconds - * since the epoch - * @param showIntent an intent that can be used to show or edit details of - * the alarm clock. - */ - public AlarmClockInfo(long triggerTime, PendingIntent showIntent) { - mTriggerTime = triggerTime; - mShowIntent = showIntent; - } - - /** - * Use the {@link #CREATOR} - * @hide - */ - AlarmClockInfo(Parcel in) { - mTriggerTime = in.readLong(); - mShowIntent = in.readParcelable(PendingIntent.class.getClassLoader()); - } - - /** - * Returns the time at which the alarm is going to trigger. - * - * This value is UTC wall clock time in milliseconds, as returned by - * {@link System#currentTimeMillis()} for example. - */ - public long getTriggerTime() { - return mTriggerTime; - } - - /** - * Returns an intent intent that can be used to show or edit details of the alarm clock in - * the application that scheduled it. - * - * <p class="note">Beware that any application can retrieve and send this intent, potentially - * with additional fields filled in. See - * {@link PendingIntent#send(android.content.Context, int, android.content.Intent) - * PendingIntent.send()} and {@link android.content.Intent#fillIn Intent.fillIn()} - * for details. - */ - public PendingIntent getShowIntent() { - return mShowIntent; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeLong(mTriggerTime); - dest.writeParcelable(mShowIntent, flags); - } - - public static final Creator<AlarmClockInfo> CREATOR = new Creator<AlarmClockInfo>() { - @Override - public AlarmClockInfo createFromParcel(Parcel in) { - return new AlarmClockInfo(in); - } - - @Override - public AlarmClockInfo[] newArray(int size) { - return new AlarmClockInfo[size]; - } - }; -} diff --git a/core/java/android/app/AlarmClockInfo.aidl b/core/java/android/app/AlarmManager.aidl index 58a3644d8928..c9547b28740a 100644 --- a/core/java/android/app/AlarmClockInfo.aidl +++ b/core/java/android/app/AlarmManager.aidl @@ -16,4 +16,4 @@ package android.app; -parcelable AlarmClockInfo; +parcelable AlarmManager.AlarmClockInfo; diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index fa2d64c9c1a5..a64e0ed5bb30 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -20,9 +20,12 @@ import android.annotation.SdkConstant; import android.content.Context; import android.content.Intent; import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; import android.os.RemoteException; import android.os.UserHandle; import android.os.WorkSource; +import android.os.Parcelable.Creator; /** * This class provides access to the system alarm services. These allow you @@ -579,4 +582,85 @@ public class AlarmManager return null; } } + + /** + * An immutable description of an alarm clock. + * + * @see AlarmManager#setAlarmClock + * @see AlarmManager#getNextAlarmClock + */ + public static final class AlarmClockInfo implements Parcelable { + + private final long mTriggerTime; + private final PendingIntent mShowIntent; + + /** + * Creates a new alarm clock description. + * + * @param triggerTime time at which the underlying alarm is triggered in wall time + * milliseconds since the epoch + * @param showIntent an intent that can be used to show or edit details of + * the alarm clock. + */ + public AlarmClockInfo(long triggerTime, PendingIntent showIntent) { + mTriggerTime = triggerTime; + mShowIntent = showIntent; + } + + /** + * Use the {@link #CREATOR} + * @hide + */ + AlarmClockInfo(Parcel in) { + mTriggerTime = in.readLong(); + mShowIntent = in.readParcelable(PendingIntent.class.getClassLoader()); + } + + /** + * Returns the time at which the alarm is going to trigger. + * + * This value is UTC wall clock time in milliseconds, as returned by + * {@link System#currentTimeMillis()} for example. + */ + public long getTriggerTime() { + return mTriggerTime; + } + + /** + * Returns an intent intent that can be used to show or edit details of the alarm clock in + * the application that scheduled it. + * + * <p class="note">Beware that any application can retrieve and send this intent, + * potentially with additional fields filled in. See + * {@link PendingIntent#send(android.content.Context, int, android.content.Intent) + * PendingIntent.send()} and {@link android.content.Intent#fillIn Intent.fillIn()} + * for details. + */ + public PendingIntent getShowIntent() { + return mShowIntent; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeLong(mTriggerTime); + dest.writeParcelable(mShowIntent, flags); + } + + public static final Creator<AlarmClockInfo> CREATOR = new Creator<AlarmClockInfo>() { + @Override + public AlarmClockInfo createFromParcel(Parcel in) { + return new AlarmClockInfo(in); + } + + @Override + public AlarmClockInfo[] newArray(int size) { + return new AlarmClockInfo[size]; + } + }; + } } diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index a52186a446b5..a6b3608e6095 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -451,8 +451,8 @@ public class AppOpsManager { null, //VIBRATE null, //READ_CONTACTS null, //WRITE_CONTACTS - null, //READ_CALL_LOG - null, //WRITE_CALL_LOG + UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG + UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG null, //READ_CALENDAR null, //WRITE_CALENDAR UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index e9d4bd9763e4..52b69e12eb84 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -648,21 +648,21 @@ public abstract class ApplicationThreadNative extends Binder return true; } - case STOP_MEDIA_PLAYING_TRANSACTION: + case CANCEL_VISIBLE_BEHIND_TRANSACTION: { data.enforceInterface(IApplicationThread.descriptor); IBinder token = data.readStrongBinder(); - scheduleStopMediaPlaying(token); + scheduleCancelVisibleBehind(token); reply.writeNoException(); return true; } - case BACKGROUND_MEDIA_PLAYING_CHANGED_TRANSACTION: + case BACKGROUND_VISIBLE_BEHIND_CHANGED_TRANSACTION: { data.enforceInterface(IApplicationThread.descriptor); IBinder token = data.readStrongBinder(); boolean enabled = data.readInt() > 0; - scheduleBackgroundMediaPlayingChanged(token, enabled); + scheduleBackgroundVisibleBehindChanged(token, enabled); reply.writeNoException(); return true; } @@ -1334,21 +1334,23 @@ class ApplicationThreadProxy implements IApplicationThread { } @Override - public void scheduleStopMediaPlaying(IBinder token) throws RemoteException { + public void scheduleCancelVisibleBehind(IBinder token) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); - mRemote.transact(STOP_MEDIA_PLAYING_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); + mRemote.transact(CANCEL_VISIBLE_BEHIND_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } @Override - public void scheduleBackgroundMediaPlayingChanged(IBinder token, boolean enabled) throws RemoteException { + public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled) + throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); data.writeInt(enabled ? 1 : 0); - mRemote.transact(BACKGROUND_MEDIA_PLAYING_CHANGED_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); + mRemote.transact(BACKGROUND_VISIBLE_BEHIND_CHANGED_TRANSACTION, data, null, + IBinder.FLAG_ONEWAY); data.recycle(); } diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java index 54c5bc441ef5..75ecbd931b5d 100644 --- a/core/java/android/app/EnterTransitionCoordinator.java +++ b/core/java/android/app/EnterTransitionCoordinator.java @@ -59,6 +59,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { private boolean mIsViewsTransitionComplete; private boolean mIsSharedElementTransitionComplete; private ArrayList<Matrix> mSharedElementParentMatrices; + private Transition mEnterViewsTransition; public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver, ArrayList<String> sharedElementNames, boolean isReturning) { @@ -104,6 +105,10 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { triggerViewsReady(mapNamedElements(accepted, localNames)); } + public Transition getEnterViewsTransition() { + return mEnterViewsTransition; + } + @Override protected void viewsReady(ArrayMap<String, View> sharedElements) { super.viewsReady(sharedElements); @@ -399,10 +404,17 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { viewTransitionComplete(); } else { viewsTransition.forceVisibility(View.INVISIBLE, true); - setTransitionAlpha(mTransitioningViews, 1); viewsTransition.addListener(new ContinueTransitionListener() { @Override + public void onTransitionStart(Transition transition) { + mEnterViewsTransition = transition; + setTransitionAlpha(mTransitioningViews, 1); + super.onTransitionStart(transition); + } + + @Override public void onTransitionEnd(Transition transition) { + mEnterViewsTransition = null; transition.removeListener(this); viewTransitionComplete(); super.onTransitionEnd(transition); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 772e13235fd7..2dbc4ea588aa 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -383,7 +383,7 @@ public interface IActivityManager extends IInterface { public void showBootMessage(CharSequence msg, boolean always) throws RemoteException; - public void dismissKeyguardOnNextActivity() throws RemoteException; + public void keyguardWaitingForActivityDrawn() throws RemoteException; public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) throws RemoteException; @@ -443,9 +443,9 @@ public interface IActivityManager extends IInterface { public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values) throws RemoteException; - public boolean setMediaPlaying(IBinder token, boolean playing) throws RemoteException; - public boolean isBackgroundMediaPlaying(IBinder token) throws RemoteException; - public void mediaResourcesReleased(IBinder token) throws RemoteException; + public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException; + public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException; + public void backgroundResourcesReleased(IBinder token) throws RemoteException; public void notifyLaunchTaskBehindComplete(IBinder token) throws RemoteException; public void notifyEnterAnimationComplete(IBinder token) throws RemoteException; @@ -688,7 +688,6 @@ public interface IActivityManager extends IInterface { int UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+135; int GET_PROCESS_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+136; int SHOW_BOOT_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+137; - int DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+138; int KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+139; int GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+140; int REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+141; @@ -754,10 +753,11 @@ public interface IActivityManager extends IInterface { int STOP_LOCK_TASK_BY_CURRENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+222; int FINISH_VOICE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+223; int IS_TOP_OF_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+224; - int SET_MEDIA_PLAYING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+225; - int IS_BG_MEDIA_PLAYING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+226; - int MEDIA_RESOURCES_RELEASED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+227; + int REQUEST_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+225; + int IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+226; + int BACKGROUND_RESOURCES_RELEASED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+227; int NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+228; int START_ACTIVITY_FROM_RECENTS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 229; int NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+230; + int KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+231; } diff --git a/core/java/android/app/IAlarmManager.aidl b/core/java/android/app/IAlarmManager.aidl index fb33706dde34..194082e2d9f4 100644 --- a/core/java/android/app/IAlarmManager.aidl +++ b/core/java/android/app/IAlarmManager.aidl @@ -16,7 +16,7 @@ */ package android.app; -import android.app.AlarmClockInfo; +import android.app.AlarmManager; import android.app.PendingIntent; import android.os.WorkSource; @@ -29,11 +29,11 @@ interface IAlarmManager { /** windowLength == 0 means exact; windowLength < 0 means the let the OS decide */ void set(int type, long triggerAtTime, long windowLength, long interval, in PendingIntent operation, in WorkSource workSource, - in AlarmClockInfo alarmClock); + in AlarmManager.AlarmClockInfo alarmClock); boolean setTime(long millis); void setTimeZone(String zone); void remove(in PendingIntent operation); - AlarmClockInfo getNextAlarmClock(int userId); + AlarmManager.AlarmClockInfo getNextAlarmClock(int userId); } diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index 4a1fda4e8dde..01b6fdfdc238 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -145,8 +145,8 @@ public interface IApplicationThread extends IInterface { void setProcessState(int state) throws RemoteException; void scheduleInstallProvider(ProviderInfo provider) throws RemoteException; void updateTimePrefs(boolean is24Hour) throws RemoteException; - void scheduleStopMediaPlaying(IBinder token) throws RemoteException; - void scheduleBackgroundMediaPlayingChanged(IBinder token, boolean enabled) throws RemoteException; + void scheduleCancelVisibleBehind(IBinder token) throws RemoteException; + void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled) throws RemoteException; void scheduleEnterAnimationComplete(IBinder token) throws RemoteException; String descriptor = "android.app.IApplicationThread"; @@ -202,7 +202,7 @@ public interface IApplicationThread extends IInterface { int SET_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+49; int SCHEDULE_INSTALL_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+50; int UPDATE_TIME_PREFS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+51; - int STOP_MEDIA_PLAYING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+52; - int BACKGROUND_MEDIA_PLAYING_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+53; + int CANCEL_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+52; + int BACKGROUND_VISIBLE_BEHIND_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+53; int ENTER_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+54; } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 90b8b869fd3c..5f58839a81c4 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -279,6 +279,7 @@ public class Notification implements Parcelable * * @deprecated Use {@link #audioAttributes} instead. */ + @Deprecated public static final int STREAM_DEFAULT = -1; /** @@ -288,6 +289,7 @@ public class Notification implements Parcelable * * @deprecated Use {@link #audioAttributes} instead. */ + @Deprecated public int audioStreamType = STREAM_DEFAULT; /** @@ -2193,6 +2195,7 @@ public class Notification implements Parcelable * @deprecated use {@link #setSound(Uri, AudioAttributes)} instead. * @see Notification#sound */ + @Deprecated public Builder setSound(Uri sound, int streamType) { mSound = sound; mAudioStreamType = streamType; @@ -2574,9 +2577,21 @@ public class Notification implements Parcelable } private RemoteViews applyStandardTemplate(int resId, boolean fitIn1U) { + final boolean largeFontScale + = mContext.getResources().getConfiguration().fontScale >= 1.25f; + Bitmap profileIcon = getProfileBadge(); RemoteViews contentView = new BuilderRemoteViews(mContext.getPackageName(), mOriginatingUserId, resId); + + if (largeFontScale) { + // Make a little extra room for the bigger text. + final int margin = (int) mContext.getResources() + .getDimensionPixelSize(R.dimen.notification_large_font_vert_pad); + contentView.setViewPadding(R.id.line1, 0, margin, 0, 0); + contentView.setViewPadding(R.id.line3, 0, 0, 0, margin); + } + boolean showLine3 = false; boolean showLine2 = false; @@ -3218,7 +3233,7 @@ public class Notification implements Parcelable } private int getBigTextLayoutResource() { - return R.layout.notification_template_material_big_text; + return getBigBaseLayoutResource(); } private int getInboxLayoutResource() { diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java index f79eb04af0f2..0a255f7f1af1 100644 --- a/core/java/android/app/UiModeManager.java +++ b/core/java/android/app/UiModeManager.java @@ -125,15 +125,15 @@ public class UiModeManager { public static final int ENABLE_CAR_MODE_GO_CAR_HOME = 0x0001; /** - * Flag for use with {@link #enableCarMode(int)}: do not hold full wake lock - * while in car mode. By default, when this flag is not set, the system may hold - * a full wake lock to keep the screen turned on while in car mode. - * Setting this flag disables such behavior and the screen may be turned off if - * there is no other user activity and no other full wake lock held. + * Flag for use with {@link #enableCarMode(int)}: allow sleep mode while in car mode. + * By default, when this flag is not set, the system may hold a full wake lock to keep the + * screen turned on and prevent the system from entering sleep mode while in car mode. + * Setting this flag disables such behavior and the system may enter sleep mode + * if there is no other user activity and no other wake lock held. * Setting this flag can be relevant for a car dock application that does not require the * screen kept on. */ - public static final int ENABLE_CAR_MODE_NO_WAKE_LOCK = 0x0002; + public static final int ENABLE_CAR_MODE_ALLOW_SLEEP = 0x0002; /** * Force device into car mode, like it had been placed in the car dock. diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 42b8dbf1a7f5..f0b609aec1ea 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -1428,6 +1428,9 @@ public final class BluetoothAdapter { if (VDBG) Log.d(TAG, "onBluetoothServiceDown: " + mService); synchronized (mManagerCallback) { mService = null; + mLeScanClients.clear(); + if (sBluetoothLeAdvertiser != null) sBluetoothLeAdvertiser.cleanup(); + if (sBluetoothLeScanner != null) sBluetoothLeScanner.cleanup(); for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){ try { if (cb != null) { diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java index 5a39dd6b3ceb..c8df60e800f1 100644 --- a/core/java/android/bluetooth/BluetoothGattServer.java +++ b/core/java/android/bluetooth/BluetoothGattServer.java @@ -519,6 +519,7 @@ public final class BluetoothGattServer implements BluetoothProfile { * @param characteristic The local characteristic that has been updated * @param confirm true to request confirmation from the client (indication), * false to send a notification + * @throws IllegalArgumentException * @return true, if the notification has been triggered successfully */ public boolean notifyCharacteristicChanged(BluetoothDevice device, @@ -529,6 +530,11 @@ public final class BluetoothGattServer implements BluetoothProfile { BluetoothGattService service = characteristic.getService(); if (service == null) return false; + if (characteristic.getValue() == null) { + throw new IllegalArgumentException("Chracteristic value is empty. Use " + + "BluetoothGattCharacteristic#setvalue to update"); + } + try { mService.sendNotification(mServerIf, device.getAddress(), service.getType(), service.getInstanceId(), diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java index 331ebfcf7244..f6315ac3e45f 100644 --- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java +++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java @@ -175,6 +175,15 @@ public final class BluetoothLeAdvertiser { } } + /** + * Cleans up advertise clients. Should be called when bluetooth is down. + * + * @hide + */ + public void cleanup() { + mLeAdvertisers.clear(); + } + // Compute the size of the advertise data. private int totalBytes(AdvertiseData data) { if (data == null) { diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java index 7c3cbc6163bb..988cea5edb4b 100644 --- a/core/java/android/bluetooth/le/BluetoothLeScanner.java +++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java @@ -209,6 +209,15 @@ public final class BluetoothLeScanner { } /** + * Cleans up scan clients. Should be called when bluetooth is down. + * + * @hide + */ + public void cleanup() { + mLeScanClients.clear(); + } + + /** * Bluetooth GATT interface callbacks */ private static class BleScanCallbackWrapper extends BluetoothGattCallbackWrapper { diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java index e7f33ff11683..2f3d06fc4bcf 100644 --- a/core/java/android/bluetooth/le/ScanRecord.java +++ b/core/java/android/bluetooth/le/ScanRecord.java @@ -257,9 +257,11 @@ public final class ScanRecord { } return new ScanRecord(serviceUuids, manufacturerData, serviceData, advertiseFlag, txPowerLevel, localName, scanRecord); - } catch (IndexOutOfBoundsException e) { + } catch (Exception e) { Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord)); - return null; + // As the record is invalid, ignore all the parsed results for this packet + // and return an empty record with raw scanRecord bytes in results + return new ScanRecord(null, null, null, -1, Integer.MIN_VALUE, null, scanRecord); } } diff --git a/core/java/android/bluetooth/le/Utils.java b/core/java/android/bluetooth/le/Utils.java index 8598dd7772bd..ccdae6964697 100644 --- a/core/java/android/bluetooth/le/Utils.java +++ b/core/java/android/bluetooth/le/Utils.java @@ -44,7 +44,7 @@ public class Utils { StringBuilder buffer = new StringBuilder(); buffer.append('{'); for (int i = 0; i < array.size(); ++i) { - buffer.append(array.keyAt(i)).append("=").append(array.valueAt(i)); + buffer.append(array.keyAt(i)).append("=").append(Arrays.toString(array.valueAt(i))); } buffer.append('}'); return buffer.toString(); diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 974ff136f217..abe4f0a19001 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -3874,15 +3874,15 @@ public class Intent implements Parcelable, Cloneable { /** * By default a document created by {@link #FLAG_ACTIVITY_NEW_DOCUMENT} will * have its entry in recent tasks removed when the user closes it (with back - * or however else it may finish()). If you would like to instead allow the + * or however else it may finish()). If you would like to instead allow the * document to be kept in recents so that it can be re-launched, you can use - * this flag. When set and the task's activity is finished, the recents entry - * will remain in the interface for the user to re-launch it, like a recents - * entry for a top-level application. - * - * <p>The receiving activity can override this request with - * {@link android.R.styleable#AndroidManifestActivity_autoRemoveFromRecents} - * or by explcitly calling {@link android.app.Activity#finishAndRemoveTask() + * this flag. When set and the task's activity is finished, the recents + * entry will remain in the interface for the user to re-launch it, like a + * recents entry for a top-level application. + * <p> + * The receiving activity can override this request with + * {@link android.R.attr#autoRemoveFromRecents} or by explcitly calling + * {@link android.app.Activity#finishAndRemoveTask() * Activity.finishAndRemoveTask()}. */ public static final int FLAG_ACTIVITY_RETAIN_IN_RECENTS = 0x00002000; diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java index cd4a7a0ecb7d..e3c5449ee4b3 100644 --- a/core/java/android/content/IntentFilter.java +++ b/core/java/android/content/IntentFilter.java @@ -1184,13 +1184,9 @@ public class IntentFilter implements Parcelable { * {@link #MATCH_CATEGORY_MASK} and {@link #MATCH_ADJUSTMENT_MASK}), * or one of the error codes {@link #NO_MATCH_TYPE} if the type didn't match, * {@link #NO_MATCH_DATA} if the scheme/path didn't match, - * {@link #NO_MATCH_ACTION if the action didn't match, or + * {@link #NO_MATCH_ACTION} if the action didn't match, or * {@link #NO_MATCH_CATEGORY} if one or more categories didn't match. * - * @return How well the filter matches. Negative if it doesn't match, - * zero or positive positive value if it does with a higher - * value representing a better match. - * * @see #match(String, String, String, android.net.Uri , Set, String) */ public final int match(ContentResolver resolver, Intent intent, @@ -1218,7 +1214,7 @@ public class IntentFilter implements Parcelable { * {@link #MATCH_CATEGORY_MASK} and {@link #MATCH_ADJUSTMENT_MASK}), * or one of the error codes {@link #NO_MATCH_TYPE} if the type didn't match, * {@link #NO_MATCH_DATA} if the scheme/path didn't match, - * {@link #NO_MATCH_ACTION if the action didn't match, or + * {@link #NO_MATCH_ACTION} if the action didn't match, or * {@link #NO_MATCH_CATEGORY} if one or more categories didn't match. * * @see #matchData diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index db87cf79de82..44bf35dc2e10 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -4256,6 +4256,16 @@ public class PackageParser { public ArraySet<String> mUpgradeKeySets; public ArrayMap<String, ArraySet<PublicKey>> mKeySetMapping; + /** + * The install time abi override for this package, if any. + * + * TODO: This seems like a horrible place to put the abiOverride because + * this isn't something the packageParser parsers. However, this fits in with + * the rest of the PackageManager where package scanning randomly pushes + * and prods fields out of {@code this.applicationInfo}. + */ + public String cpuAbiOverride; + public Package(String packageName) { this.packageName = packageName; applicationInfo.packageName = packageName; diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index af574dbeb80c..4e7da48b4c9a 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -70,7 +70,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { /** * Additional flag for {@link #protectionLevel}, corresponding - * to the <code>development</code> value of + * to the <code>appop</code> value of * {@link android.R.attr#protectionLevel}. */ public static final int PROTECTION_FLAG_APPOP = 0x40; diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 8423d0952ee8..ba811b72707c 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -640,10 +640,13 @@ public class InputMethodService extends AbstractInputMethodService { * You can call this to try to enable hardware accelerated drawing for * your IME. This must be set before {@link #onCreate}, so you * will typically call it in your constructor. It is not always possible - * to use hardware acclerated drawing in an IME (for example on low-end + * to use hardware accelerated drawing in an IME (for example on low-end * devices that do not have the resources to support this), so the call * returns true if it succeeds otherwise false if you will need to draw * in software. You must be able to handle either case. + * + * @deprecated Starting in API 21, hardware acceleration is always enabled + * on capable devices. */ public boolean enableHardwareAcceleration() { if (mWindow != null) { diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index 129248c7e05e..a4ec80c9a511 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -49,9 +49,8 @@ import java.util.Objects; public final class RouteInfo implements Parcelable { /** * The IP destination address for this route. - * TODO: Make this an IpPrefix. */ - private final LinkAddress mDestination; + private final IpPrefix mDestination; /** * The gateway address for this route. @@ -81,26 +80,15 @@ public final class RouteInfo implements Parcelable { * @param gateway the IP address to route packets through * @param iface the interface name to send packets on * - * TODO: Convert to use IpPrefix. - * * @hide */ public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) { - this(destination == null ? null : - new LinkAddress(destination.getAddress(), destination.getPrefixLength()), - gateway, iface); - } - - /** - * @hide - */ - public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) { if (destination == null) { if (gateway != null) { if (gateway instanceof Inet4Address) { - destination = new LinkAddress(Inet4Address.ANY, 0); + destination = new IpPrefix(Inet4Address.ANY, 0); } else { - destination = new LinkAddress(Inet6Address.ANY, 0); + destination = new IpPrefix(Inet6Address.ANY, 0); } } else { // no destination, no gateway. invalid. @@ -108,6 +96,9 @@ public final class RouteInfo implements Parcelable { destination); } } + // TODO: set mGateway to null if there is no gateway. This is more correct, saves space, and + // matches the documented behaviour. Before we can do this we need to fix all callers (e.g., + // ConnectivityService) to stop doing things like r.getGateway().equals(), ... . if (gateway == null) { if (destination.getAddress() instanceof Inet4Address) { gateway = Inet4Address.ANY; @@ -117,20 +108,28 @@ public final class RouteInfo implements Parcelable { } mHasGateway = (!gateway.isAnyLocalAddress()); - mDestination = new LinkAddress(NetworkUtils.getNetworkPart(destination.getAddress(), - destination.getPrefixLength()), destination.getPrefixLength()); if ((destination.getAddress() instanceof Inet4Address && (gateway instanceof Inet4Address == false)) || (destination.getAddress() instanceof Inet6Address && (gateway instanceof Inet6Address == false))) { throw new IllegalArgumentException("address family mismatch in RouteInfo constructor"); } - mGateway = gateway; - mInterface = iface; + mDestination = destination; // IpPrefix objects are immutable. + mGateway = gateway; // InetAddress objects are immutable. + mInterface = iface; // Strings are immutable. mIsHost = isHost(); } /** + * @hide + */ + public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) { + this(destination == null ? null : + new IpPrefix(destination.getAddress(), destination.getPrefixLength()), + gateway, iface); + } + + /** * Constructs a {@code RouteInfo} object. * * If destination is null, then gateway must be specified and the @@ -164,7 +163,7 @@ public final class RouteInfo implements Parcelable { * @hide */ public RouteInfo(InetAddress gateway) { - this((LinkAddress) null, gateway, null); + this((IpPrefix) null, gateway, null); } /** @@ -200,9 +199,9 @@ public final class RouteInfo implements Parcelable { if (host == null) return null; if (host instanceof Inet4Address) { - return new RouteInfo(new LinkAddress(host, 32), gateway, iface); + return new RouteInfo(new IpPrefix(host, 32), gateway, iface); } else { - return new RouteInfo(new LinkAddress(host, 128), gateway, iface); + return new RouteInfo(new IpPrefix(host, 128), gateway, iface); } } @@ -219,7 +218,7 @@ public final class RouteInfo implements Parcelable { * @return {@link IpPrefix} specifying the destination. This is never {@code null}. */ public IpPrefix getDestination() { - return new IpPrefix(mDestination.getAddress(), mDestination.getPrefixLength()); + return mDestination; } /** @@ -227,7 +226,7 @@ public final class RouteInfo implements Parcelable { * @hide */ public LinkAddress getDestinationLinkAddress() { - return mDestination; + return new LinkAddress(mDestination.getAddress(), mDestination.getPrefixLength()); } /** @@ -363,7 +362,7 @@ public final class RouteInfo implements Parcelable { RouteInfo target = (RouteInfo) obj; - return Objects.equals(mDestination, target.getDestinationLinkAddress()) && + return Objects.equals(mDestination, target.getDestination()) && Objects.equals(mGateway, target.getGateway()) && Objects.equals(mInterface, target.getInterface()); } @@ -388,16 +387,9 @@ public final class RouteInfo implements Parcelable { * Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { - dest.writeByteArray(mDestination.getAddress().getAddress()); - dest.writeInt(mDestination.getPrefixLength()); - - if (mGateway == null) { - dest.writeByte((byte) 0); - } else { - dest.writeByte((byte) 1); - dest.writeByteArray(mGateway.getAddress()); - } - + dest.writeParcelable(mDestination, flags); + byte[] gatewayBytes = (mGateway == null) ? null : mGateway.getAddress(); + dest.writeByteArray(gatewayBytes); dest.writeString(mInterface); } @@ -407,33 +399,16 @@ public final class RouteInfo implements Parcelable { public static final Creator<RouteInfo> CREATOR = new Creator<RouteInfo>() { public RouteInfo createFromParcel(Parcel in) { - InetAddress destAddr = null; - int prefix = 0; - InetAddress gateway = null; + IpPrefix dest = in.readParcelable(null); + InetAddress gateway = null; byte[] addr = in.createByteArray(); - prefix = in.readInt(); - try { - destAddr = InetAddress.getByAddress(addr); + gateway = InetAddress.getByAddress(addr); } catch (UnknownHostException e) {} - if (in.readByte() == 1) { - addr = in.createByteArray(); - - try { - gateway = InetAddress.getByAddress(addr); - } catch (UnknownHostException e) {} - } - String iface = in.readString(); - LinkAddress dest = null; - - if (destAddr != null) { - dest = new LinkAddress(destAddr, prefix); - } - return new RouteInfo(dest, gateway, iface); } diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index a1c2aa1d3e60..645d510b45c1 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -614,7 +614,7 @@ public final class Parcel { * Flatten an ArrayMap into the parcel at the current dataPosition(), * growing dataCapacity() if needed. The Map keys must be String objects. */ - /* package */ void writeArrayMapInternal(ArrayMap<String,Object> val) { + /* package */ void writeArrayMapInternal(ArrayMap<String, Object> val) { if (val == null) { writeInt(-1); return; @@ -629,7 +629,7 @@ public final class Parcel { int startPos; for (int i=0; i<N; i++) { if (DEBUG_ARRAY_MAP) startPos = dataPosition(); - writeValue(val.keyAt(i)); + writeString(val.keyAt(i)); writeValue(val.valueAt(i)); if (DEBUG_ARRAY_MAP) Log.d(TAG, " Write #" + i + " " + (dataPosition()-startPos) + " bytes: key=0x" @@ -639,6 +639,13 @@ public final class Parcel { } /** + * @hide For testing only. + */ + public void writeArrayMap(ArrayMap<String, Object> val) { + writeArrayMapInternal(val); + } + + /** * Flatten a Bundle into the parcel at the current dataPosition(), * growing dataCapacity() if needed. */ @@ -2411,7 +2418,7 @@ public final class Parcel { int startPos; while (N > 0) { if (DEBUG_ARRAY_MAP) startPos = dataPosition(); - Object key = readValue(loader); + String key = readString(); Object value = readValue(loader); if (DEBUG_ARRAY_MAP) Log.d(TAG, " Read #" + (N-1) + " " + (dataPosition()-startPos) + " bytes: key=0x" @@ -2419,6 +2426,7 @@ public final class Parcel { outVal.append(key, value); N--; } + outVal.validate(); } /* package */ void readArrayMapSafelyInternal(ArrayMap outVal, int N, @@ -2429,7 +2437,7 @@ public final class Parcel { Log.d(TAG, "Reading safely " + N + " ArrayMap entries", here); } while (N > 0) { - Object key = readValue(loader); + String key = readString(); if (DEBUG_ARRAY_MAP) Log.d(TAG, " Read safe #" + (N-1) + ": key=0x" + (key != null ? key.hashCode() : 0) + " " + key); Object value = readValue(loader); @@ -2438,6 +2446,17 @@ public final class Parcel { } } + /** + * @hide For testing only. + */ + public void readArrayMap(ArrayMap outVal, ClassLoader loader) { + final int N = readInt(); + if (N < 0) { + return; + } + readArrayMapInternal(outVal, N, loader); + } + private void readListInternal(List outVal, int N, ClassLoader loader) { while (N > 0) { diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 6334f76fd7ea..f381fdfc4c62 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -298,10 +298,10 @@ public final class PowerManager { public static final int USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS = 1 << 0; /** - * Go to sleep reason code: Going to sleep due by user request. + * Go to sleep reason code: Going to sleep due by application request. * @hide */ - public static final int GO_TO_SLEEP_REASON_USER = 0; + public static final int GO_TO_SLEEP_REASON_APPLICATION = 0; /** * Go to sleep reason code: Going to sleep due by request of the @@ -317,6 +317,24 @@ public final class PowerManager { public static final int GO_TO_SLEEP_REASON_TIMEOUT = 2; /** + * Go to sleep reason code: Going to sleep due to the lid switch being closed. + * @hide + */ + public static final int GO_TO_SLEEP_REASON_LID_SWITCH = 3; + + /** + * Go to sleep reason code: Going to sleep due to the power button being pressed. + * @hide + */ + public static final int GO_TO_SLEEP_REASON_POWER_BUTTON = 4; + + /** + * Go to sleep reason code: Going to sleep due to HDMI. + * @hide + */ + public static final int GO_TO_SLEEP_REASON_HDMI = 5; + + /** * The value to pass as the 'reason' argument to reboot() to * reboot into recovery mode (for applying system updates, doing * factory resets, etc.). @@ -325,6 +343,7 @@ public final class PowerManager { * permission (in addition to * {@link android.Manifest.permission#REBOOT}). * </p> + * @hide */ public static final String REBOOT_RECOVERY = "recovery"; @@ -513,7 +532,7 @@ public final class PowerManager { * @see #wakeUp */ public void goToSleep(long time) { - goToSleep(time, GO_TO_SLEEP_REASON_USER, 0); + goToSleep(time, GO_TO_SLEEP_REASON_APPLICATION, 0); } /** diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 7aee455d5189..7a46e40c5368 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -432,7 +432,7 @@ public class RecoverySystem { // Having written the command file, go ahead and reboot PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - pm.reboot("recovery"); + pm.reboot(PowerManager.REBOOT_RECOVERY); throw new IOException("Reboot failed (no permissions?)"); } diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 30875060d35b..f9e7b786824f 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -696,6 +696,26 @@ public class UserManager { } /** + * Checks whether it's possible to add more users. Caller must hold the MANAGE_USERS + * permission. + * + * @return true if more users can be added, false if limit has been reached. + * @hide + */ + public boolean canAddMoreUsers() { + final List<UserInfo> users = getUsers(true); + final int totalUserCount = users.size(); + int aliveUserCount = 0; + for (int i = 0; i < totalUserCount; i++) { + UserInfo user = users.get(i); + if (!user.isGuest()) { + aliveUserCount++; + } + } + return aliveUserCount < getMaxSupportedUsers(); + } + + /** * Returns list of the profiles of userHandle including * userHandle itself. * Note that it this returns both enabled and not enabled profiles. See diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java index acd79424fbbe..e95e6e21b251 100644 --- a/core/java/android/preference/PreferenceFragment.java +++ b/core/java/android/preference/PreferenceFragment.java @@ -258,6 +258,7 @@ public abstract class PreferenceFragment extends Fragment implements */ public void setPreferenceScreen(PreferenceScreen preferenceScreen) { if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) { + onUnbindPreferences(); mHavePrefs = true; if (mInitDone) { postBindPreferences(); @@ -350,6 +351,10 @@ public abstract class PreferenceFragment extends Fragment implements } /** @hide */ + protected void onUnbindPreferences() { + } + + /** @hide */ public ListView getListView() { ensureList(); return mList; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 55ba9e97f0dc..888655989e4c 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -170,6 +170,20 @@ public final class Settings { "android.settings.ACCESSIBILITY_SETTINGS"; /** + * Activity Action: Show settings to control access to usage information. + * <p> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. + * <p> + * Input: Nothing. + * <p> + * Output: Nothing. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_USAGE_ACCESS_SETTINGS = + "android.settings.USAGE_ACCESS_SETTINGS"; + + /** * Activity Action: Show settings to allow configuration of security and * location privacy. * <p> @@ -372,6 +386,21 @@ public final class Settings { * Output: Nothing. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_VOICE_INPUT_SETTINGS = + "android.settings.VOICE_INPUT_SETTINGS"; + + /** + * Activity Action: Show settings to configure input methods, in particular + * allowing the user to enable input methods. + * <p> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. + * <p> + * Input: Nothing. + * <p> + * Output: Nothing. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_INPUT_METHOD_SETTINGS = "android.settings.INPUT_METHOD_SETTINGS"; @@ -2335,16 +2364,6 @@ public final class Settings { public static final String VIBRATE_WHEN_RINGING = "vibrate_when_ringing"; /** - * Whether automatic routing of system audio to USB audio peripheral is disabled. - * The value is boolean (1 or 0), where 1 means automatic routing is disabled, - * and 0 means automatic routing is enabled. - * - * @hide - */ - public static final String USB_AUDIO_AUTOMATIC_ROUTING_DISABLED = - "usb_audio_automatic_routing_disabled"; - - /** * Whether the audible DTMF tones are played by the dialer when dialing. The value is * boolean (1 or 0). */ @@ -4716,6 +4735,16 @@ public final class Settings { public static final String TV_INPUT_CUSTOM_LABELS = "tv_input_custom_labels"; /** + * Whether automatic routing of system audio to USB audio peripheral is disabled. + * The value is boolean (1 or 0), where 1 means automatic routing is disabled, + * and 0 means automatic routing is enabled. + * + * @hide + */ + public static final String USB_AUDIO_AUTOMATIC_ROUTING_DISABLED = + "usb_audio_automatic_routing_disabled"; + + /** * This are the settings to be backed up. * * NOTE: Settings are backed up and restored in the order they appear @@ -6343,7 +6372,7 @@ public final class Settings { /** * Milliseconds to wait before bouncing Wi-Fi after settings is restored. Note that after - * the caller is done with this, they should call {@link ContentResolver#delete(Uri)} to + * the caller is done with this, they should call {@link ContentResolver#delete} to * clean up any value that they may have written. * * @hide diff --git a/core/java/android/service/persistentdata/PersistentDataBlockManager.java b/core/java/android/service/persistentdata/PersistentDataBlockManager.java index 42a2e5767488..0ffdf68c4b30 100644 --- a/core/java/android/service/persistentdata/PersistentDataBlockManager.java +++ b/core/java/android/service/persistentdata/PersistentDataBlockManager.java @@ -16,6 +16,7 @@ package android.service.persistentdata; +import android.annotation.SystemApi; import android.os.RemoteException; import android.util.Slog; @@ -30,12 +31,14 @@ import android.util.Slog; * {@link PersistentDataBlockManager#getDataBlockSize()}. * * Clients can query the maximum size for a block via + * {@link PersistentDataBlockManager#getMaximumDataBlockSize()} * * Clients can read the currently written block by invoking * {@link PersistentDataBlockManager#read()}. * * @hide */ +@SystemApi public class PersistentDataBlockManager { private static final String TAG = PersistentDataBlockManager.class.getSimpleName(); private IPersistentDataBlockService sService; diff --git a/core/java/android/service/voice/VoiceInteractionServiceInfo.java b/core/java/android/service/voice/VoiceInteractionServiceInfo.java index bacda0486daa..e6e94137ef28 100644 --- a/core/java/android/service/voice/VoiceInteractionServiceInfo.java +++ b/core/java/android/service/voice/VoiceInteractionServiceInfo.java @@ -99,6 +99,11 @@ public class VoiceInteractionServiceInfo { mParseError = "No sessionService specified"; return; } + /* Not yet time + if (mRecognitionService == null) { + mParseError = "No recogitionService specified"; + return; + } */ } catch (XmlPullParserException e) { mParseError = "Error parsing voice interation service meta-data: " + e; Log.w(TAG, "error parsing voice interaction service meta-data", e); diff --git a/core/java/android/text/InputFilter.java b/core/java/android/text/InputFilter.java index 8d4b08e3c40f..bff09a20e595 100644 --- a/core/java/android/text/InputFilter.java +++ b/core/java/android/text/InputFilter.java @@ -75,14 +75,15 @@ public interface InputFilter * greater than the specified length. */ public static class LengthFilter implements InputFilter { + private final int mMax; + public LengthFilter(int max) { mMax = max; } - public CharSequence filter(CharSequence source, int start, int end, - Spanned dest, int dstart, int dend) { + public CharSequence filter(CharSequence source, int start, int end, Spanned dest, + int dstart, int dend) { int keep = mMax - (dest.length() - (dend - dstart)); - if (keep <= 0) { return ""; } else if (keep >= end - start) { @@ -99,6 +100,11 @@ public interface InputFilter } } - private int mMax; + /** + * @return the maximum length enforced by this input filter + */ + public int getMax() { + return mMax; + } } } diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index a36f06c79a58..7dce34875d49 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -273,16 +273,22 @@ public abstract class Layout { // Draw all leading margin spans. Adjust left or right according // to the paragraph direction of the line. final int length = spans.length; + boolean useFirstLineMargin = isFirstParaLine; + for (int n = 0; n < length; n++) { + if (spans[n] instanceof LeadingMarginSpan2) { + int count = ((LeadingMarginSpan2) spans[n]).getLeadingMarginLineCount(); + int startLine = getLineForOffset(sp.getSpanStart(spans[n])); + // if there is more than one LeadingMarginSpan2, use + // the count that is greatest + if (i < startLine + count) { + useFirstLineMargin = true; + break; + } + } + } for (int n = 0; n < length; n++) { if (spans[n] instanceof LeadingMarginSpan) { LeadingMarginSpan margin = (LeadingMarginSpan) spans[n]; - boolean useFirstLineMargin = isFirstParaLine; - if (margin instanceof LeadingMarginSpan2) { - int count = ((LeadingMarginSpan2) margin).getLeadingMarginLineCount(); - int startLine = getLineForOffset(sp.getSpanStart(margin)); - useFirstLineMargin = i < startLine + count; - } - if (dir == DIR_RIGHT_TO_LEFT) { margin.drawLeadingMargin(canvas, paint, right, dir, ltop, lbaseline, lbottom, buf, @@ -1535,15 +1541,18 @@ public abstract class Layout { boolean isFirstParaLine = lineStart == 0 || spanned.charAt(lineStart - 1) == '\n'; + boolean useFirstLineMargin = isFirstParaLine; for (int i = 0; i < spans.length; i++) { - LeadingMarginSpan span = spans[i]; - boolean useFirstLineMargin = isFirstParaLine; - if (span instanceof LeadingMarginSpan2) { - int spStart = spanned.getSpanStart(span); + if (spans[i] instanceof LeadingMarginSpan2) { + int spStart = spanned.getSpanStart(spans[i]); int spanLine = getLineForOffset(spStart); - int count = ((LeadingMarginSpan2)span).getLeadingMarginLineCount(); - useFirstLineMargin = line < spanLine + count; + int count = ((LeadingMarginSpan2) spans[i]).getLeadingMarginLineCount(); + // if there is more than one LeadingMarginSpan2, use the count that is greatest + useFirstLineMargin |= line < spanLine + count; } + } + for (int i = 0; i < spans.length; i++) { + LeadingMarginSpan span = spans[i]; margin += span.getLeadingMargin(useFirstLineMargin); } diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 4144a75e404b..aecf488b6f0a 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -201,13 +201,12 @@ public class StaticLayout extends Layout { restWidth -= sp[i].getLeadingMargin(false); // LeadingMarginSpan2 is odd. The count affects all - // leading margin spans, not just this particular one, - // and start from the top of the span, not the top of the - // paragraph. + // leading margin spans, not just this particular one if (lms instanceof LeadingMarginSpan2) { LeadingMarginSpan2 lms2 = (LeadingMarginSpan2) lms; int lmsFirstLine = getLineForOffset(spanned.getSpanStart(lms2)); - firstWidthLineLimit = lmsFirstLine + lms2.getLeadingMarginLineCount(); + firstWidthLineLimit = Math.max(firstWidthLineLimit, + lmsFirstLine + lms2.getLeadingMarginLineCount()); } } diff --git a/core/java/android/text/style/LeadingMarginSpan.java b/core/java/android/text/style/LeadingMarginSpan.java index 2f429ffccf62..96a7cd906a35 100644 --- a/core/java/android/text/style/LeadingMarginSpan.java +++ b/core/java/android/text/style/LeadingMarginSpan.java @@ -28,6 +28,9 @@ import android.text.TextUtils; * margin spans on a single paragraph; they will be rendered in order, each * adding its margin to the ones before it. The leading margin is on the right * for lines in a right-to-left paragraph. + * <p> + * LeadingMarginSpans should be attached from the first character to the last + * character of a single paragraph. */ public interface LeadingMarginSpan extends ParagraphStyle @@ -69,18 +72,22 @@ extends ParagraphStyle /** - * An extended version of {@link LeadingMarginSpan}, which allows - * the implementor to specify the number of lines of text to which - * this object is attached that the "first line of paragraph" margin - * width will be applied to. + * An extended version of {@link LeadingMarginSpan}, which allows the + * implementor to specify the number of lines of the paragraph to which + * this object is attached that the "first line of paragraph" margin width + * will be applied to. + * <p> + * There should only be one LeadingMarginSpan2 per paragraph. The leading + * margin line count affects all LeadingMarginSpans in the paragraph, + * adjusting the number of lines to which the first line margin is applied. + * <p> + * As with LeadingMarginSpans, LeadingMarginSpan2s should be attached from + * the beginning to the end of a paragraph. */ public interface LeadingMarginSpan2 extends LeadingMarginSpan, WrapTogetherSpan { /** - * Returns the number of lines of text to which this object is + * Returns the number of lines of the paragraph to which this object is * attached that the "first line" margin will apply to. - * Note that if this returns N, the first N lines of the region, - * not the first N lines of each paragraph, will be given the - * special margin width. */ public int getLeadingMarginLineCount(); }; diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java index 9a0b7fc644fb..3889cb68129d 100644 --- a/core/java/android/util/ArrayMap.java +++ b/core/java/android/util/ArrayMap.java @@ -410,7 +410,7 @@ public final class ArrayMap<K, V> implements Map<K, V> { /** * Add a new value to the array map. - * @param key The key under which to store the value. <b>Must not be null.</b> If + * @param key The key under which to store the value. If * this key already exists in the array, its value will be replaced. * @param value The value to store for the given key. * @return Returns the old value that was stored for the given key, or null if there @@ -496,6 +496,44 @@ public final class ArrayMap<K, V> implements Map<K, V> { } /** + * The use of the {@link #append} function can result in invalid array maps, in particular + * an array map where the same key appears multiple times. This function verifies that + * the array map is valid, throwing IllegalArgumentException if a problem is found. The + * main use for this method is validating an array map after unpacking from an IPC, to + * protect against malicious callers. + * @hide + */ + public void validate() { + final int N = mSize; + if (N <= 1) { + // There can't be dups. + return; + } + int basehash = mHashes[0]; + int basei = 0; + for (int i=1; i<N; i++) { + int hash = mHashes[i]; + if (hash != basehash) { + basehash = hash; + basei = i; + continue; + } + // We are in a run of entries with the same hash code. Go backwards through + // the array to see if any keys are the same. + final Object cur = mArray[i<<1]; + for (int j=i-1; j>=basei; j--) { + final Object prev = mArray[j<<1]; + if (cur == prev) { + throw new IllegalArgumentException("Duplicate key in ArrayMap: " + cur); + } + if (cur != null && prev != null && cur.equals(prev)) { + throw new IllegalArgumentException("Duplicate key in ArrayMap: " + cur); + } + } + } + } + + /** * Perform a {@link #put(Object, Object)} of all key/value pairs in <var>array</var> * @param array The array whose contents are to be retrieved. */ diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index 3f10b9228d28..946a3f796939 100644 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -68,7 +68,7 @@ public class DisplayMetrics { /** * Intermediate density for screens that sit somewhere between - * {@link #DENSITY_XHIGH} (320dpi) and {@link #DENSITY_XXHIGH} (480 dpi). + * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi). * This is not a density that applications should target, instead relying * on the system to scale their {@link #DENSITY_XXHIGH} assets for them. */ @@ -80,6 +80,14 @@ public class DisplayMetrics { public static final int DENSITY_XXHIGH = 480; /** + * Intermediate density for screens that sit somewhere between + * {@link #DENSITY_XXHIGH} (480 dpi) and {@link #DENSITY_XXXHIGH} (560 dpi). + * This is not a density that applications should target, instead relying + * on the system to scale their {@link #DENSITY_XXXHIGH} assets for them. + */ + public static final int DENSITY_560 = 560; + + /** * Standard quantized DPI for extra-extra-extra-high-density screens. Applications * should not generally worry about this density; relying on XHIGH graphics * being scaled up to it should be sufficient for almost all cases. A typical diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 83767cb2bf22..7deb9c89f79f 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -121,7 +121,8 @@ interface IWindowManager boolean isKeyguardSecure(); boolean inKeyguardRestrictedInputMode(); void dismissKeyguard(); - void keyguardGoingAway(); + void keyguardGoingAway(boolean disableWindowAnimations, + boolean keyguardGoingToNotificationShade); void closeSystemDialogs(String reason); diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index b6c650da9753..053fdd007e08 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -737,13 +737,14 @@ public interface WindowManagerPolicy { /** * Create and return an animation to re-display a force hidden window. */ - public Animation createForceHideEnterAnimation(boolean onWallpaper); + public Animation createForceHideEnterAnimation(boolean onWallpaper, + boolean goingToNotificationShade); /** * Create and return an animation to let the wallpaper disappear after being shown on a force * hiding window. */ - public Animation createForceHideWallpaperExitAnimation(); + public Animation createForceHideWallpaperExitAnimation(boolean goingToNotificationShade); /** * Called from the input reader thread before a key is enqueued. @@ -1014,6 +1015,11 @@ public interface WindowManagerPolicy { public void dismissKeyguardLw(); /** + * Notifies the keyguard that the activity has drawn it was waiting for. + */ + public void notifyActivityDrawnForKeyguardLw(); + + /** * Ask the policy whether the Keyguard has drawn. If the Keyguard is disabled, this method * returns true as soon as we know that Keyguard is disabled. * diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java index 4f342315504f..ca6437a4d31c 100644 --- a/core/java/android/view/accessibility/AccessibilityCache.java +++ b/core/java/android/view/accessibility/AccessibilityCache.java @@ -36,7 +36,7 @@ final class AccessibilityCache { private static final boolean DEBUG = false; - private static final boolean CHECK_INTEGRITY = Build.IS_DEBUGGABLE; + private static final boolean CHECK_INTEGRITY = "eng".equals(Build.TYPE); private final Object mLock = new Object(); diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 1bf4639ee5b9..3987fbc02989 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -562,6 +562,7 @@ public class AccessibilityNodeInfo implements Parcelable { private LongArray mChildNodeIds; private ArrayList<AccessibilityAction> mActions; + private int mMaxTextLength = -1; private int mMovementGranularities; private int mTextSelectionStart = UNDEFINED_SELECTION_INDEX; @@ -1045,6 +1046,36 @@ public class AccessibilityNodeInfo implements Parcelable { } /** + * Sets the maximum text length, or -1 for no limit. + * <p> + * Typically used to indicate that an editable text field has a limit on + * the number of characters entered. + * <p> + * <strong>Note:</strong> Cannot be called from an + * {@link android.accessibilityservice.AccessibilityService}. + * This class is made immutable before being delivered to an AccessibilityService. + * + * @param max The maximum text length. + * @see #getMaxTextLength() + * + * @throws IllegalStateException If called from an AccessibilityService. + */ + public void setMaxTextLength(int max) { + enforceNotSealed(); + mMaxTextLength = max; + } + + /** + * Returns the maximum text length for this node. + * + * @return The maximum text length, or -1 for no limit. + * @see #setMaxTextLength(int) + */ + public int getMaxTextLength() { + return mMaxTextLength; + } + + /** * Sets the movement granularities for traversing the text of this node. * <p> * <strong>Note:</strong> Cannot be called from an @@ -2469,8 +2500,8 @@ public class AccessibilityNodeInfo implements Parcelable { parcel.writeInt(0); } + parcel.writeInt(mMaxTextLength); parcel.writeInt(mMovementGranularities); - parcel.writeInt(mBooleanProperties); parcel.writeCharSequence(mPackageName); @@ -2562,6 +2593,7 @@ public class AccessibilityNodeInfo implements Parcelable { } mBooleanProperties = other.mBooleanProperties; + mMaxTextLength = other.mMaxTextLength; mMovementGranularities = other.mMovementGranularities; final LongArray otherChildNodeIds = other.mChildNodeIds; @@ -2636,8 +2668,8 @@ public class AccessibilityNodeInfo implements Parcelable { } } + mMaxTextLength = parcel.readInt(); mMovementGranularities = parcel.readInt(); - mBooleanProperties = parcel.readInt(); mPackageName = parcel.readCharSequence(); @@ -2695,6 +2727,7 @@ public class AccessibilityNodeInfo implements Parcelable { mLabeledById = ROOT_NODE_ID; mWindowId = UNDEFINED_ITEM_ID; mConnectionId = UNDEFINED_CONNECTION_ID; + mMaxTextLength = -1; mMovementGranularities = 0; if (mChildNodeIds != null) { mChildNodeIds.clear(); @@ -2911,6 +2944,7 @@ public class AccessibilityNodeInfo implements Parcelable { builder.append("; className: ").append(mClassName); builder.append("; text: ").append(mText); builder.append("; error: ").append(mError); + builder.append("; maxTextLength: ").append(mMaxTextLength); builder.append("; contentDescription: ").append(mContentDescription); builder.append("; viewIdResName: ").append(mViewIdResourceName); diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 623b5f96963f..eec35709e1b4 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1655,7 +1655,12 @@ public final class InputMethodManager { final boolean isImmediate = (mCursorAnchorInfoMonitorMode & CursorAnchorInfoRequest.FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE) != 0; if (!isImmediate && Objects.equals(mCursorAnchorInfo, cursorAnchorInfo)) { - Log.w(TAG, "Ignoring redundant updateCursorAnchorInfo: info=" + cursorAnchorInfo); + // TODO: Consider always emitting this message once we have addressed redundant + // calls of this method from android.widget.Editor. + if (DEBUG) { + Log.w(TAG, "Ignoring redundant updateCursorAnchorInfo: info=" + + cursorAnchorInfo); + } return; } if (DEBUG) Log.v(TAG, "updateCursorAnchorInfo: " + cursorAnchorInfo); diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index e07a6e3d9081..1b0cb3d8caac 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -1730,9 +1730,12 @@ public class WebView extends AbsoluteLayout * <ul> * <li> This method can be used to allow JavaScript to control the host * application. This is a powerful feature, but also presents a security - * risk for applications targeted to API level - * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} or below, because - * JavaScript could use reflection to access an + * risk for apps targeting {@link android.os.Build.VERSION_CODES#JELLY_BEAN} or earlier. + * Apps that target a version later than {@link android.os.Build.VERSION_CODES#JELLY_BEAN} + * are still vulnerable if the app runs on a device running Android earlier than 4.2. + * The most secure way to use this method is to target {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} + * and to ensure the method is called only when running on Android 4.2 or later. + * With these older versions, JavaScript could use reflection to access an * injected object's public fields. Use of this method in a WebView * containing untrusted content could allow an attacker to manipulate the * host application in unintended ways, executing Java code with the @@ -1740,7 +1743,8 @@ public class WebView extends AbsoluteLayout * method in a WebView which could contain untrusted content.</li> * <li> JavaScript interacts with Java object on a private, background * thread of this WebView. Care is therefore required to maintain thread - * safety.</li> + * safety. + * </li> * <li> The Java object's fields are not accessible.</li> * <li> For applications targeted to API level {@link android.os.Build.VERSION_CODES#L} * and above, methods of injected Java objects are enumerable from diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 23894ee7e43f..c7ffedc1e0f9 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -29,6 +29,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemProperties; +import android.os.Trace; import android.text.TextUtils; import android.util.AndroidRuntimeException; import android.util.Log; @@ -71,38 +72,55 @@ public final class WebViewFactory { private static WebViewFactoryProvider sProviderInstance; private static final Object sProviderLock = new Object(); private static boolean sAddressSpaceReserved = false; + private static PackageInfo sPackageInfo; public static String getWebViewPackageName() { return AppGlobals.getInitialApplication().getString( com.android.internal.R.string.config_webViewPackageName); } + public static PackageInfo getLoadedPackageInfo() { + return sPackageInfo; + } + static WebViewFactoryProvider getProvider() { synchronized (sProviderLock) { // For now the main purpose of this function (and the factory abstraction) is to keep // us honest and minimize usage of WebView internals when binding the proxy. if (sProviderInstance != null) return sProviderInstance; - loadNativeLibrary(); - - Class<WebViewFactoryProvider> providerClass; + Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getProvider()"); try { - providerClass = getFactoryClass(); - } catch (ClassNotFoundException e) { - Log.e(LOGTAG, "error loading provider", e); - throw new AndroidRuntimeException(e); - } + Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.loadNativeLibrary()"); + loadNativeLibrary(); + Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); - try { - sProviderInstance = providerClass.newInstance(); - if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance); - return sProviderInstance; - } catch (Exception e) { - Log.e(LOGTAG, "error instantiating provider", e); - throw new AndroidRuntimeException(e); + Class<WebViewFactoryProvider> providerClass; + Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getFactoryClass()"); + try { + providerClass = getFactoryClass(); + } catch (ClassNotFoundException e) { + Log.e(LOGTAG, "error loading provider", e); + throw new AndroidRuntimeException(e); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); + } + + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); + Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "providerClass.newInstance()"); + try { + sProviderInstance = providerClass.newInstance(); + if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance); + return sProviderInstance; + } catch (Exception e) { + Log.e(LOGTAG, "error instantiating provider", e); + throw new AndroidRuntimeException(e); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); + StrictMode.setThreadPolicy(oldPolicy); + } } finally { - StrictMode.setThreadPolicy(oldPolicy); + Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); } } } @@ -112,9 +130,9 @@ public final class WebViewFactory { try { // First fetch the package info so we can log the webview package version. String packageName = getWebViewPackageName(); - PackageInfo pi = initialApplication.getPackageManager().getPackageInfo(packageName, 0); - Log.i(LOGTAG, "Loading " + packageName + " version " + pi.versionName + - " (code " + pi.versionCode + ")"); + sPackageInfo = initialApplication.getPackageManager().getPackageInfo(packageName, 0); + Log.i(LOGTAG, "Loading " + packageName + " version " + sPackageInfo.versionName + + " (code " + sPackageInfo.versionCode + ")"); // Construct a package context to load the Java code into the current app. Context webViewContext = initialApplication.createPackageContext(packageName, @@ -122,8 +140,13 @@ public final class WebViewFactory { initialApplication.getAssets().addAssetPath( webViewContext.getApplicationInfo().sourceDir); ClassLoader clazzLoader = webViewContext.getClassLoader(); - return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY, true, - clazzLoader); + Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()"); + try { + return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY, true, + clazzLoader); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); + } } catch (PackageManager.NameNotFoundException e) { // If the package doesn't exist, then try loading the null WebView instead. // If that succeeds, then this is a device without WebView support; if it fails then diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java index ccd0480164f7..29a6a7d4177f 100644 --- a/core/java/android/widget/CheckedTextView.java +++ b/core/java/android/widget/CheckedTextView.java @@ -53,6 +53,8 @@ public class CheckedTextView extends TextView implements Checkable { private int mBasePadding; private int mCheckMarkWidth; + private int mCheckMarkGravity = Gravity.END; + private boolean mNeedRequestlayout; private static final int[] CHECKED_STATE_SET = { @@ -83,15 +85,17 @@ public class CheckedTextView extends TextView implements Checkable { } mCheckMarkTintMode = Drawable.parseTintMode(a.getInt( - R.styleable.CompoundButton_buttonTintMode, -1), mCheckMarkTintMode); + R.styleable.CheckedTextView_checkMarkTintMode, -1), mCheckMarkTintMode); - if (a.hasValue(R.styleable.CompoundButton_buttonTint)) { - mCheckMarkTintList = a.getColorStateList(R.styleable.CompoundButton_buttonTint); + if (a.hasValue(R.styleable.CheckedTextView_checkMarkTint)) { + mCheckMarkTintList = a.getColorStateList(R.styleable.CheckedTextView_checkMarkTint); mHasCheckMarkTint = true; applyCheckMarkTint(); } + mCheckMarkGravity = a.getInt(R.styleable.CheckedTextView_checkMarkGravity, Gravity.END); + boolean checked = a.getBoolean(R.styleable.CheckedTextView_checked, false); setChecked(checked); @@ -293,7 +297,7 @@ public class CheckedTextView extends TextView implements Checkable { @Override protected void internalSetPadding(int left, int top, int right, int bottom) { super.internalSetPadding(left, top, right, bottom); - setBasePadding(isLayoutRtl()); + setBasePadding(isCheckMarkAtStart()); } @Override @@ -306,7 +310,7 @@ public class CheckedTextView extends TextView implements Checkable { resetPaddingToInitialValues(); int newPadding = (mCheckMarkDrawable != null) ? mCheckMarkWidth + mBasePadding : mBasePadding; - if (isLayoutRtl()) { + if (isCheckMarkAtStart()) { mNeedRequestlayout |= (mPaddingLeft != newPadding); mPaddingLeft = newPadding; } else { @@ -319,14 +323,20 @@ public class CheckedTextView extends TextView implements Checkable { } } - private void setBasePadding(boolean isLayoutRtl) { - if (isLayoutRtl) { + private void setBasePadding(boolean checkmarkAtStart) { + if (checkmarkAtStart) { mBasePadding = mPaddingLeft; } else { mBasePadding = mPaddingRight; } } + private boolean isCheckMarkAtStart() { + final int gravity = Gravity.getAbsoluteGravity(mCheckMarkGravity, getLayoutDirection()); + final int hgrav = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; + return hgrav == Gravity.LEFT; + } + @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); @@ -347,13 +357,13 @@ public class CheckedTextView extends TextView implements Checkable { break; } - final boolean isLayoutRtl = isLayoutRtl(); + final boolean checkMarkAtStart = isCheckMarkAtStart(); final int width = getWidth(); final int top = y; final int bottom = top + height; final int left; final int right; - if (isLayoutRtl) { + if (checkMarkAtStart) { left = mBasePadding; right = left + mCheckMarkWidth; } else { diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index b162e549bf2e..a536b2d3db6e 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8392,6 +8392,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } + // Check for known input filter types. + final int numFilters = mFilters.length; + for (int i = 0; i < numFilters; i++) { + final InputFilter filter = mFilters[i]; + if (filter instanceof InputFilter.LengthFilter) { + info.setMaxTextLength(((InputFilter.LengthFilter) filter).getMax()); + } + } + if (!isSingleLine()) { info.setMultiLine(true); } diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl index a5421f5dc95e..64f3bea32a08 100644 --- a/core/java/com/android/internal/policy/IKeyguardService.aidl +++ b/core/java/com/android/internal/policy/IKeyguardService.aidl @@ -65,4 +65,10 @@ interface IKeyguardService { * @param fadeoutDuration the duration of the exit animation, in milliseconds */ oneway void startKeyguardExitAnimation(long startTime, long fadeoutDuration); + + /** + * Notifies the Keyguard that the activity that was starting has now been drawn and it's safe + * to start the keyguard dismiss sequence. + */ + oneway void onActivityDrawn(); } diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java index 9e24844aee9d..254f60296280 100644 --- a/core/java/com/android/internal/widget/ActionBarContainer.java +++ b/core/java/com/android/internal/widget/ActionBarContainer.java @@ -253,7 +253,7 @@ public class ActionBarContainer extends FrameLayout { return null; } - private boolean isCollapsed(View view) { + private static boolean isCollapsed(View view) { return view == null || view.getVisibility() == GONE || view.getMeasuredHeight() == 0; } @@ -326,35 +326,33 @@ public class ActionBarContainer extends FrameLayout { * projection surfaces. */ private class ActionBarBackgroundDrawable extends Drawable { - private Drawable getDrawable() { + @Override + public void draw(Canvas canvas) { if (mIsSplit) { if (mSplitBackground != null) { - return mSplitBackground; + mSplitBackground.draw(canvas); } } else { if (mBackground != null) { - return mBackground; + mBackground.draw(canvas); } if (mStackedBackground != null && mIsStacked) { - return mStackedBackground; + mStackedBackground.draw(canvas); } } - return null; - } - - @Override - public void draw(Canvas canvas) { - final Drawable drawable = getDrawable(); - if (drawable != null) { - drawable.draw(canvas); - } } @Override public void getOutline(@NonNull Outline outline) { - final Drawable drawable = getDrawable(); - if (drawable != null) { - drawable.getOutline(outline); + if (mIsSplit) { + if (mSplitBackground != null) { + mSplitBackground.getOutline(outline); + } + } else { + // ignore the stacked background for shadow casting + if (mBackground != null) { + mBackground.getOutline(outline); + } } } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 7e8d8287bc84..ece3e9d5e503 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -18,7 +18,6 @@ package com.android.internal.widget; import android.Manifest; import android.app.ActivityManagerNative; -import android.app.AlarmClockInfo; import android.app.AlarmManager; import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; @@ -1169,7 +1168,7 @@ public class LockPatternUtils { * @return A formatted string of the next alarm (for showing on the lock screen), * or null if there is no next alarm. */ - public AlarmClockInfo getNextAlarm() { + public AlarmManager.AlarmClockInfo getNextAlarm() { AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); return alarmManager.getNextAlarmClock(UserHandle.USER_CURRENT); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index ff483ce49f24..931d1c656f6f 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1852,7 +1852,8 @@ android:description="@string/permdesc_manageCaCertificates" /> <!-- @SystemApi Allows an application to do certain operations needed for - interacting with the recovery (system update) system. --> + interacting with the recovery (system update) system. + @hide --> <permission android:name="android.permission.RECOVERY" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:protectionLevel="signature|system" diff --git a/core/res/res/anim/lock_screen_behind_enter_fade_in.xml b/core/res/res/anim/lock_screen_behind_enter_fade_in.xml new file mode 100644 index 000000000000..94e40a868ed3 --- /dev/null +++ b/core/res/res/anim/lock_screen_behind_enter_fade_in.xml @@ -0,0 +1,27 @@ +<?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 + --> + +<alpha xmlns:android="http://schemas.android.com/apk/res/android" + android:background="#ff000000" + android:detachWallpaper="true" + android:shareInterpolator="false" + android:interpolator="@interpolator/linear" + android:fromAlpha="0" android:toAlpha="1" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:duration="250" + android:startOffset="100"> +</alpha>
\ No newline at end of file diff --git a/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml b/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml index 09d800149e49..ce974dc8099d 100644 --- a/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml +++ b/core/res/res/anim/lock_screen_behind_enter_wallpaper.xml @@ -22,15 +22,8 @@ android:fillEnabled="true" android:fillBefore="true" android:interpolator="@interpolator/decelerate_quint" android:duration="400"/> - <scale - android:fromXScale="0.94" android:toXScale="1.0" - android:fromYScale="0.94" android:toYScale="1.0" - android:pivotX="50%" android:pivotY="100%" - android:fillEnabled="true" android:fillBefore="true" - android:interpolator="@interpolator/decelerate_quint" - android:duration="400" /> - <translate android:fromYDelta="5%" android:toYDelta="0" + <translate android:fromYDelta="11%" android:toYDelta="0" android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" android:interpolator="@interpolator/decelerate_quint" android:duration="300" /> diff --git a/core/res/res/anim/wallpaper_close_enter.xml b/core/res/res/anim/wallpaper_close_enter.xml index 981923ac4723..a18981393be0 100644 --- a/core/res/res/anim/wallpaper_close_enter.xml +++ b/core/res/res/anim/wallpaper_close_enter.xml @@ -18,15 +18,17 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" android:zAdjustment="top"> - <scale android:fromXScale=".2" android:toXScale="1.0" - android:fromYScale=".2" android:toYScale="1.0" - android:pivotX="50%p" android:pivotY="50%p" - android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/decelerate_cubic" - android:duration="300" /> + android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top"> + <alpha android:fromAlpha="0" android:toAlpha="1.0" - android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/decelerate_cubic" - android:duration="300"/> + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:interpolator="@interpolator/decelerate_quart" + android:startOffset="300" + android:duration="167"/> + + <translate android:fromYDelta="110%" android:toYDelta="0" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:interpolator="@interpolator/decelerate_quint" + android:startOffset="300" + android:duration="417" /> </set>
\ No newline at end of file diff --git a/core/res/res/anim/wallpaper_close_exit.xml b/core/res/res/anim/wallpaper_close_exit.xml index a91eb49c0e61..12b31aefcd46 100644 --- a/core/res/res/anim/wallpaper_close_exit.xml +++ b/core/res/res/anim/wallpaper_close_exit.xml @@ -20,5 +20,5 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:detachWallpaper="true" android:shareInterpolator="false" android:zAdjustment="normal"> <alpha android:fromAlpha="1.0" android:toAlpha="1.0" - android:duration="300" /> + android:duration="417" /> </set>
\ No newline at end of file diff --git a/core/res/res/layout/notification_material_action.xml b/core/res/res/layout/notification_material_action.xml index 7ccaad52cb53..8f8c4fba2b42 100644 --- a/core/res/res/layout/notification_material_action.xml +++ b/core/res/res/layout/notification_material_action.xml @@ -21,11 +21,12 @@ android:layout_width="0dp" android:layout_height="48dp" android:layout_weight="1" + android:layout_margin="0dp" android:gravity="start|center_vertical" android:drawablePadding="8dp" android:paddingStart="8dp" android:textColor="#555555" - android:textSize="14dp" + android:textSize="@dimen/notification_text_size" android:singleLine="true" android:ellipsize="end" /> diff --git a/core/res/res/layout/notification_material_action_tombstone.xml b/core/res/res/layout/notification_material_action_tombstone.xml index 8bf456ead691..976448b08bb3 100644 --- a/core/res/res/layout/notification_material_action_tombstone.xml +++ b/core/res/res/layout/notification_material_action_tombstone.xml @@ -25,7 +25,7 @@ android:drawablePadding="8dp" android:paddingStart="8dp" android:textColor="#555555" - android:textSize="14dp" + android:textSize="@dimen/notification_text_size" android:singleLine="true" android:ellipsize="end" android:alpha="0.5" diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml index ab13b986dfd3..5e51db92ad26 100644 --- a/core/res/res/layout/notification_template_material_base.xml +++ b/core/res/res/layout/notification_template_material_base.xml @@ -29,106 +29,27 @@ /> <LinearLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - - android:layout_gravity="fill_vertical" + android:layout_height="match_parent" + android:layout_gravity="top" + android:layout_marginEnd="8dp" android:layout_marginStart="@dimen/notification_large_icon_width" android:minHeight="@dimen/notification_large_icon_height" android:orientation="vertical" - android:paddingEnd="8dp" - android:paddingTop="2dp" - android:paddingBottom="2dp" - android:gravity="top" > - <LinearLayout - android:id="@+id/line1" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="6dp" - android:layout_marginStart="8dp" - android:orientation="horizontal" - > - <TextView android:id="@+id/title" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - android:layout_weight="1" - /> - <ViewStub android:id="@+id/time" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:visibility="gone" - android:layout="@layout/notification_template_part_time" - /> - <ViewStub android:id="@+id/chronometer" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:visibility="gone" - android:layout="@layout/notification_template_part_chronometer" - /> - </LinearLayout> - <TextView android:id="@+id/text2" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Line2" + <include layout="@layout/notification_template_part_line1" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="-2dp" - android:layout_marginBottom="-2dp" - android:layout_marginStart="8dp" - android:singleLine="true" - android:fadingEdge="horizontal" - android:ellipsize="marquee" - android:visibility="gone" + android:layout_weight="1" /> - <ProgressBar - android:id="@android:id/progress" + <include layout="@layout/notification_template_part_line2" android:layout_width="match_parent" - android:layout_height="12dp" - android:layout_marginStart="8dp" - android:visibility="gone" - style="@style/Widget.StatusBar.Material.ProgressBar" + android:layout_height="wrap_content" + android:layout_weight="1" /> - <LinearLayout - android:id="@+id/line3" + <include layout="@layout/notification_template_part_line3" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="horizontal" - android:gravity="center_vertical" - android:layout_marginStart="8dp" - > - <TextView android:id="@+id/text" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:layout_gravity="center" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - /> - <TextView android:id="@+id/info" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Info" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:layout_weight="0" - android:singleLine="true" - android:gravity="center" - android:paddingStart="8dp" - /> - <ImageView android:id="@+id/profile_icon" - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_gravity="center" - android:layout_weight="0" - android:layout_marginStart="8dp" - android:scaleType="centerInside" - android:visibility="gone" - /> - </LinearLayout> + android:layout_weight="1" + /> </LinearLayout> </FrameLayout> diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml index 0564a8f30c25..2243a0927cf5 100644 --- a/core/res/res/layout/notification_template_material_big_base.xml +++ b/core/res/res/layout/notification_template_material_big_base.xml @@ -30,124 +30,24 @@ <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_gravity="fill_vertical" + android:layout_gravity="top" + android:layout_marginEnd="8dp" + android:layout_marginStart="@dimen/notification_large_icon_width" android:minHeight="@dimen/notification_large_icon_height" android:orientation="vertical" - android:gravity="top" > - <LinearLayout + <include layout="@layout/notification_template_part_line1" /> + <include layout="@layout/notification_template_part_line2" /> + <TextView android:id="@+id/big_text" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/notification_large_icon_width" android:minHeight="@dimen/notification_large_icon_height" - android:paddingTop="2dp" - android:orientation="vertical" - > - <LinearLayout - android:id="@+id/line1" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="6dp" - android:layout_marginEnd="8dp" - android:layout_marginStart="8dp" - android:orientation="horizontal" - > - <TextView android:id="@+id/title" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - android:layout_weight="1" - /> - <ViewStub android:id="@+id/time" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:visibility="gone" - android:layout="@layout/notification_template_part_time" - /> - <ViewStub android:id="@+id/chronometer" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:visibility="gone" - android:layout="@layout/notification_template_part_chronometer" - /> - </LinearLayout> - <TextView android:id="@+id/text2" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Line2" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="-2dp" - android:layout_marginBottom="-2dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:singleLine="true" - android:fadingEdge="horizontal" - android:ellipsize="marquee" - android:visibility="gone" - /> - <TextView android:id="@+id/big_text" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:singleLine="false" - android:visibility="gone" - /> - <LinearLayout - android:id="@+id/line3" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:orientation="horizontal" - android:gravity="center_vertical" - > - <TextView android:id="@+id/text" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:layout_gravity="center" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - /> - <TextView android:id="@+id/info" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Info" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:layout_weight="0" - android:singleLine="true" - android:gravity="center" - android:paddingStart="8dp" - /> - <ImageView android:id="@+id/profile_icon" - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_gravity="center" - android:layout_weight="0" - android:layout_marginStart="8dp" - android:scaleType="centerInside" - android:visibility="gone" - /> - </LinearLayout> - <ProgressBar - android:id="@android:id/progress" - android:layout_width="match_parent" - android:layout_height="12dp" - android:layout_marginBottom="8dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:visibility="gone" - style="@style/Widget.StatusBar.Material.ProgressBar" - /> - </LinearLayout> + android:layout_weight="1" + android:singleLine="false" + android:visibility="gone" + /> + <include layout="@layout/notification_template_part_line3" /> <ImageView android:layout_width="match_parent" android:layout_height="1dp" @@ -156,9 +56,10 @@ android:background="@drawable/list_divider_holo_light" /> <include layout="@layout/notification_material_action_list" + android:layout_marginLeft="-8dp" + android:layout_marginRight="-8dp" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/notification_large_icon_width" /> </LinearLayout> </FrameLayout> diff --git a/core/res/res/layout/notification_template_material_big_picture.xml b/core/res/res/layout/notification_template_material_big_picture.xml index 74819fd8ccc3..302e651f8be2 100644 --- a/core/res/res/layout/notification_template_material_big_picture.xml +++ b/core/res/res/layout/notification_template_material_big_picture.xml @@ -40,13 +40,13 @@ /> <include layout="@layout/notification_template_material_base" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="64dp" /> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="208dp" - android:paddingStart="64dp" + android:paddingStart="@dimen/notification_large_icon_width" android:layout_gravity="bottom" android:background="#CCEEEEEE" > diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml deleted file mode 100644 index 1de5add91c8c..000000000000 --- a/core/res/res/layout/notification_template_material_big_text.xml +++ /dev/null @@ -1,179 +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 - --> -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:internal="http://schemas.android.com/apk/prv/res/android" - android:id="@+id/status_bar_latest_event_content" - android:layout_width="match_parent" - android:layout_height="wrap_content" - internal:layout_minHeight="65dp" - internal:layout_maxHeight="unbounded" - > - <include layout="@layout/notification_template_icon_group" - android:layout_width="@dimen/notification_large_icon_width" - android:layout_height="@dimen/notification_large_icon_height" - /> - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="fill_vertical" - android:layout_marginStart="@dimen/notification_large_icon_width" - android:orientation="vertical" - android:paddingTop="0dp" - android:paddingBottom="2dp" - android:gravity="top" - > - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:minHeight="@dimen/notification_large_icon_height" - android:orientation="vertical" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:layout_weight="1" - > - <LinearLayout - android:id="@+id/line1" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="8dp" - android:orientation="horizontal" - android:layout_gravity="top" - android:layout_weight="0" - > - <TextView android:id="@+id/title" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - android:layout_weight="1" - /> - <ViewStub android:id="@+id/time" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:visibility="gone" - android:layout="@layout/notification_template_part_time" - /> - <ViewStub android:id="@+id/chronometer" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:visibility="gone" - android:layout="@layout/notification_template_part_chronometer" - /> - </LinearLayout> - <TextView android:id="@+id/text2" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Line2" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="-2dp" - android:layout_marginBottom="-2dp" - android:layout_marginEnd="8dp" - android:singleLine="true" - android:fadingEdge="horizontal" - android:ellipsize="marquee" - android:layout_weight="0" - android:visibility="gone" - /> - <ProgressBar - android:id="@android:id/progress" - android:layout_width="match_parent" - android:layout_height="12dp" - android:layout_marginBottom="8dp" - android:layout_marginEnd="8dp" - android:visibility="gone" - android:layout_weight="0" - style="@style/Widget.StatusBar.Material.ProgressBar" - /> - <TextView android:id="@+id/big_text" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginBottom="10dp" - android:layout_marginEnd="8dp" - android:singleLine="false" - android:visibility="gone" - android:maxLines="8" - android:ellipsize="end" - android:layout_weight="1" - /> - </LinearLayout> - <ImageView - android:layout_width="match_parent" - android:layout_height="1dip" - android:id="@+id/action_divider" - android:visibility="gone" - android:background="@drawable/list_divider_holo_light" /> - <include - layout="@layout/notification_material_action_list" - android:layout_width="match_parent" - android:layout_height="0dp" - android:visibility="gone" - android:layout_weight="1" - /> - <ImageView - android:layout_width="match_parent" - android:layout_height="1dp" - android:id="@+id/overflow_divider" - android:layout_marginBottom="8dp" - android:visibility="visible" - android:background="@drawable/list_divider_holo_light" /> - <LinearLayout - android:id="@+id/line3" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginBottom="8dp" - android:layout_marginEnd="8dp" - android:orientation="horizontal" - android:layout_weight="0" - android:gravity="center_vertical" - > - <TextView android:id="@+id/text" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:layout_gravity="center" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - /> - <TextView android:id="@+id/info" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Info" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:layout_weight="0" - android:singleLine="true" - android:gravity="center" - android:paddingStart="8dp" - /> - <ImageView android:id="@+id/profile_icon" - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_gravity="center" - android:layout_weight="0" - android:layout_marginStart="8dp" - android:scaleType="centerInside" - android:visibility="gone" - /> - </LinearLayout> - </LinearLayout> -</FrameLayout> diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml index 8411ff57b04e..6133791c7525 100644 --- a/core/res/res/layout/notification_template_material_inbox.xml +++ b/core/res/res/layout/notification_template_material_inbox.xml @@ -30,175 +30,93 @@ <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_gravity="fill_vertical" + android:layout_gravity="top" android:layout_marginStart="@dimen/notification_large_icon_width" android:minHeight="@dimen/notification_large_icon_height" android:orientation="vertical" - android:paddingTop="0dp" - android:paddingBottom="2dp" - android:gravity="top" > - <LinearLayout + <include layout="@layout/notification_template_part_line1" /> + <include layout="@layout/notification_template_part_line2" /> + <TextView android:id="@+id/inbox_text0" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:minHeight="@dimen/notification_large_icon_height" - android:paddingTop="2dp" - android:orientation="vertical" - > - <LinearLayout - android:id="@+id/line1" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:paddingTop="6dp" - android:orientation="horizontal" - android:layout_weight="0" - > - <TextView android:id="@+id/title" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - android:layout_weight="1" - /> - <ViewStub android:id="@+id/time" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:visibility="gone" - android:layout="@layout/notification_template_part_time" - /> - <ViewStub android:id="@+id/chronometer" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="0" - android:visibility="gone" - android:layout="@layout/notification_template_part_chronometer" - /> - </LinearLayout> - <TextView android:id="@+id/text2" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Line2" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="-2dp" - android:layout_marginBottom="-2dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:singleLine="true" - android:fadingEdge="horizontal" - android:ellipsize="marquee" - android:visibility="gone" - android:layout_weight="0" - /> - <ProgressBar - android:id="@android:id/progress" - android:layout_width="match_parent" - android:layout_height="12dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:visibility="gone" - android:layout_weight="0" - style="@style/Widget.Material.Light.ProgressBar.Horizontal" - /> - <TextView android:id="@+id/inbox_text0" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text1" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text2" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text3" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text4" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginStart="8dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text5" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text6" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_more" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - android:text="@android:string/ellipsis" - /> - <FrameLayout - android:id="@+id/inbox_end_pad" - android:layout_width="match_parent" - android:layout_height="8dip" - android:visibility="gone" - android:layout_weight="0" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text1" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text2" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text3" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text4" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text5" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text6" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_more" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + android:text="@android:string/ellipsis" /> - </LinearLayout> + <FrameLayout + android:id="@+id/inbox_end_pad" + android:layout_width="match_parent" + android:layout_height="8dip" + android:visibility="gone" + android:layout_weight="0" + /> <ImageView android:layout_width="match_parent" android:layout_height="1dip" @@ -209,6 +127,8 @@ layout="@layout/notification_material_action_list" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginLeft="-8dp" + android:layout_marginRight="-8dp" android:layout_weight="0" /> <ImageView @@ -217,47 +137,6 @@ android:id="@+id/overflow_divider" android:visibility="visible" android:background="@drawable/list_divider_holo_light" /> - <LinearLayout - android:id="@+id/line3" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="8dp" - android:layout_marginStart="8dp" - android:layout_marginBottom="8dp" - android:layout_marginEnd="8dp" - android:orientation="horizontal" - android:layout_weight="0" - android:gravity="center_vertical" - > - <TextView android:id="@+id/text" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:layout_gravity="center" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - /> - <TextView android:id="@+id/info" - android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Info" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:layout_weight="0" - android:singleLine="true" - android:gravity="center" - android:paddingStart="8dp" - /> - <ImageView android:id="@+id/profile_icon" - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_gravity="center" - android:layout_weight="0" - android:layout_marginStart="8dp" - android:scaleType="centerInside" - android:visibility="gone" - /> - </LinearLayout> + <include layout="@layout/notification_template_part_line3" /> </LinearLayout> </FrameLayout> diff --git a/core/res/res/layout/notification_template_part_line1.xml b/core/res/res/layout/notification_template_part_line1.xml new file mode 100644 index 000000000000..d652959ebd3f --- /dev/null +++ b/core/res/res/layout/notification_template_part_line1.xml @@ -0,0 +1,49 @@ +<?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 + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/line1" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:paddingTop="@dimen/notification_vert_pad" + android:layout_weight="0" + > + <TextView android:id="@+id/title" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + android:layout_weight="1" + /> + <ViewStub android:id="@+id/time" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="0" + android:visibility="gone" + android:layout="@layout/notification_template_part_time" + /> + <ViewStub android:id="@+id/chronometer" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="0" + android:visibility="gone" + android:layout="@layout/notification_template_part_chronometer" + /> +</LinearLayout> diff --git a/core/res/res/layout/notification_template_part_line2.xml b/core/res/res/layout/notification_template_part_line2.xml new file mode 100644 index 000000000000..1e19df1adc99 --- /dev/null +++ b/core/res/res/layout/notification_template_part_line2.xml @@ -0,0 +1,40 @@ +<?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 + --> + +<merge xmlns:android="http://schemas.android.com/apk/res/android"> + <TextView + android:id="@+id/text2" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Line2" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="-2dp" + android:layout_marginBottom="-2dp" + android:singleLine="true" + android:fadingEdge="horizontal" + android:ellipsize="marquee" + android:visibility="gone" + android:layout_weight="0" + /> + <ProgressBar + android:id="@android:id/progress" + android:layout_width="match_parent" + android:layout_height="8dp" + android:visibility="gone" + android:layout_weight="0" + style="@style/Widget.Material.Light.ProgressBar.Horizontal" + /> +</merge> diff --git a/core/res/res/layout/notification_template_part_line3.xml b/core/res/res/layout/notification_template_part_line3.xml new file mode 100644 index 000000000000..2c8c704c6115 --- /dev/null +++ b/core/res/res/layout/notification_template_part_line3.xml @@ -0,0 +1,56 @@ +<?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 + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/line3" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:layout_weight="0" + android:gravity="center_vertical" + android:paddingBottom="@dimen/notification_vert_pad" + > + <TextView android:id="@+id/text" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + /> + <TextView android:id="@+id/info" + android:textAppearance="@style/TextAppearance.StatusBar.Material.EventContent.Info" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_weight="0" + android:singleLine="true" + android:gravity="center" + android:paddingStart="8dp" + /> + <ImageView android:id="@+id/profile_icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="center" + android:layout_weight="0" + android:layout_marginStart="8dp" + android:scaleType="centerInside" + android:visibility="gone" + /> +</LinearLayout> diff --git a/core/res/res/layout/preference_widget_switch.xml b/core/res/res/layout/preference_widget_switch.xml index 7395ff27bc62..25e8aa65d13a 100644 --- a/core/res/res/layout/preference_widget_switch.xml +++ b/core/res/res/layout/preference_widget_switch.xml @@ -21,4 +21,5 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="false" + android:clickable="false" android:background="@null" /> diff --git a/core/res/res/layout/select_dialog_multichoice_material.xml b/core/res/res/layout/select_dialog_multichoice_material.xml index 8b4c59df8728..01e4cfa89960 100644 --- a/core/res/res/layout/select_dialog_multichoice_material.xml +++ b/core/res/res/layout/select_dialog_multichoice_material.xml @@ -26,4 +26,5 @@ android:paddingStart="16dip" android:paddingEnd="16dip" android:checkMark="?android:attr/listChoiceIndicatorMultiple" + android:checkMarkGravity="start" android:ellipsize="marquee" /> diff --git a/core/res/res/layout/select_dialog_singlechoice_material.xml b/core/res/res/layout/select_dialog_singlechoice_material.xml index 27a6648b53ec..0f3c277a8a50 100644 --- a/core/res/res/layout/select_dialog_singlechoice_material.xml +++ b/core/res/res/layout/select_dialog_singlechoice_material.xml @@ -26,4 +26,5 @@ android:paddingStart="16dip" android:paddingEnd="16dip" android:checkMark="?android:attr/listChoiceIndicatorSingle" + android:checkMarkGravity="start" android:ellipsize="marquee" /> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index f6c0d719a1ec..89bda8217d95 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -3163,6 +3163,17 @@ result to valid color values. Saturate(S + D) --> <enum name="add" value="16" /> </attr> + <!-- Gravity for aligning a CheckedTextView's checkmark to one side or the other. --> + <attr name="checkMarkGravity"> + <!-- Push object to the left of its container, not changing its size. --> + <flag name="left" value="0x03" /> + <!-- Push object to the right of its container, not changing its size. --> + <flag name="right" value="0x05" /> + <!-- Push object to the beginning of its container, not changing its size. --> + <flag name="start" value="0x00800003" /> + <!-- Push object to the end of its container, not changing its size. --> + <flag name="end" value="0x00800005" /> + </attr> </declare-styleable> <declare-styleable name="EditText"> </declare-styleable> @@ -5209,14 +5220,10 @@ <attr name="name" /> <!-- The width a path stroke --> <attr name="strokeWidth" format="float" /> - <!-- The opacity of a path stroke @hide--> - <attr name="strokeOpacity" format="float" /> <!-- The color to stroke the path if not defined implies no stroke--> <attr name="strokeColor" format="color" /> <!-- The color to fill the path if not defined implies no fill--> <attr name="fillColor" format="color" /> - <!-- The level of opacity of the filled area of the path @hide--> - <attr name="fillOpacity" format="float" /> <!-- The specification of the operations that define the path --> <attr name="pathData" format="string" /> <!-- The fraction of the path to trim from the start from 0 to 1 --> @@ -6855,9 +6862,11 @@ its {@link android.service.voice.VoiceInteractionService#SERVICE_META_DATA} meta-data entry. Described here are the attributes that can be included in that tag. --> <declare-styleable name="VoiceInteractionService"> - <!-- The service that hosts active voice interaction sessions. --> + <!-- The service that hosts active voice interaction sessions. This is required. --> <attr name="sessionService" format="string" /> - <!-- The service that provides voice recognition. --> + <!-- The service that provides voice recognition. This is required. When the user + selects this voice interaction service, they will also be implicitly selecting + the component here for their recognition service. --> <attr name="recognitionService" format="string" /> <attr name="settingsActivity" /> </declare-styleable> @@ -7278,9 +7287,8 @@ <!-- Component name of an activity that allows the user to modify the settings for this service. --> <attr name="settingsActivity" /> - <!-- Component name of an xml file that describes the structure of TV content ratings that - this service uses. --> - <attr name="contentRatingSystemXml" format="reference" /> + <!-- Reference to an XML document that describes TV content rating. --> + <attr name="tvContentRatingDescription" format="reference" /> </declare-styleable> <declare-styleable name="ResolverDrawerLayout"> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index bacdc3ffb7c0..9d6c36dd1c57 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -42,11 +42,6 @@ <dimen name="status_bar_icon_size">24dip</dimen> <!-- Size of the giant number (unread count) in the notifications --> <dimen name="status_bar_content_number_size">48sp</dimen> - <!-- Height of the system bar (combined status & navigation); used by - SystemUI internally, not respected by the window manager. --> - <dimen name="system_bar_height">@dimen/navigation_bar_height</dimen> - <!-- Height of notification icons in the system bar --> - <dimen name="system_bar_icon_size">32dip</dimen> <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. --> <dimen name="status_bar_edge_ignore">5dp</dimen> @@ -220,11 +215,17 @@ <dimen name="action_bar_stacked_tab_max_width">180dp</dimen> <!-- Size of notification text (see TextAppearance.StatusBar.EventContent) --> - <dimen name="notification_text_size">13dp</dimen> + <dimen name="notification_text_size">13sp</dimen> <!-- Size of notification text titles (see TextAppearance.StatusBar.EventContent.Title) --> - <dimen name="notification_title_text_size">16dp</dimen> + <dimen name="notification_title_text_size">16sp</dimen> <!-- Size of smaller notification text (see TextAppearance.StatusBar.EventContent.Line2, Info, Time) --> - <dimen name="notification_subtext_size">12dp</dimen> + <dimen name="notification_subtext_size">12sp</dimen> + + <!-- 8dp at the top/bottom of the notification view --> + <dimen name="notification_vert_pad">10dp</dimen> + + <!-- Replacement for @dimen/notification_vert_pad when the text is large --> + <dimen name="notification_large_font_vert_pad">3dp</dimen> <!-- Keyguard dimensions --> <!-- TEMP --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 67352d795c32..e894a9cb47e9 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2118,11 +2118,9 @@ <public type="attr" name="transitionGroup" /> <public type="attr" name="viewportWidth" /> <public type="attr" name="viewportHeight" /> - <public type="attr" name="fillOpacity" /> <public type="attr" name="fillColor" /> <public type="attr" name="pathData" /> <public type="attr" name="strokeColor" /> - <public type="attr" name="strokeOpacity" /> <public type="attr" name="strokeWidth" /> <public type="attr" name="trimPathStart" /> <public type="attr" name="trimPathEnd" /> @@ -2269,7 +2267,7 @@ <public type="attr" name="windowReenterTransition" /> <public type="attr" name="windowSharedElementReturnTransition" /> <public type="attr" name="windowSharedElementReenterTransition" /> - <public type="attr" name="contentRatingSystemXml"/> + <public type="attr" name="tvContentRatingDescription"/> <public type="attr" name="datePickerMode"/> <public type="attr" name="timePickerMode"/> <public type="attr" name="inset" /> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index e67eae1129e2..74992ed4a82e 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4839,24 +4839,28 @@ <string name="day_of_week_label_typeface">sans-serif</string> <!-- Notify use that they are in Lock-to-app --> - <string name="lock_to_app_toast">You are in lock-to-app mode. To exit, touch and hold the Recents button</string> + <string name="lock_to_app_toast">To unpin this screen, touch and hold Back and Recents at the same time.</string> + <!-- Notify use that they are in Lock-to-app in accessibility mode --> + <string name="lock_to_app_toast_accessible">To unpin this screen, touch and hold Recents.</string> <!-- Notify user that they are locked in lock-to-app mode --> - <string name="lock_to_app_toast_locked">You are in Lock-to-App mode.</string> + <string name="lock_to_app_toast_locked">Screen is pinned. Unpinning isn\'t allowed by your organization.</string> <!-- Lock-to-app dialog title. --> - <string name="lock_to_app_title">Use lock-to-app?</string> + <string name="lock_to_app_title">Use screen pinning?</string> <!-- Lock-to-app dialog description. --> - <string name="lock_to_app_description">Lock-to-app locks the display in a single app.\n\nTo exit, touch and hold the Recents button.</string> + <string name="lock_to_app_description">Screen pinning locks the display in a single view.\n\nTo exit, touch and hold Back and Recents at the same time.</string> + <!-- Lock-to-app dialog description when in accessibility mode. --> + <string name="lock_to_app_description_accessible">Screen pinning locks the display in a single view.\n\nTo exit, touch and hold Recents.</string> <!-- Lock-to-app negative response. --> <string name="lock_to_app_negative">NO, THANKS</string> <!-- Lock-to-app positive response. --> <string name="lock_to_app_positive">START</string> <!-- Starting lock-to-app indication. --> - <string name="lock_to_app_start">Locked to app</string> + <string name="lock_to_app_start">Screen pinned</string> <!-- Exting lock-to-app indication. --> - <string name="lock_to_app_exit">No longer locked to app</string> + <string name="lock_to_app_exit">Screen unpinned</string> <!-- Lock-to-app checkbox for lock on exit --> - <string name="lock_to_app_use_screen_lock">Ask for %1$s before exiting</string> + <string name="lock_to_app_use_screen_lock">Ask for %1$s before unpinning</string> <!-- Lock-to-app unlock pin string --> <string name="lock_to_app_unlock_pin">PIN</string> @@ -4867,35 +4871,35 @@ <!-- Range specific TV content rating system strings for AM TV --> <string name="display_name_amtvrs" translatable="false">AM-TV-RS</string> - <string name="description_amtvrs">Range specific TV content rating system strings for Armenia</string> + <string name="description_amtvrs" translatable="false">Range specific TV content rating system strings for Armenia</string> <string name="display_name_amtvrs_y" translatable="false">Y</string> <string name="display_name_amtvrs_y7" translatable="false">Y7</string> <string name="display_name_amtvrs_ga" translatable="false">GA</string> <string name="display_name_amtvrs_tw" translatable="false">TW</string> <string name="display_name_amtvrs_t" translatable="false">T</string> <string name="display_name_amtvrs_a" translatable="false">A</string> - <string name="description_amtvrs_y">Suitable for ages 2–11</string> - <string name="description_amtvrs_y7">Suitable for ages 7–16</string> - <string name="description_amtvrs_ga">Suitable for general audiences</string> - <string name="description_amtvrs_tw">Suitable for teens ages 9 and up</string> - <string name="description_amtvrs_t">Suitable for teens ages 12 and up</string> - <string name="description_amtvrs_a">Suitable only for adults ages 18 and up</string> + <string name="description_amtvrs_y" translatable="false">Suitable for ages 2-11</string> + <string name="description_amtvrs_y7" translatable="false">Suitable for ages 7-16</string> + <string name="description_amtvrs_ga" translatable="false">Suitable for general audiences</string> + <string name="description_amtvrs_tw" translatable="false">Suitable for teens ages 9 and up</string> + <string name="description_amtvrs_t" translatable="false">Suitable for teens ages 12 and up</string> + <string name="description_amtvrs_a" translatable="false">Suitable only for adults ages 18 and up</string> <!-- Age specific TV content rating system strings for AM TV --> <string name="display_name_amtvas" translatable="false">AM-TV-AS</string> - <string name="description_amtvas">Age specific TV content rating system strings for Armenia</string> + <string name="description_amtvas" translatable="false">Age specific TV content rating system strings for Armenia</string> <string name="display_name_amtvas_ec" translatable="false">EC</string> <string name="display_name_amtvas_e" translatable="false">E</string> <string name="display_name_amtvas_e9" translatable="false">E9</string> <string name="display_name_amtvas_t" translatable="false">T</string> <string name="display_name_amtvas_m" translatable="false">M</string> <string name="display_name_amtvas_ao" translatable="false">AO</string> - <string name="description_amtvas_ec">Suitable for ages 2 and up</string> - <string name="description_amtvas_e">Suitable for ages 5 and up</string> - <string name="description_amtvas_e9">Suitable for ages 9 and up</string> - <string name="description_amtvas_t">Suitable for ages 12 and up</string> - <string name="description_amtvas_m">Suitable for ages 16 and up</string> - <string name="description_amtvas_ao">Suitable for ages 17 and up</string> + <string name="description_amtvas_ec" translatable="false">Suitable for ages 2 and up</string> + <string name="description_amtvas_e" translatable="false">Suitable for ages 5 and up</string> + <string name="description_amtvas_e9" translatable="false">Suitable for ages 9 and up</string> + <string name="description_amtvas_t" translatable="false">Suitable for ages 12 and up</string> + <string name="description_amtvas_m" translatable="false">Suitable for ages 16 and up</string> + <string name="description_amtvas_ao" translatable="false">Suitable for ages 17 and up</string> <!-- TV content rating system strings for AR TV --> <string name="display_name_artv" translatable="false">AR-TV</string> @@ -4903,10 +4907,10 @@ <string name="display_name_artv_13" translatable="false">Apto para mayores de 13 años</string> <string name="display_name_artv_16" translatable="false">Apto para mayores de 16 años</string> <string name="display_name_artv_18" translatable="false">Apto para mayores de 18 años</string> - <string name="description_artv_all">Suitable for all audiences. Programs may contain mild violence, language and mature situations</string> - <string name="description_artv_13">Suitable for ages 13 and up. Programs may contain mild to moderate language and mild violence and sexual references</string> - <string name="description_artv_16">Suitable for ages 16 and up. Programs may contain more intensive violence and coarse language, partial nudity and moderate sexual references</string> - <string name="description_artv_18">Suitable for mature audiences only. Programs contain strong violence, coarse language and explicit sexual references</string> + <string name="description_artv_all" translatable="false">Suitable for all audiences. Programs may contain mild violence, language and mature situations</string> + <string name="description_artv_13" translatable="false">Suitable for ages 13 and up. Programs may contain mild to moderate language and mild violence and sexual references</string> + <string name="description_artv_16" translatable="false">Suitable for ages 16 and up. Programs may contain more intensive violence and coarse language, partial nudity and moderate sexual references</string> + <string name="description_artv_18" translatable="false">Suitable for mature audiences only. Programs contain strong violence, coarse language and explicit sexual references</string> <!-- TV content rating system strings for AU TV --> <string name="display_name_autv" translatable="false">Australian TV Classification</string> @@ -4917,13 +4921,13 @@ <string name="display_name_autv_ma15" translatable="false">MA 15+</string> <string name="display_name_autv_r18" translatable="false">R 18+</string> <string name="display_name_autv_x18" translatable="false">X 18+</string> - <string name="description_autv_ctc">This has advertising approval, but is not yet classified</string> - <string name="description_autv_g">The content is very mild in impact, and suitable for everyone</string> - <string name="description_autv_pg">The content is mild in impact, but it may contain content that children find confusing or upsetting and may require the guidance or parents and guardians</string> - <string name="description_autv_m">The content is moderate in impact, and it is recommended for teenagers aged 15 years and over</string> - <string name="description_autv_ma15">The content is strong in impact, and it is legally restricted to persons 15 years and over</string> - <string name="description_autv_r18">The content is high in impact, and it is restricted to adults</string> - <string name="description_autv_x18">The content is restricted to adults. This classification is a special and legally restricted category which contains only sexually explicit content</string> + <string name="description_autv_ctc" translatable="false">This has advertising approval, but is not yet classified</string> + <string name="description_autv_g" translatable="false">The content is very mild in impact, and suitable for everyone</string> + <string name="description_autv_pg" translatable="false">The content is mild in impact, but it may contain content that children find confusing or upsetting and may require the guidance or parents and guardians</string> + <string name="description_autv_m" translatable="false">The content is moderate in impact, and it is recommended for teenagers aged 15 years and over</string> + <string name="description_autv_ma15" translatable="false">The content is strong in impact, and it is legally restricted to persons 15 years and over</string> + <string name="description_autv_r18" translatable="false">The content is high in impact, and it is restricted to adults</string> + <string name="description_autv_x18" translatable="false">The content is restricted to adults. This classification is a special and legally restricted category which contains only sexually explicit content</string> <!-- TV content rating system strings for BG TV --> <string name="display_name_bgtv" translatable="false">BG-TV</string> @@ -4932,11 +4936,11 @@ <string name="display_name_bgtv_c" translatable="false">C</string> <string name="display_name_bgtv_d" translatable="false">D</string> <string name="display_name_bgtv_x" translatable="false">X</string> - <string name="description_bgtv_a">Recommended to children. When the film confirms the ideals of humanism or popularizes the national and world cultures or contributes to upbringing children</string> - <string name="description_bgtv_b">No restrictive recommendations from the Committee. When the film is in no way contrary to the universal rules of morality in this country, has no restrictive recommendations from the Committee and does not fall in rating A</string> - <string name="description_bgtv_c">No persons under the age of 12 are admitted unless accompanied by an adult. When the film contains certain erotic scenes or scenes with drinking, taking drugs or stimulants or a few scenes of violence</string> - <string name="description_bgtv_d">No persons under the age of 16 are admitted. When the film contains quite a number of erotic scenes or scenes with drinking, taking drugs or stimulants or a considerable number of scenes showing violence</string> - <string name="description_bgtv_x">No persons under the age of 18 are admitted. When the film is naturalistically erotic or shows violence in an ostentatious manner</string> + <string name="description_bgtv_a" translatable="false">Recommended to children. When the film confirms the ideals of humanism or popularizes the national and world cultures or contributes to upbringing children</string> + <string name="description_bgtv_b" translatable="false">No restrictive recommendations from the Committee. When the film is in no way contrary to the universal rules of morality in this country, has no restrictive recommendations from the Committee and does not fall in rating A</string> + <string name="description_bgtv_c" translatable="false">No persons under the age of 12 are admitted unless accompanied by an adult. When the film contains certain erotic scenes or scenes with drinking, taking drugs or stimulants or a few scenes of violence</string> + <string name="description_bgtv_d" translatable="false">No persons under the age of 16 are admitted. When the film contains quite a number of erotic scenes or scenes with drinking, taking drugs or stimulants or a considerable number of scenes showing violence</string> + <string name="description_bgtv_x" translatable="false">No persons under the age of 18 are admitted. When the film is naturalistically erotic or shows violence in an ostentatious manner</string> <!-- TV content rating system strings for BR TV --> <string name="display_name_brtv" translatable="false">Brazil Content Rating</string> @@ -4946,12 +4950,12 @@ <string name="display_name_brtv_14" translatable="false">14 anos</string> <string name="display_name_brtv_16" translatable="false">16 anos</string> <string name="display_name_brtv_18" translatable="false">18 anos</string> - <string name="description_brtv_l">Content is suitable for all audiences</string> - <string name="description_brtv_10">Content suitable for viewers over the age of 10</string> - <string name="description_brtv_12">Content suitable for viewers over the age of 12</string> - <string name="description_brtv_14">Content suitable for viewers over the age of 14</string> - <string name="description_brtv_16">Content suitable for viewers over the age of 16</string> - <string name="description_brtv_18">Content suitable for viewers over the age of 18</string> + <string name="description_brtv_l" translatable="false">Content is suitable for all audiences</string> + <string name="description_brtv_10" translatable="false">Content suitable for viewers over the age of 10</string> + <string name="description_brtv_12" translatable="false">Content suitable for viewers over the age of 12</string> + <string name="description_brtv_14" translatable="false">Content suitable for viewers over the age of 14</string> + <string name="description_brtv_16" translatable="false">Content suitable for viewers over the age of 16</string> + <string name="description_brtv_18" translatable="false">Content suitable for viewers over the age of 18</string> <!-- TV content rating system strings for CA TV --> <string name="display_name_catv" translatable="false">Canadian TV Classification System</string> @@ -4962,20 +4966,20 @@ <string name="display_name_catv_pg" translatable="false">PG</string> <string name="display_name_catv_14" translatable="false">14+</string> <string name="display_name_catv_18" translatable="false">18+</string> - <string name="description_catv_exempt">Shows which are exempt from ratings (such as news and sports programming) will not display an on-screen rating at all</string> - <string name="description_catv_c">Programming suitable for children ages of 2–7 years. No profanity or sexual content of any level allowed. Contains little violence</string> - <string name="description_catv_c8">Suitable for children ages 8+. Low level violence and fantasy horror is allowed. No foul language is allowed, but occasional "socially offensive and discriminatory" language is allowed if in the context of the story. No sexual content of any level allowed</string> - <string name="description_catv_g">Suitable for general audiences. Programming suitable for the entire family with mild violence, and mild profanity and/or censored language</string> - <string name="description_catv_pg">Parental guidance. Moderate violence and moderate profanity is allowed, as is brief nudity and sexual references if important to the context of the story</string> - <string name="description_catv_14">Programming intended for viewers ages 14 and older. May contain strong violence and strong profanity, and depictions of sexual activity as long as they are within the context of a story</string> - <string name="description_catv_18">Programming intended for viewers ages 18 and older. May contain explicit violence and sexual activity</string> + <string name="description_catv_exempt" translatable="false">Shows which are exempt from ratings (such as news and sports programming) will not display an on-screen rating at all</string> + <string name="description_catv_c" translatable="false">Programming suitable for children ages of 2-7 years. No profanity or sexual content of any level allowed. Contains little violence</string> + <string name="description_catv_c8" translatable="false">Suitable for children ages 8+. Low level violence and fantasy horror is allowed. No foul language is allowed, but occasional "socially offensive and discriminatory" language is allowed if in the context of the story. No sexual content of any level allowed</string> + <string name="description_catv_g" translatable="false">Suitable for general audiences. Programming suitable for the entire family with mild violence, and mild profanity and/or censored language</string> + <string name="description_catv_pg" translatable="false">Parental guidance. Moderate violence and moderate profanity is allowed, as is brief nudity and sexual references if important to the context of the story</string> + <string name="description_catv_14" translatable="false">Programming intended for viewers ages 14 and older. May contain strong violence and strong profanity, and depictions of sexual activity as long as they are within the context of a story</string> + <string name="description_catv_18" translatable="false">Programming intended for viewers ages 18 and older. May contain explicit violence and sexual activity</string> <!-- TV content rating system strings for CH TV --> <string name="display_name_chtv" translatable="false">CH-TV</string> <string name="display_name_chtv_all" translatable="false">All ages</string> <string name="display_name_chtv_red" translatable="false">Red rectangle</string> - <string name="description_chtv_all">This program is suitable for all ages</string> - <string name="description_chtv_red">This program contains scenes that may hurt sensitive people, therefore the red symbol will be displayed</string> + <string name="description_chtv_all" translatable="false">This program is suitable for all ages</string> + <string name="description_chtv_red" translatable="false">This program contains scenes that may hurt sensitive people, therefore the red symbol will be displayed</string> <!-- TV content rating system strings for CL TV --> <string name="display_name_cltv" translatable="false">CL-TV</string> @@ -4986,13 +4990,13 @@ <string name="display_name_cltv_f" translatable="false">F</string> <string name="display_name_cltv_r" translatable="false">R</string> <string name="display_name_cltv_a" translatable="false">A</string> - <string name="description_cltv_i">Programs suitable for all children</string> - <string name="description_cltv_i7">Programs recommended for children ages 7 or older</string> - <string name="description_cltv_i10">Programs recommended for children ages 10 or older</string> - <string name="description_cltv_i12">Programs recommended for children and teens ages 12 or older</string> - <string name="description_cltv_f">Programs suitable for a general audience, with content appropriate for all ages</string> - <string name="description_cltv_r">Programs may content not suitable for children not accompanied by an adult</string> - <string name="description_cltv_a">Programs suitable for adult audiences only (ages 18 or older), may contain coarse language, and sexual or explicit situations</string> + <string name="description_cltv_i" translatable="false">Programs suitable for all children</string> + <string name="description_cltv_i7" translatable="false">Programs recommended for children ages 7 or older</string> + <string name="description_cltv_i10" translatable="false">Programs recommended for children ages 10 or older</string> + <string name="description_cltv_i12" translatable="false">Programs recommended for children and teens ages 12 or older</string> + <string name="description_cltv_f" translatable="false">Programs suitable for a general audience, with content appropriate for all ages</string> + <string name="description_cltv_r" translatable="false">Programs may content not suitable for children not accompanied by an adult</string> + <string name="description_cltv_a" translatable="false">Programs suitable for adult audiences only (ages 18 or older), may contain coarse language, and sexual or explicit situations</string> <!-- TV content rating system strings for DE TV --> <string name="display_name_detv" translatable="false">DE-TV</string> @@ -5000,10 +5004,10 @@ <string name="display_name_detv_12" translatable="false">ab 12 Jahren</string> <string name="display_name_detv_16" translatable="false">ab 16 Jahren</string> <string name="display_name_detv_18" translatable="false">ab 18 Jahren</string> - <string name="description_detv_all">The program is suitable for all ages</string> - <string name="description_detv_12">The program is not suitable for viewers under the age of 12</string> - <string name="description_detv_16">The program is not suitable for viewers under the age of 16</string> - <string name="description_detv_18">The program is not suitable for viewers under the age of 18</string> + <string name="description_detv_all" translatable="false">The program is suitable for all ages</string> + <string name="description_detv_12" translatable="false">The program is not suitable for viewers under the age of 12</string> + <string name="description_detv_16" translatable="false">The program is not suitable for viewers under the age of 16</string> + <string name="description_detv_18" translatable="false">The program is not suitable for viewers under the age of 18</string> <!-- TV content rating system strings for DK TV --> <string name="display_name_dktv" translatable="false">DK-TV</string> @@ -5011,10 +5015,10 @@ <string name="display_name_dktv_y" translatable="false">Yellow symbol</string> <string name="display_name_dktv_r" translatable="false">Red symbol</string> <string name="display_name_dktv_b" translatable="false">Blue symbol</string> - <string name="description_dktv_g">programs suitable for all ages</string> - <string name="description_dktv_y">programs suitable children accompanied by an adult</string> - <string name="description_dktv_r">programs containing material with more intensive content </string> - <string name="description_dktv_b">programs containing explicit content and strictly for adults only</string> + <string name="description_dktv_g" translatable="false">programs suitable for all ages</string> + <string name="description_dktv_y" translatable="false">programs suitable children accompanied by an adult</string> + <string name="description_dktv_r" translatable="false">programs containing material with more intensive content </string> + <string name="description_dktv_b" translatable="false">programs containing explicit content and strictly for adults only</string> <!-- TV content rating system strings for ES TV --> <string name="display_name_estv" translatable="false">ES-TV</string> @@ -5025,13 +5029,13 @@ <string name="display_name_estv_12" translatable="false">12</string> <string name="display_name_estv_16" translatable="false">16</string> <string name="display_name_estv_18" translatable="false">18</string> - <string name="description_estv_tp">Recommended for all ages</string> - <string name="description_estv_i">Specially recommended for preschoolers and kids</string> - <string name="description_estv_7">Recommended for people older than 7 years old</string> - <string name="description_estv_7i">Recommended for kids older than 7 years old</string> - <string name="description_estv_12">Recommended for people older than 12 years old</string> - <string name="description_estv_16">Recommended for people older than 16 years old</string> - <string name="description_estv_18">Recommended for people older than 18 years old</string> + <string name="description_estv_tp" translatable="false">Recommended for all ages</string> + <string name="description_estv_i" translatable="false">Specially recommended for preschoolers and kids</string> + <string name="description_estv_7" translatable="false">Recommended for people older than 7 years old</string> + <string name="description_estv_7i" translatable="false">Recommended for kids older than 7 years old</string> + <string name="description_estv_12" translatable="false">Recommended for people older than 12 years old</string> + <string name="description_estv_16" translatable="false">Recommended for people older than 16 years old</string> + <string name="description_estv_18" translatable="false">Recommended for people older than 18 years old</string> <!-- TV content rating system strings for FI TV --> <string name="display_name_fitv" translatable="false">FI-TV</string> @@ -5040,11 +5044,11 @@ <string name="display_name_fitv_k12" translatable="false">K12</string> <string name="display_name_fitv_k16" translatable="false">K16</string> <string name="display_name_fitv_k18" translatable="false">K18</string> - <string name="description_fitv_s">Allowed at all times</string> - <string name="description_fitv_k7">Not recommended for children under 7</string> - <string name="description_fitv_k12">Not recommended for children under 12</string> - <string name="description_fitv_k16">Not recommended for children under 16</string> - <string name="description_fitv_k18">Not recommended for children under 18</string> + <string name="description_fitv_s" translatable="false">Allowed at all times</string> + <string name="description_fitv_k7" translatable="false">Not recommended for children under 7</string> + <string name="description_fitv_k12" translatable="false">Not recommended for children under 12</string> + <string name="description_fitv_k16" translatable="false">Not recommended for children under 16</string> + <string name="description_fitv_k18" translatable="false">Not recommended for children under 18</string> <!-- TV content rating system strings for FR TV --> <string name="display_name_frtv" translatable="false">FR-TV</string> @@ -5053,11 +5057,11 @@ <string name="display_name_frtv_12" translatable="false">Déconseillé aux -12 ans</string> <string name="display_name_frtv_16" translatable="false">Déconseillé aux -16 ans</string> <string name="display_name_frtv_18" translatable="false">Déconseillé aux -18 ans</string> - <string name="description_frtv_all">Appropriate for all ages</string> - <string name="description_frtv_10">Not recommended for children under 10</string> - <string name="description_frtv_12">Not recommended for children under 12</string> - <string name="description_frtv_16">Not recommended for children under 16</string> - <string name="description_frtv_18">Not recommended for persons under 18</string> + <string name="description_frtv_all" translatable="false">Appropriate for all ages</string> + <string name="description_frtv_10" translatable="false">Not recommended for children under 10</string> + <string name="description_frtv_12" translatable="false">Not recommended for children under 12</string> + <string name="description_frtv_16" translatable="false">Not recommended for children under 16</string> + <string name="description_frtv_18" translatable="false">Not recommended for persons under 18</string> <!-- TV content rating system strings for GR TV --> <string name="display_name_grtv" translatable="false">GR-TV</string> @@ -5066,20 +5070,20 @@ <string name="display_name_grtv_12" translatable="false">White triangle in orange background</string> <string name="display_name_grtv_15" translatable="false">White square in purple background</string> <string name="display_name_grtv_18" translatable="false">White X in red background</string> - <string name="description_grtv_all">Suitable for all ages</string> - <string name="description_grtv_10">Parental consent suggested</string> - <string name="description_grtv_12">Required parental consent</string> - <string name="description_grtv_15">Suitable for minors over the age of 15</string> - <string name="description_grtv_18">Suitable only for adults profanity before midnight is punishable by fine, except when used in the context of the program</string> + <string name="description_grtv_all" translatable="false">Suitable for all ages</string> + <string name="description_grtv_10" translatable="false">Parental consent suggested</string> + <string name="description_grtv_12" translatable="false">Required parental consent</string> + <string name="description_grtv_15" translatable="false">Suitable for minors over the age of 15</string> + <string name="description_grtv_18" translatable="false">Suitable only for adults profanity before midnight is punishable by fine, except when used in the context of the program</string> <!-- TV content rating system strings for HK TV --> <string name="display_name_hktv" translatable="false">HK-TV</string> <string name="display_name_hktv_g" translatable="false">G</string> <string name="display_name_hktv_pg" translatable="false">PG</string> <string name="display_name_hktv_m" translatable="false">M</string> - <string name="description_hktv_g">For general audiences</string> - <string name="description_hktv_pg">Programs are unsuitable for children, parental guidance is recommended</string> - <string name="description_hktv_m">Programs are recommended only for adult viewers above the age of 18</string> + <string name="description_hktv_g" translatable="false">For general audiences</string> + <string name="description_hktv_pg" translatable="false">Programs are unsuitable for children, parental guidance is recommended</string> + <string name="description_hktv_m" translatable="false">Programs are recommended only for adult viewers above the age of 18</string> <!-- TV content rating system strings for HU TV --> <string name="display_name_hutv" translatable="false">HU-TV</string> @@ -5089,12 +5093,12 @@ <string name="display_name_hutv_12" translatable="false">12</string> <string name="display_name_hutv_16" translatable="false">16</string> <string name="display_name_hutv_18" translatable="false">18</string> - <string name="description_hutv_u">Programs can be viewed by any age</string> - <string name="description_hutv_cf">Programs recommended for children. It is an optional rating, there is no obligation for broadcasters to indicate it</string> - <string name="description_hutv_6">Programs not recommended for children below the age of 6, may not contain any violence or sexual content</string> - <string name="description_hutv_12">Programs not recommended for children below the age of 12, may contain light sexual content or explicit language</string> - <string name="description_hutv_16">Programs not recommended for teens and children below the age of 16, may contain more intensive violence and sexual content</string> - <string name="description_hutv_18">The program is recommended only for adult viewers (for ages 18 and up), may contain explicit violence and explicit sexual content</string> + <string name="description_hutv_u" translatable="false">Programs can be viewed by any age</string> + <string name="description_hutv_cf" translatable="false">Programs recommended for children. It is an optional rating, there is no obligation for broadcasters to indicate it</string> + <string name="description_hutv_6" translatable="false">Programs not recommended for children below the age of 6, may not contain any violence or sexual content</string> + <string name="description_hutv_12" translatable="false">Programs not recommended for children below the age of 12, may contain light sexual content or explicit language</string> + <string name="description_hutv_16" translatable="false">Programs not recommended for teens and children below the age of 16, may contain more intensive violence and sexual content</string> + <string name="description_hutv_18" translatable="false">The program is recommended only for adult viewers (for ages 18 and up), may contain explicit violence and explicit sexual content</string> <!-- TV content rating system strings for ID TV --> <string name="display_name_idtv" translatable="false">ID-TV</string> @@ -5106,14 +5110,14 @@ <string name="display_name_idtv_r" translatable="false">R</string> <string name="display_name_idtv_r_bo" translatable="false">R-BO</string> <string name="display_name_idtv_d" translatable="false">D</string> - <string name="description_idtv_p">Suitable for children from ages 2 through 11</string> - <string name="description_idtv_a">Suitable for teens and children from ages 7 through 16</string> - <string name="description_idtv_a_bo">Suitable for children ages 5 through 10, with parental guidance or permission</string> - <string name="description_idtv_su">Suitable for general audiences</string> - <string name="description_idtv_bo">Parental guidance suggested for ages 5 and under</string> - <string name="description_idtv_r">Suitable for teens from ages 13 through 17</string> - <string name="description_idtv_r_bo">Suitable for teens with parental guidance or permission</string> - <string name="description_idtv_d">Suitable for viewers over 18 and older only</string> + <string name="description_idtv_p" translatable="false">Suitable for children from ages 2 through 11</string> + <string name="description_idtv_a" translatable="false">Suitable for teens and children from ages 7 through 16</string> + <string name="description_idtv_a_bo" translatable="false">Suitable for children ages 5 through 10, with parental guidance or permission</string> + <string name="description_idtv_su" translatable="false">Suitable for general audiences</string> + <string name="description_idtv_bo" translatable="false">Parental guidance suggested for ages 5 and under</string> + <string name="description_idtv_r" translatable="false">Suitable for teens from ages 13 through 17</string> + <string name="description_idtv_r_bo" translatable="false">Suitable for teens with parental guidance or permission</string> + <string name="description_idtv_d" translatable="false">Suitable for viewers over 18 and older only</string> <!-- TV content rating system strings for IE TV --> <string name="display_name_ietv" translatable="false">RTÉ programme classifications</string> @@ -5122,11 +5126,11 @@ <string name="display_name_ietv_ya" translatable="false">YA</string> <string name="display_name_ietv_ps" translatable="false">PS</string> <string name="display_name_ietv_ma" translatable="false">MA</string> - <string name="description_ietv_ga">Suitable for all ages</string> - <string name="description_ietv_ch">Suitable for children ages 5 to 10, may contain comedic violence or action fantasy violence</string> - <string name="description_ietv_ya">Suitable for adolescent audiences, may contain thematic elements that would appeal to teenagers</string> - <string name="description_ietv_ps">Suitable for more mature viewers, more mature themes may be present</string> - <string name="description_ietv_ma">Most restrictive classification, allowing for heavy subject matter and coarse language</string> + <string name="description_ietv_ga" translatable="false">Suitable for all ages</string> + <string name="description_ietv_ch" translatable="false">Suitable for children ages 5 to 10, may contain comedic violence or action fantasy violence</string> + <string name="description_ietv_ya" translatable="false">Suitable for adolescent audiences, may contain thematic elements that would appeal to teenagers</string> + <string name="description_ietv_ps" translatable="false">Suitable for more mature viewers, more mature themes may be present</string> + <string name="description_ietv_ma" translatable="false">Most restrictive classification, allowing for heavy subject matter and coarse language</string> <!-- TV content rating system strings for IL TV --> <string name="display_name_iltv" translatable="false">IL-TV</string> @@ -5135,11 +5139,11 @@ <string name="display_name_iltv_15" translatable="false">15+</string> <string name="display_name_iltv_18" translatable="false">18+</string> <string name="display_name_iltv_e" translatable="false">E</string> - <string name="description_iltv_g">General audience; anyone, regardless of age, can view the program, usually news and children\'s programming</string> - <string name="description_iltv_12">Suitable for teens and children ages 12 and over, no child under 12 are permitted to view the program</string> - <string name="description_iltv_15">Suitable for teens ages 15 and over, no child under 15 may view the programme</string> - <string name="description_iltv_18">Suitable for adults only, no minors may view the programme</string> - <string name="description_iltv_e">Exempt from classification</string> + <string name="description_iltv_g" translatable="false">General audience; anyone, regardless of age, can view the program, usually news and children\'s programming</string> + <string name="description_iltv_12" translatable="false">Suitable for teens and children ages 12 and over, no child under 12 are permitted to view the program</string> + <string name="description_iltv_15" translatable="false">Suitable for teens ages 15 and over, no child under 15 may view the programme</string> + <string name="description_iltv_18" translatable="false">Suitable for adults only, no minors may view the programme</string> + <string name="description_iltv_e" translatable="false">Exempt from classification</string> <!-- TV content rating system strings for IN TV --> <string name="display_name_intv" translatable="false">IN-TV</string> @@ -5147,10 +5151,10 @@ <string name="display_name_intv_u/a" translatable="false">U/A</string> <string name="display_name_intv_a" translatable="false">A</string> <string name="display_name_intv_s" translatable="false">S</string> - <string name="description_intv_u">Unrestricted public exhibition</string> - <string name="description_intv_u/a">Unrestricted public exhibition, but with a caution regarding parental guidance to those under 12 years of age</string> - <string name="description_intv_a">Public exhibition restricted to adults 18 years of age and older only</string> - <string name="description_intv_s">Public exhibition restricted to members of any profession or any class of persons</string> + <string name="description_intv_u" translatable="false">Unrestricted public exhibition</string> + <string name="description_intv_u/a" translatable="false">Unrestricted public exhibition, but with a caution regarding parental guidance to those under 12 years of age</string> + <string name="description_intv_a" translatable="false">Public exhibition restricted to adults 18 years of age and older only</string> + <string name="description_intv_s" translatable="false">Public exhibition restricted to members of any profession or any class of persons</string> <!-- TV content rating system strings for IS TV --> <string name="display_name_istv" translatable="false">IS-TV</string> @@ -5161,13 +5165,13 @@ <string name="display_name_istv_14" translatable="false">14</string> <string name="display_name_istv_16" translatable="false">16</string> <string name="display_name_istv_18" translatable="false">18</string> - <string name="description_istv_l">Programs suitable for all ages</string> - <string name="description_istv_7">Programs suitable for ages 7 and older</string> - <string name="description_istv_10">Programs suitable for ages 10 and older</string> - <string name="description_istv_12">Programs suitable for ages 12 and older</string> - <string name="description_istv_14">Programs suitable for ages 14 and older</string> - <string name="description_istv_16">Programs suitable for ages 16 and older</string> - <string name="description_istv_18">Programs suitable for ages 18 and older</string> + <string name="description_istv_l" translatable="false">Programs suitable for all ages</string> + <string name="description_istv_7" translatable="false">Programs suitable for ages 7 and older</string> + <string name="description_istv_10" translatable="false">Programs suitable for ages 10 and older</string> + <string name="description_istv_12" translatable="false">Programs suitable for ages 12 and older</string> + <string name="description_istv_14" translatable="false">Programs suitable for ages 14 and older</string> + <string name="description_istv_16" translatable="false">Programs suitable for ages 16 and older</string> + <string name="description_istv_18" translatable="false">Programs suitable for ages 18 and older</string> <!-- TV content rating system strings for KR TV --> <string name="display_name_krtv" translatable="false">KR-TV</string> @@ -5176,11 +5180,11 @@ <string name="display_name_krtv_12" translatable="false">12세이상시청가</string> <string name="display_name_krtv_15" translatable="false">15세이상시청가</string> <string name="display_name_krtv_19" translatable="false">19세이상시청가</string> - <string name="description_krtv_all">Appropriate for all ages</string> - <string name="description_krtv_7">May contain material inappropriate for children younger than 7, and parental discretion should be used</string> - <string name="description_krtv_12">May deemed inappropriate for those younger than 12, and parental discretion should be used</string> - <string name="description_krtv_15">May be inappropriate for children under 15, and that parental discretion should be used</string> - <string name="description_krtv_19">For adults only</string> + <string name="description_krtv_all" translatable="false">Appropriate for all ages</string> + <string name="description_krtv_7" translatable="false">May contain material inappropriate for children younger than 7, and parental discretion should be used</string> + <string name="description_krtv_12" translatable="false">May deemed inappropriate for those younger than 12, and parental discretion should be used</string> + <string name="description_krtv_15" translatable="false">May be inappropriate for children under 15, and that parental discretion should be used</string> + <string name="description_krtv_19" translatable="false">For adults only</string> <!-- TV content rating system strings for MV TV --> <string name="display_name_mvtv" translatable="false">MV-TV</string> @@ -5193,15 +5197,15 @@ <string name="display_name_mvtv_18" translatable="false">18+</string> <string name="display_name_mvtv_21" translatable="false">21+</string> <string name="display_name_mvtv_x" translatable="false">X</string> - <string name="description_mvtv_y">Young children</string> - <string name="description_mvtv_g">General viewing for all ages</string> - <string name="description_mvtv_pg">Parental guidance is required unaccompanied children</string> - <string name="description_mvtv_pg-12">Parental guidance is required for children under the age of 12</string> - <string name="description_mvtv_12">Teens and children aged 12 and older may watch, otherwise restricted</string> - <string name="description_mvtv_15">Restricted to viewers aged 15 and above</string> - <string name="description_mvtv_18">Restricted to viewers aged 18 and above</string> - <string name="description_mvtv_21">Restricted to viewers aged 21 and above</string> - <string name="description_mvtv_x">Most restrictive classification, only adults ages 25 and above may view</string> + <string name="description_mvtv_y" translatable="false">Young children</string> + <string name="description_mvtv_g" translatable="false">General viewing for all ages</string> + <string name="description_mvtv_pg" translatable="false">Parental guidance is required unaccompanied children</string> + <string name="description_mvtv_pg-12" translatable="false">Parental guidance is required for children under the age of 12</string> + <string name="description_mvtv_12" translatable="false">Teens and children aged 12 and older may watch, otherwise restricted</string> + <string name="description_mvtv_15" translatable="false">Restricted to viewers aged 15 and above</string> + <string name="description_mvtv_18" translatable="false">Restricted to viewers aged 18 and above</string> + <string name="description_mvtv_21" translatable="false">Restricted to viewers aged 21 and above</string> + <string name="description_mvtv_x" translatable="false">Most restrictive classification, only adults ages 25 and above may view</string> <!-- TV content rating system strings for MX TV --> <string name="display_name_mxtv" translatable="false">MX-TV</string> @@ -5211,21 +5215,21 @@ <string name="display_name_mxtv_c" translatable="false">C</string> <string name="display_name_mxtv_d" translatable="false">D</string> <string name="display_name_mxtv_rc" translatable="false">RC</string> - <string name="description_mxtv_a">Appropriate for all ages, parental guidance is recommended for children under 7 years</string> - <string name="description_mxtv_b">Designed for ages 12 and older, may contain some sexual situations, mild violence, and mild language</string> - <string name="description_mxtv_b-15">Designed for ages 15 and up, slightly more intensive than the \'A\' and \'B\' ratings</string> - <string name="description_mxtv_c">Designed to be viewed by adults aged 18 or older only, generally more intensive content </string> - <string name="description_mxtv_d">Designed to be viewed only by mature adults (at least 21 years of age and over), contains extreme content matter</string> - <string name="description_mxtv_rc">Banned from public television in Mexico</string> + <string name="description_mxtv_a" translatable="false">Appropriate for all ages, parental guidance is recommended for children under 7 years</string> + <string name="description_mxtv_b" translatable="false">Designed for ages 12 and older, may contain some sexual situations, mild violence, and mild language</string> + <string name="description_mxtv_b-15" translatable="false">Designed for ages 15 and up, slightly more intensive than the \'A\' and \'B\' ratings</string> + <string name="description_mxtv_c" translatable="false">Designed to be viewed by adults aged 18 or older only, generally more intensive content </string> + <string name="description_mxtv_d" translatable="false">Designed to be viewed only by mature adults (at least 21 years of age and over), contains extreme content matter</string> + <string name="description_mxtv_rc" translatable="false">Banned from public television in Mexico</string> <!-- TV content rating system strings for MY TV --> <string name="display_name_mytv" translatable="false">MY-TV</string> <string name="display_name_mytv_u" translatable="false">U</string> <string name="display_name_mytv_p13" translatable="false">P13</string> <string name="display_name_mytv_18" translatable="false">18</string> - <string name="description_mytv_u">General viewing for all ages, can be broadcast anytime</string> - <string name="description_mytv_p13">For viewers ages 13 and above, children under 13 needs parental guidance, can be broadcast anytime, but some elements may only be broadcast at night</string> - <string name="description_mytv_18">For viewers ages 18 and above only</string> + <string name="description_mytv_u" translatable="false">General viewing for all ages, can be broadcast anytime</string> + <string name="description_mytv_p13" translatable="false">For viewers ages 13 and above, children under 13 needs parental guidance, can be broadcast anytime, but some elements may only be broadcast at night</string> + <string name="description_mytv_18" translatable="false">For viewers ages 18 and above only</string> <!-- TV content rating system strings for NL TV --> <string name="display_name_nltv" translatable="false">NICAM</string> @@ -5240,31 +5244,31 @@ <string name="display_name_nltv_9" translatable="false">Let op met kinderen tot 9 jaar</string> <string name="display_name_nltv_12" translatable="false">Let op met kinderen tot 12 jaar</string> <string name="display_name_nltv_16" translatable="false">Let op met kinderen tot 16 jaar</string> - <string name="description_nltv_v">Violence</string> - <string name="description_nltv_f">Scary or Disturbing Content </string> - <string name="description_nltv_s">Sexual Content</string> - <string name="description_nltv_d">Discrimination</string> - <string name="description_nltv_da">Drug and/or Alcohol abuse</string> - <string name="description_nltv_l">Bad Language</string> - <string name="description_nltv_al">All Ages</string> - <string name="description_nltv_6">Parental advisory for children under 6</string> - <string name="description_nltv_9">Parental advisory for children under 9</string> - <string name="description_nltv_12">Parental advisory for children under 12</string> - <string name="description_nltv_16">Parental advisory for children under 16</string> + <string name="description_nltv_v" translatable="false">Violence\nApplicable to NL_TV_AL, NL_TV_6, NL_TV_9, NL_TV_12, NL_TV_16</string> + <string name="description_nltv_f" translatable="false">Scary or Disturbing ContentViolence\nApplicable to NL_TV_AL, NL_TV_6, NL_TV_9, NL_TV_12, NL_TV_16</string> + <string name="description_nltv_s" translatable="false">Sexual Content\nApplicable to NL_TV_AL, NL_TV_6, NL_TV_9, NL_TV_12, NL_TV_16</string> + <string name="description_nltv_d" translatable="false">Discrimination\nApplicable to NL_TV_AL, NL_TV_6, NL_TV_9, NL_TV_12, NL_TV_16</string> + <string name="description_nltv_da" translatable="false">Drug and/or Alcohol abuse\nApplicable to NL_TV_AL, NL_TV_6, NL_TV_9, NL_TV_12, NL_TV_16</string> + <string name="description_nltv_l" translatable="false">Bad Language\nApplicable to NL_TV_AL, NL_TV_6, NL_TV_9, NL_TV_12, NL_TV_16</string> + <string name="description_nltv_al" translatable="false">All Ages</string> + <string name="description_nltv_6" translatable="false">Parental advisory for children under 6</string> + <string name="description_nltv_9" translatable="false">Parental advisory for children under 9</string> + <string name="description_nltv_12" translatable="false">Parental advisory for children under 12</string> + <string name="description_nltv_16" translatable="false">Parental advisory for children under 16</string> <!-- TV content rating system strings for NZF(Free) TV --> <string name="display_name_nzftv" translatable="false">NZ-Free-TV</string> - <string name="description_nzftv">New Zealand\'s free-to-air TV content rating system</string> + <string name="description_nzftv" translatable="false">TV content rating system for free-to-air channels in New Zealand</string> <string name="display_name_nzftv_g" translatable="false">G</string> <string name="display_name_nzftv_pgr" translatable="false">PGR</string> <string name="display_name_nzftv_ao" translatable="false">AO</string> - <string name="description_nzftv_g">These exclude material likely to harm children under 14 and can screen at any time. Programmes may not necessarily be designed for younger viewers, but must not contain material likely to cause them undue distress or discomfort</string> - <string name="description_nzftv_pgr">Programmes more suited to more mature viewers. These are not necessarily unsuitable for children, but viewer discretion is advised, and parents and guardians are encouraged to supervise younger viewers</string> - <string name="description_nzftv_ao">Contain material of an adult nature handled in such a way that it is unsuitable for children</string> + <string name="description_nzftv_g" translatable="false">These exclude material likely to harm children under 14 and can screen at any time. Programmes may not necessarily be designed for younger viewers, but must not contain material likely to cause them undue distress or discomfort</string> + <string name="description_nzftv_pgr" translatable="false">Programmes more suited to more mature viewers. These are not necessarily unsuitable for children, but viewer discretion is advised, and parents and guardians are encouraged to supervise younger viewers</string> + <string name="description_nzftv_ao" translatable="false">Contain material of an adult nature handled in such a way that it is unsuitable for children</string> <!-- TV content rating system strings for NZP(Pay) TV --> <string name="display_name_nzptv" translatable="false">NZ-Pay-TV</string> - <string name="description_nzptv">New Zealand\'s pay TV content rating system</string> + <string name="description_nzptv" translatable="false">TV content rating system for Pay TV channels in New Zealand</string> <string name="display_name_nzptv_c" translatable="false">C</string> <string name="display_name_nzptv_v" translatable="false">V</string> <string name="display_name_nzptv_l" translatable="false">L</string> @@ -5274,46 +5278,46 @@ <string name="display_name_nzptv_m" translatable="false">M</string> <string name="display_name_nzptv_16" translatable="false">16</string> <string name="display_name_nzptv_18" translatable="false">18</string> - <string name="description_nzptv_c">Content may offend</string> - <string name="description_nzptv_v">Violence</string> - <string name="description_nzptv_l">Language</string> - <string name="description_nzptv_s">Sexual content</string> - <string name="description_nzptv_g">suitable for general audiences</string> - <string name="description_nzptv_pg">Parental guidance recommended for under 10</string> - <string name="description_nzptv_m">Suitable for mature audiences 13 and up</string> - <string name="description_nzptv_16">Suitable for viewers 16 and up</string> - <string name="description_nzptv_18">Suitable for viewers 18 and up</string> + <string name="description_nzptv_c" translatable="false">Content may offend\nApplicable to NZ_PTV_PG, NZ_PTV_M, NZ_PTV_16, NZ_PTV_18</string> + <string name="description_nzptv_v" translatable="false">Violence\nApplicable to NZ_PTV_PG, NZ_PTV_M, NZ_PTV_16, NZ_PTV_18</string> + <string name="description_nzptv_l" translatable="false">Language\nApplicable to NZ_PTV_PG, NZ_PTV_M, NZ_PTV_16, NZ_PTV_18</string> + <string name="description_nzptv_s" translatable="false">Sexual content\nApplicable to NZ_PTV_PG, NZ_PTV_M, NZ_PTV_16, NZ_PTV_18</string> + <string name="description_nzptv_g" translatable="false">suitable for general audiences</string> + <string name="description_nzptv_pg" translatable="false">Parental guidance recommended for under 10</string> + <string name="description_nzptv_m" translatable="false">Suitable for mature audiences 13 and up</string> + <string name="description_nzptv_16" translatable="false">Suitable for viewers 16 and up</string> + <string name="description_nzptv_18" translatable="false">Suitable for viewers 18 and up</string> <!-- TV content rating system strings for PE TV --> <string name="display_name_petv" translatable="false">PE-TV</string> - <string name="description_petv">TV content rating system for some Peruvian channels in Peru</string> + <string name="description_petv" translatable="false">TV content rating system for some Peruvian channels in Peru</string> <string name="display_name_petv_a" translatable="false">Apt</string> <string name="display_name_petv_14" translatable="false">14</string> <string name="display_name_petv_18" translatable="false">18</string> - <string name="description_petv_a">Suitable for all audiences</string> - <string name="description_petv_14">Suitable for people aged 14 and above only</string> - <string name="description_petv_18">Suitable for people aged 18 and above only</string> + <string name="description_petv_a" translatable="false">Suitable for all audiences</string> + <string name="description_petv_14" translatable="false">Suitable for people aged 14 and above only</string> + <string name="description_petv_18" translatable="false">Suitable for people aged 18 and above only</string> <!-- TV content rating system strings for America TV in PE --> <string name="display_name_peatv" translatable="false">PE-ATV</string> - <string name="description_peatv">TV content rating system for America Television in Peru that uses its own rating system</string> + <string name="description_peatv" translatable="false">TV content rating system for America Television in Peru that uses its own rating system</string> <string name="display_name_peatv_gp" translatable="false">GP</string> <string name="display_name_peatv_pg" translatable="false">PG</string> <string name="display_name_peatv_14" translatable="false">TV-14</string> <string name="display_name_peatv_18" translatable="false">TV-18</string> - <string name="description_peatv_gp">General audience</string> - <string name="description_peatv_pg">Parental guidance required for under 6</string> - <string name="description_peatv_14">Suitable for people aged 14 and above only</string> - <string name="description_peatv_18">Suitable for people aged 18 and above only</string> + <string name="description_peatv_gp" translatable="false">General audience</string> + <string name="description_peatv_pg" translatable="false">Parental guidance required for under 6</string> + <string name="description_peatv_14" translatable="false">Suitable for people aged 14 and above only</string> + <string name="description_peatv_18" translatable="false">Suitable for people aged 18 and above only</string> <!-- TV content rating system strings for PH TV --> <string name="display_name_phtv" translatable="false">MTRCB</string> <string name="display_name_phtv_g" translatable="false">G</string> <string name="display_name_phtv_pg" translatable="false">PG</string> <string name="display_name_phtv_spg" translatable="false">SPG</string> - <string name="description_phtv_g">Suitable for all public viewers</string> - <string name="description_phtv_pg">Programmes rated PG may contain scenes or other content that are unsuitable for children without the guidance of a parent</string> - <string name="description_phtv_spg">Contains mature themes or moderate to intense violence, which may be deemed unfit for children to watch without strict parental supervision</string> + <string name="description_phtv_g" translatable="false">Suitable for all public viewers</string> + <string name="description_phtv_pg" translatable="false">Programmes rated PG may contain scenes or other content that are unsuitable for children without the guidance of a parent</string> + <string name="description_phtv_spg" translatable="false">Contains mature themes or moderate to intense violence, which may be deemed unfit for children to watch without strict parental supervision</string> <!-- TV content rating system strings for PL TV --> <string name="display_name_pltv" translatable="false">PL-TV</string> @@ -5322,11 +5326,11 @@ <string name="display_name_pltv_12" translatable="false">12</string> <string name="display_name_pltv_16" translatable="false">16</string> <string name="display_name_pltv_18" translatable="false">18</string> - <string name="description_pltv_g">Positive or neutral view of the world, little to no violence, non-sexual love, and no sexual content</string> - <string name="description_pltv_7">Age 7 and above. May additionally contain some mild language, bloodless violence, and a more negative view of the world</string> - <string name="description_pltv_12">Age 12 and above. May contain some foul language, some violence, and some sexual content</string> - <string name="description_pltv_16">Age 16 and above. Deviant social behaviour, world filled with violence and sexuality, simplified picture of adulthood, display of physical force, especially in controversial social context, immoral behaviour without ethic dilemma, putting the blame on the victim, excessive concentration on material possessions</string> - <string name="description_pltv_18">Age 18 and above. One-sided display of the joys of adult life without showing responsibilities, social justification of violent behaviour, excessive vulgarity, use of racial slurs and social stereotypes, explicit sexual content, praise of aggression or vulgarity</string> + <string name="description_pltv_g" translatable="false">Positive or neutral view of the world, little to no violence, non-sexual love, and no sexual content</string> + <string name="description_pltv_7" translatable="false">Age 7 and above. May additionally contain some mild language, bloodless violence, and a more negative view of the world</string> + <string name="description_pltv_12" translatable="false">Age 12 and above. May contain some foul language, some violence, and some sexual content</string> + <string name="description_pltv_16" translatable="false">Age 16 and above. Deviant social behaviour, world filled with violence and sexuality, simplified picture of adulthood, display of physical force, especially in controversial social context, immoral behaviour without ethic dilemma, putting the blame on the victim, excessive concentration on material possessions</string> + <string name="description_pltv_18" translatable="false">Age 18 and above. One-sided display of the joys of adult life without showing responsibilities, social justification of violent behaviour, excessive vulgarity, use of racial slurs and social stereotypes, explicit sexual content, praise of aggression or vulgarity</string> <!-- TV content rating system strings for PT TV --> <string name="display_name_pttv" translatable="false">PT-TV</string> @@ -5334,10 +5338,10 @@ <string name="display_name_pttv_10" translatable="false">10</string> <string name="display_name_pttv_12" translatable="false">12</string> <string name="display_name_pttv_16" translatable="false">16</string> - <string name="description_pttv_t">Suitable for all</string> - <string name="description_pttv_10">May not be suitable for children under 10, parental guidance advised</string> - <string name="description_pttv_12">May not be suitable for children under 12, parental guidance advised</string> - <string name="description_pttv_16">Not suitable for children under 16</string> + <string name="description_pttv_t" translatable="false">Suitable for all</string> + <string name="description_pttv_10" translatable="false">May not be suitable for children under 10, parental guidance advised</string> + <string name="description_pttv_12" translatable="false">May not be suitable for children under 12, parental guidance advised</string> + <string name="description_pttv_16" translatable="false">Not suitable for children under 16</string> <!-- TV content rating system strings for RO TV --> <string name="display_name_rotv" translatable="false">RO-TV</string> @@ -5347,12 +5351,12 @@ <string name="display_name_rotv_12" translatable="false">12</string> <string name="display_name_rotv_15" translatable="false">15</string> <string name="display_name_rotv_18" translatable="false">18</string> - <string name="description_rotv_y">Young Ages</string> - <string name="description_rotv_g">General Exhibition</string> - <string name="description_rotv_ap">Parental guidance is recommended for children below the age of 12</string> - <string name="description_rotv_12">Forbidden for children under 12 years of age</string> - <string name="description_rotv_15">Forbidden for children under 15 years of age</string> - <string name="description_rotv_18">Forbidden for children under 18 years of age</string> + <string name="description_rotv_y" translatable="false">Young Ages</string> + <string name="description_rotv_g" translatable="false">General Exhibition</string> + <string name="description_rotv_ap" translatable="false">Parental guidance is recommended for children below the age of 12</string> + <string name="description_rotv_12" translatable="false">Forbidden for children under 12 years of age</string> + <string name="description_rotv_15" translatable="false">Forbidden for children under 15 years of age</string> + <string name="description_rotv_18" translatable="false">Forbidden for children under 18 years of age</string> <!-- TV content rating system strings for RU TV --> <string name="display_name_rutv" translatable="false">RU-TV</string> @@ -5361,11 +5365,11 @@ <string name="display_name_rutv_12" translatable="false">12+</string> <string name="display_name_rutv_16" translatable="false">16+</string> <string name="display_name_rutv_18" translatable="false">18+</string> - <string name="description_rutv_0">Can be watched by Any Age</string> - <string name="description_rutv_6">Only kids the age of 6 or older can watch</string> - <string name="description_rutv_12">Only kids the age of 12 or older can watch</string> - <string name="description_rutv_16">Only teens the age of 16 or older can watch</string> - <string name="description_rutv_18">Restricted to children ONLY people 18 or older</string> + <string name="description_rutv_0" translatable="false">Can be watched by Any Age</string> + <string name="description_rutv_6" translatable="false">Only kids the age of 6 or older can watch</string> + <string name="description_rutv_12" translatable="false">Only kids the age of 12 or older can watch</string> + <string name="description_rutv_16" translatable="false">Only teens the age of 16 or older can watch</string> + <string name="description_rutv_18" translatable="false">Restricted to children ONLY people 18 or older</string> <!-- TV content rating system strings for RS TV --> <string name="display_name_rstv" translatable="false">RS-TV</string> @@ -5376,27 +5380,27 @@ <string name="display_name_rstv_16" translatable="false">16</string> <string name="display_name_rstv_17" translatable="false">17</string> <string name="display_name_rstv_18" translatable="false">18</string> - <string name="description_rstv_g">Program suitable for all ages</string> - <string name="description_rstv_12">Program not suitable for children under the age of 12 </string> - <string name="description_rstv_14">Program not suitable for children/teens under the age of 14</string> - <string name="description_rstv_15">Program not suitable for children/teens under the age of 15</string> - <string name="description_rstv_16">Program not suitable for children/teens under the age of 16</string> - <string name="description_rstv_17">Program not suitable for children/teens under the age of 17</string> - <string name="description_rstv_18">Program not suitable for minors under the age of 18</string> + <string name="description_rstv_g" translatable="false">Program suitable for all ages</string> + <string name="description_rstv_12" translatable="false">Program not suitable for children under the age of 12 </string> + <string name="description_rstv_14" translatable="false">Program not suitable for children/teens under the age of 14</string> + <string name="description_rstv_15" translatable="false">Program not suitable for children/teens under the age of 15</string> + <string name="description_rstv_16" translatable="false">Program not suitable for children/teens under the age of 16</string> + <string name="description_rstv_17" translatable="false">Program not suitable for children/teens under the age of 17</string> + <string name="description_rstv_18" translatable="false">Program not suitable for minors under the age of 18</string> <!-- TV content rating system strings for SGF(Free-to-Air) TV --> <string name="display_name_sgftv" translatable="false">SG-Free-TV</string> <string name="display_name_sgftv_pg" translatable="false">PG</string> <string name="display_name_sgftv_pg13" translatable="false">PG13</string> - <string name="description_sgftv_pg">Suitable for most but parents should guide their young</string> - <string name="description_sgftv_pg13">Parental Guidance Strongly Cautioned – Suitable for 13 And Above</string> + <string name="description_sgftv_pg" translatable="false">Suitable for most but parents should guide their young</string> + <string name="description_sgftv_pg13" translatable="false">Parental Guidance Strongly Cautioned - Suitable for 13 And Above</string> <!-- TV content rating system strings for SGP(Pay TV) TV --> <string name="display_name_sgptv" translatable="false">SG-Pay-TV</string> <string name="display_name_sgptv_nc16" translatable="false">NC16</string> <string name="display_name_sgptv_m18" translatable="false">M18</string> - <string name="description_sgptv_nc16">No Children Under 16</string> - <string name="description_sgptv_m18">Nobody under age 18 is admitted</string> + <string name="description_sgptv_nc16" translatable="false">No Children Under 16</string> + <string name="description_sgptv_m18" translatable="false">Nobody under age 18 is admitted</string> <!-- TV content rating system strings for SI TV --> <string name="display_name_sitv" translatable="false">SI-TV</string> @@ -5404,10 +5408,10 @@ <string name="display_name_sitv_12" translatable="false">+12</string> <string name="display_name_sitv_15" translatable="false">+15</string> <string name="display_name_sitv_ad" translatable="false">AD</string> - <string name="description_sitv_vs">Parental guidance suggested (for children under 6)</string> - <string name="description_sitv_12">Content suitable for teens over 12 years</string> - <string name="description_sitv_15">Content suitable for teens over 15 years</string> - <string name="description_sitv_ad">Content exclusively for adults</string> + <string name="description_sitv_vs" translatable="false">Parental guidance suggested (for children under 6)</string> + <string name="description_sitv_12" translatable="false">Content suitable for teens over 12 years</string> + <string name="description_sitv_15" translatable="false">Content suitable for teens over 15 years</string> + <string name="description_sitv_ad" translatable="false">Content exclusively for adults</string> <!-- TV content rating system strings for TH TV --> <string name="display_name_thtv" translatable="false">TH-TV</string> @@ -5417,12 +5421,12 @@ <string name="display_name_thtv_pg13" translatable="false">PG13</string> <string name="display_name_thtv_pg18" translatable="false">PG18</string> <string name="display_name_thtv_adults" translatable="false">Adults</string> - <string name="description_thtv_primary">Content suitable for primary school aged children</string> - <string name="description_thtv_children">Content suitable for children between 6–12 years old</string> - <string name="description_thtv_general">Content suitable for general audiences</string> - <string name="description_thtv_pg13">Content suitable for people aged 13 and above, but can be watched by those who are under the recommended age if parental guidance is provided</string> - <string name="description_thtv_pg18">Content suitable for people aged above 18 years old; those who are younger that 18 must be provided with parental guidance</string> - <string name="description_thtv_adults">Content unsuitable for children and youngsters</string> + <string name="description_thtv_primary" translatable="false">Content suitable for primary school aged children</string> + <string name="description_thtv_children" translatable="false">Content suitable for children between 6-12 years old</string> + <string name="description_thtv_general" translatable="false">Content suitable for general audiences</string> + <string name="description_thtv_pg13" translatable="false">Content suitable for people aged 13 and above, but can be watched by those who are under the recommended age if parental guidance is provided</string> + <string name="description_thtv_pg18" translatable="false">Content suitable for people aged above 18 years old; those who are younger that 18 must be provided with parental guidance</string> + <string name="description_thtv_adults" translatable="false">Content unsuitable for children and youngsters</string> <!-- TV content rating system strings for TR TV --> <string name="display_name_trtv" translatable="false">TR-TV</string> @@ -5430,10 +5434,10 @@ <string name="display_name_trtv_7" translatable="false">7+</string> <string name="display_name_trtv_13" translatable="false">13+</string> <string name="display_name_trtv_18" translatable="false">18+</string> - <string name="description_trtv_g">General audience. Suitable for all ages</string> - <string name="description_trtv_7">Suitable for ages 7 and over</string> - <string name="description_trtv_13">Suitable for ages 13 and over</string> - <string name="description_trtv_18">Suitable for ages 13 and over</string> + <string name="description_trtv_g" translatable="false">General audience. Suitable for all ages</string> + <string name="description_trtv_7" translatable="false">Suitable for ages 7 and over</string> + <string name="description_trtv_13" translatable="false">Suitable for ages 13 and over</string> + <string name="description_trtv_18" translatable="false">Suitable for ages 13 and over</string> <!-- TV content rating system strings for TW TV --> <string name="display_name_twtv" translatable="false">TW-TV</string> @@ -5441,54 +5445,54 @@ <string name="display_name_twtv_p" translatable="false">Protected category</string> <string name="display_name_twtv_pg" translatable="false">Parental guidance category</string> <string name="display_name_twtv_r" translatable="false">Restricted category</string> - <string name="description_twtv_g">For all ages</string> - <string name="description_twtv_p">Not suitable for children under 6 years old. People aged 6 but under 12 require guidance from accompanying adults to watch</string> - <string name="description_twtv_pg">Not suitable for people under 12 years of age. Parental guidance is required for people aged 12 but under 18</string> - <string name="description_twtv_r">For adults only and people under 18 years of age must not watch</string> + <string name="description_twtv_g" translatable="false">For all ages</string> + <string name="description_twtv_p" translatable="false">Not suitable for children under 6 years old. People aged 6 but under 12 require guidance from accompanying adults to watch</string> + <string name="description_twtv_pg" translatable="false">Not suitable for people under 12 years of age. Parental guidance is required for people aged 12 but under 18</string> + <string name="description_twtv_r" translatable="false">For adults only and people under 18 years of age must not watch</string> <!-- TV content rating system strings for UA TV --> <string name="display_name_uatv" translatable="false">UA-TV</string> <string name="display_name_uatv_green circle" translatable="false">Green Circle</string> <string name="display_name_uatv_yellow triangle" translatable="false">Yellow Triangle</string> <string name="display_name_uatv_red square" translatable="false">Red Square</string> - <string name="description_uatv_green circle">This program does not have age restrictions</string> - <string name="description_uatv_yellow triangle">Children must view this program with parents. In it program there are fragments, which unsuitable for children</string> - <string name="description_uatv_red square">This program is only for adult viewers. In it there are scenes with nudity, drug use, or violence</string> + <string name="description_uatv_green circle" translatable="false">This program does not have age restrictions</string> + <string name="description_uatv_yellow triangle" translatable="false">Children must view this program with parents. In it program there are fragments, which unsuitable for children</string> + <string name="description_uatv_red square" translatable="false">This program is only for adult viewers. In it there are scenes with nudity, drug use, or violence</string> <!-- TV content rating system strings for US TV --> - <string name="display_name_ustvpg" translatable="false">US-TV</string> - <string name="description_ustvpg">The TV Parental Guidelines</string> - <string name="display_name_ustvpg_d" translatable="false">D</string> - <string name="display_name_ustvpg_l" translatable="false">L</string> - <string name="display_name_ustvpg_s" translatable="false">S</string> - <string name="display_name_ustvpg_v" translatable="false">V</string> - <string name="display_name_ustvpg_fv" translatable="false">FV</string> - <string name="display_name_ustvpg_y" translatable="false">TV-Y</string> - <string name="display_name_ustvpg_y7" translatable="false">TV-Y7</string> - <string name="display_name_ustvpg_g" translatable="false">TV-G</string> - <string name="display_name_ustvpg_pg" translatable="false">TV-PG</string> - <string name="display_name_ustvpg_14" translatable="false">TV-14</string> - <string name="display_name_ustvpg_ma" translatable="false">TV-MA</string> - <string name="description_ustvpg_d">Suggestive dialogue (Usually means talks about sex)</string> - <string name="description_ustvpg_l">Coarse language</string> - <string name="description_ustvpg_s">Sexual content</string> - <string name="description_ustvpg_v">Violence</string> - <string name="description_ustvpg_fv">Fantasy violence (Children\'s programming only)</string> - <string name="description_ustvpg_y">This program is designed to be appropriate for all children</string> - <string name="description_ustvpg_y7">This program is designed for children age 7 and above</string> - <string name="description_ustvpg_g">Most parents would find this program suitable for all ages</string> - <string name="description_ustvpg_pg">This program contains material that parents may find unsuitable for younger children</string> - <string name="description_ustvpg_14">This program contains some material that many parents would find unsuitable for children under 14 years of age</string> - <string name="description_ustvpg_ma">This program is specifically designed to be viewed by adults and therefore may be unsuitable for children under 17</string> + <string name="display_name_ustv" translatable="false">US-TV</string> + <string name="description_ustv" translatable="false">TV content rating system for United States</string> + <string name="display_name_ustv_d" translatable="false">D</string> + <string name="display_name_ustv_l" translatable="false">L</string> + <string name="display_name_ustv_s" translatable="false">S</string> + <string name="display_name_ustv_v" translatable="false">V</string> + <string name="display_name_ustv_fv" translatable="false">FV</string> + <string name="display_name_ustv_y" translatable="false">TV-Y</string> + <string name="display_name_ustv_y7" translatable="false">TV-Y7</string> + <string name="display_name_ustv_g" translatable="false">TV-G</string> + <string name="display_name_ustv_pg" translatable="false">TV-PG</string> + <string name="display_name_ustv_14" translatable="false">TV-14</string> + <string name="display_name_ustv_ma" translatable="false">TV-MA</string> + <string name="description_ustv_d" translatable="false">Suggestive dialogue (Usually means talks about sex)\nApplicable to US_TV_PG, US_TV_14, US_TV</string> + <string name="description_ustv_l" translatable="false">Coarse language\nApplicable to US_TV_PG, US_TV_14</string> + <string name="description_ustv_s" translatable="false">Sexual content\nApplicable to US_TV_PG, US_TV_14, US_TV_MA</string> + <string name="description_ustv_v" translatable="false">Violence\nApplicable to US_TV_PG, US_TV_14, US_TV_MA</string> + <string name="description_ustv_fv" translatable="false">Fantasy violence (Children\'s programming only)\nApplicable to US_TV_Y7</string> + <string name="description_ustv_y" translatable="false">This program is designed to be appropriate for all children</string> + <string name="description_ustv_y7" translatable="false">This program is designed for children age 7 and above</string> + <string name="description_ustv_g" translatable="false">Most parents would find this program suitable for all ages</string> + <string name="description_ustv_pg" translatable="false">This program contains material that parents may find unsuitable for younger children</string> + <string name="description_ustv_14" translatable="false">This program contains some material that many parents would find unsuitable for children under 14 years of age</string> + <string name="description_ustv_ma" translatable="false">This program is specifically designed to be viewed by adults and therefore may be unsuitable for children under 17</string> <!-- TV content rating system strings for VE TV --> <string name="display_name_vetv" translatable="false">VE-TV</string> <string name="display_name_vetv_tu" translatable="false">TU</string> <string name="display_name_vetv_su" translatable="false">SU</string> <string name="display_name_vetv_a" translatable="false">A</string> - <string name="description_vetv_tu">For all ages</string> - <string name="description_vetv_su">Parental guidance for young viewers</string> - <string name="description_vetv_a">Mature viewers</string> + <string name="description_vetv_tu" translatable="false">For all ages</string> + <string name="description_vetv_su" translatable="false">Parental guidance for young viewers</string> + <string name="description_vetv_a" translatable="false">Mature viewers</string> <!-- TV content rating system strings for ZA TV --> <string name="display_name_zatv" translatable="false">ZA-TV</string> @@ -5504,18 +5508,18 @@ <string name="display_name_zatv_16" translatable="false">16</string> <string name="display_name_zatv_18" translatable="false">18</string> <string name="display_name_zatv_r18" translatable="false">R18</string> - <string name="description_zatv_d">Drug</string> - <string name="description_zatv_v">Violence</string> - <string name="description_zatv_n">Nudity</string> - <string name="description_zatv_p">Prejudice</string> - <string name="description_zatv_s">Sex</string> - <string name="description_zatv_l">Language</string> - <string name="description_zatv_f">This is a program/film that does not contain any obscenity, and is suitable for family viewing. A logo must be displayed in the corner of the screen for 30 seconds after each commercial break</string> - <string name="description_zatv_pg">Children under 6 may watch this program/film, but must be accompanied by an adult. This program contains an adult related theme, which might include very mild language, violence and sexual innuendo. A logo must be displayed in the corner of the screen for one minute after each commercial break</string> - <string name="description_zatv_13">Children under 13 are prohibited from watching this program/film. This program contains mild language, violence and sexual innuendo. A logo must be displayed in the corner of the screen for two minutes after each commercial break</string> - <string name="description_zatv_16">Children under 16 are prohibited from watching this program/film. It contains moderate violence, language, and some sexual situations. In the case of television, this program may only be broadcast after 9pm–4:30am. A logo must be displayed in the corner of the screen for five minutes after each commercial break. A full-screen warning must be issued before the start of the program. If the program is longer than an hour, a warning must be displayed every half an hour</string> - <string name="description_zatv_18">Children under 18 are prohibited from watching this program/film. It contains extreme violence, language and/or graphic sexual content. In the case of television, this program may only be broadcast from 10pm–4:30am. A logo must be displayed in the corner of the screen for the duration of the program. A full-screen warning must be issued before the start of the program and after each commercial break</string> - <string name="description_zatv_r18">This is reserved for films of an extreme sexual nature (pornography). R18 films may only be distributed in the form of video and DVD in a controlled environment (e.g. Adult Shops). No public viewing of this film may take place. R18 films may not be broadcast on television and in cinemas</string> + <string name="description_zatv_d" translatable="false">Drug\nApplicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, ZA_TV_R18</string> + <string name="description_zatv_v" translatable="false">Violence\nApplicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, ZA_TV_R18</string> + <string name="description_zatv_n" translatable="false">Nudity\nApplicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, ZA_TV_R18</string> + <string name="description_zatv_p" translatable="false">Prejudice\nApplicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, ZA_TV_R18</string> + <string name="description_zatv_s" translatable="false">Sex\nApplicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, ZA_TV_R18</string> + <string name="description_zatv_l" translatable="false">Language\nApplicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, ZA_TV_R18</string> + <string name="description_zatv_f" translatable="false">This is a program/film that does not contain any obscenity, and is suitable for family viewing. A logo must be displayed in the corner of the screen for 30 seconds after each commercial break</string> + <string name="description_zatv_pg" translatable="false">Children under 6 may watch this program/film, but must be accompanied by an adult. This program contains an adult related theme, which might include very mild language, violence and sexual innuendo. A logo must be displayed in the corner of the screen for one minute after each commercial break</string> + <string name="description_zatv_13" translatable="false">Children under 13 are prohibited from watching this program/film. This program contains mild language, violence and sexual innuendo. A logo must be displayed in the corner of the screen for two minutes after each commercial break</string> + <string name="description_zatv_16" translatable="false">Children under 16 are prohibited from watching this program/film. It contains moderate violence, language, and some sexual situations. In the case of television, this program may only be broadcast after 9pm-4:30am. A logo must be displayed in the corner of the screen for five minutes after each commercial break. A full-screen warning must be issued before the start of the program. If the program is longer than an hour, a warning must be displayed every half an hour</string> + <string name="description_zatv_18" translatable="false">Children under 18 are prohibited from watching this program/film. It contains extreme violence, language and/or graphic sexual content. In the case of television, this program may only be broadcast from 10pm-4:30am. A logo must be displayed in the corner of the screen for the duration of the program. A full-screen warning must be issued before the start of the program and after each commercial break</string> + <string name="description_zatv_r18" translatable="false">This is reserved for films of an extreme sexual nature (pornography). R18 films may only be distributed in the form of video and DVD in a controlled environment (e.g. Adult Shops). No public viewing of this film may take place. R18 films may not be broadcast on television and in cinemas</string> <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description --> <string name="battery_saver_description">To help improve battery life, battery saver reduces your device’s performance and limits vibration and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging</string> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 35baf9c7eeb8..8fc9bacdf111 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1360,7 +1360,7 @@ please see styles_device_defaults.xml. <item name="lightZ">800dp</item> <item name="lightRadius">800dp</item> <item name="ambientShadowAlpha">0.06</item> - <item name="spotShadowAlpha">0.22</item> + <item name="spotShadowAlpha">0.16</item> </style> </resources> diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index 97d4bf6780e0..f028222b50a7 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -426,7 +426,6 @@ please see styles_device_defaults.xml. <style name="Widget.Material.Button" parent="Widget.Button"> <item name="background">@drawable/btn_default_material</item> <item name="textAppearance">?attr/textAppearanceButton</item> - <item name="textColor">?attr/textColorPrimary</item> <item name="minHeight">48dip</item> <item name="minWidth">88dip</item> <item name="stateListAnimator">@anim/button_state_list_anim_material</item> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 0ebf0b548b74..a4bec17d3112 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -349,6 +349,7 @@ <java-symbol type="dimen" name="notification_text_size" /> <java-symbol type="dimen" name="notification_title_text_size" /> <java-symbol type="dimen" name="notification_subtext_size" /> + <java-symbol type="dimen" name="notification_large_font_vert_pad" /> <java-symbol type="dimen" name="immersive_mode_cling_width" /> <java-symbol type="dimen" name="circular_display_mask_offset" /> @@ -609,9 +610,11 @@ <java-symbol type="string" name="last_month" /> <java-symbol type="string" name="launchBrowserDefault" /> <java-symbol type="string" name="lock_to_app_toast" /> + <java-symbol type="string" name="lock_to_app_toast_accessible" /> <java-symbol type="string" name="lock_to_app_toast_locked" /> <java-symbol type="string" name="lock_to_app_title" /> <java-symbol type="string" name="lock_to_app_description" /> + <java-symbol type="string" name="lock_to_app_description_accessible" /> <java-symbol type="string" name="lock_to_app_negative" /> <java-symbol type="string" name="lock_to_app_positive" /> <java-symbol type="layout" name="lock_to_app_checkbox" /> @@ -1699,7 +1702,6 @@ <java-symbol type="layout" name="notification_template_material_base" /> <java-symbol type="layout" name="notification_template_material_big_base" /> <java-symbol type="layout" name="notification_template_material_big_picture" /> - <java-symbol type="layout" name="notification_template_material_big_text" /> <java-symbol type="layout" name="notification_template_material_inbox" /> <java-symbol type="layout" name="notification_template_material_media" /> <java-symbol type="layout" name="notification_template_material_big_media" /> @@ -1721,11 +1723,11 @@ <java-symbol type="anim" name="push_up_out" /> <java-symbol type="anim" name="lock_screen_behind_enter" /> <java-symbol type="anim" name="lock_screen_behind_enter_wallpaper" /> + <java-symbol type="anim" name="lock_screen_behind_enter_fade_in" /> <java-symbol type="anim" name="lock_screen_wallpaper_exit" /> <java-symbol type="bool" name="config_alwaysUseCdmaRssi" /> <java-symbol type="dimen" name="status_bar_icon_size" /> - <java-symbol type="dimen" name="system_bar_icon_size" /> <java-symbol type="drawable" name="list_selector_pressed_holo_dark" /> <java-symbol type="drawable" name="scrubber_control_disabled_holo" /> <java-symbol type="drawable" name="scrubber_control_selector_holo" /> @@ -1978,4 +1980,8 @@ <java-symbol type="bool" name="config_sms_decode_gsm_8bit_data" /> <java-symbol type="string" name="time_picker_am_label" /> <java-symbol type="string" name="time_picker_pm_label" /> + <java-symbol type="dimen" name="text_size_small_material" /> + <java-symbol type="attr" name="checkMarkGravity" /> + <java-symbol type="layout" name="select_dialog_singlechoice_material" /> + <java-symbol type="layout" name="select_dialog_multichoice_material" /> </resources> diff --git a/core/res/res/xml/tv_content_rating_systems.xml b/core/res/res/xml/tv_content_rating_systems.xml index 8e2a23c72525..13182740030f 100644 --- a/core/res/res/xml/tv_content_rating_systems.xml +++ b/core/res/res/xml/tv_content_rating_systems.xml @@ -1549,75 +1549,75 @@ </rating-system-definition> <!-- TV content rating system for US TV --> - <rating-system-definition id="US_TVPG" - displayName="@string/display_name_ustvpg" - description="@string/description_ustvpg" + <rating-system-definition id="US_TV" + displayName="@string/display_name_ustv" + description="@string/description_ustv" country="US"> - <sub-rating-definition id="US_TVPG_D" - displayName="@string/display_name_ustvpg_d" - description="@string/description_ustvpg_d" /> - <sub-rating-definition id="US_TVPG_L" - displayName="@string/display_name_ustvpg_l" - description="@string/description_ustvpg_l" /> - <sub-rating-definition id="US_TVPG_S" - displayName="@string/display_name_ustvpg_s" - description="@string/description_ustvpg_s" /> - <sub-rating-definition id="US_TVPG_V" - displayName="@string/display_name_ustvpg_v" - description="@string/description_ustvpg_v" /> - <sub-rating-definition id="US_TVPG_FV" - displayName="@string/display_name_ustvpg_fv" - description="@string/description_ustvpg_fv" /> + <sub-rating-definition id="US_TV_D" + displayName="@string/display_name_ustv_d" + description="@string/description_ustv_d" /> + <sub-rating-definition id="US_TV_L" + displayName="@string/display_name_ustv_l" + description="@string/description_ustv_l" /> + <sub-rating-definition id="US_TV_S" + displayName="@string/display_name_ustv_s" + description="@string/description_ustv_s" /> + <sub-rating-definition id="US_TV_V" + displayName="@string/display_name_ustv_v" + description="@string/description_ustv_v" /> + <sub-rating-definition id="US_TV_FV" + displayName="@string/display_name_ustv_fv" + description="@string/description_ustv_fv" /> - <rating-definition id="US_TVPG_TV_Y" - displayName="@string/display_name_ustvpg_y" - description="@string/description_ustvpg_y" + <rating-definition id="US_TV_Y" + displayName="@string/display_name_ustv_y" + description="@string/description_ustv_y" ageHint="0" /> - <rating-definition id="US_TVPG_TV_Y7" - displayName="@string/display_name_ustvpg_y7" - description="@string/description_ustvpg_y7" + <rating-definition id="US_TV_Y7" + displayName="@string/display_name_ustv_y7" + description="@string/description_ustv_y7" ageHint="7"> - <sub-rating id="US_TVPG_FV" /> + <sub-rating id="US_TV_FV" /> </rating-definition> - <rating-definition id="US_TVPG_TV_G" - displayName="@string/display_name_ustvpg_g" - description="@string/description_ustvpg_g" + <rating-definition id="US_TV_G" + displayName="@string/display_name_ustv_g" + description="@string/description_ustv_g" ageHint="0" /> - <rating-definition id="US_TVPG_TV_PG" - displayName="@string/display_name_ustvpg_pg" - description="@string/description_ustvpg_pg" + <rating-definition id="US_TV_PG" + displayName="@string/display_name_ustv_pg" + description="@string/description_ustv_pg" ageHint="14"> - <sub-rating id="US_TVPG_D" /> - <sub-rating id="US_TVPG_L" /> - <sub-rating id="US_TVPG_S" /> - <sub-rating id="US_TVPG_V" /> + <sub-rating id="US_TV_D" /> + <sub-rating id="US_TV_L" /> + <sub-rating id="US_TV_S" /> + <sub-rating id="US_TV_V" /> </rating-definition> - <rating-definition id="US_TVPG_TV_14" - displayName="@string/display_name_ustvpg_14" - description="@string/description_ustvpg_14" + <rating-definition id="US_TV_14" + displayName="@string/display_name_ustv_14" + description="@string/description_ustv_14" ageHint="14"> - <sub-rating id="US_TVPG_D" /> - <sub-rating id="US_TVPG_L" /> - <sub-rating id="US_TVPG_S" /> - <sub-rating id="US_TVPG_V" /> + <sub-rating id="US_TV_D" /> + <sub-rating id="US_TV_L" /> + <sub-rating id="US_TV_S" /> + <sub-rating id="US_TV_V" /> </rating-definition> - <rating-definition id="US_TVPG_TV_MA" - displayName="@string/display_name_ustvpg_ma" - description="@string/description_ustvpg_ma" + <rating-definition id="US_TV_MA" + displayName="@string/display_name_ustv_ma" + description="@string/description_ustv_ma" ageHint="17"> - <sub-rating id="US_TVPG_L" /> - <sub-rating id="US_TVPG_S" /> - <sub-rating id="US_TVPG_V" /> + <sub-rating id="US_TV_L" /> + <sub-rating id="US_TV_S" /> + <sub-rating id="US_TV_V" /> </rating-definition> <order> - <rating id="US_TVPG_TV_Y" /> - <rating id="US_TVPG_TV_Y7" /> + <rating id="US_TV_Y" /> + <rating id="US_TV_Y7" /> </order> <order> - <rating id="US_TVPG_TV_G" /> - <rating id="US_TVPG_TV_PG" /> - <rating id="US_TVPG_TV_14" /> - <rating id="US_TVPG_TV_MA" /> + <rating id="US_TV_G" /> + <rating id="US_TV_PG" /> + <rating id="US_TV_14" /> + <rating id="US_TV_MA" /> </order> </rating-system-definition> diff --git a/core/tests/coretests/src/android/net/RouteInfoTest.java b/core/tests/coretests/src/android/net/RouteInfoTest.java index dcacd11776ca..0b88bc703d2c 100644 --- a/core/tests/coretests/src/android/net/RouteInfoTest.java +++ b/core/tests/coretests/src/android/net/RouteInfoTest.java @@ -214,6 +214,29 @@ public class RouteInfoTest extends TestCase { assertFalse(r.isIPv6Default()); } + public void testTruncation() { + LinkAddress l; + RouteInfo r; + + l = new LinkAddress("192.0.2.5/30"); + r = new RouteInfo(l, Address("192.0.2.1"), "wlan0"); + assertEquals("192.0.2.4", r.getDestination().getAddress().getHostAddress()); + + l = new LinkAddress("2001:db8:1:f::5/63"); + r = new RouteInfo(l, Address("2001:db8:5::1"), "wlan0"); + assertEquals("2001:db8:1:e::", r.getDestination().getAddress().getHostAddress()); + } + + // Make sure that creating routes to multicast addresses doesn't throw an exception. Even though + // there's nothing we can do with them, we don't want to crash if, e.g., someone calls + // requestRouteToHostAddress("230.0.0.0", MOBILE_HIPRI); + public void testMulticastRoute() { + RouteInfo r; + r = new RouteInfo(Prefix("230.0.0.0/32"), Address("192.0.2.1"), "wlan0"); + r = new RouteInfo(Prefix("ff02::1/128"), Address("2001:db8::1"), "wlan0"); + // No exceptions? Good. + } + public RouteInfo passThroughParcel(RouteInfo r) { Parcel p = Parcel.obtain(); RouteInfo r2 = null; diff --git a/docs/html/google/gcm/ccs.jd b/docs/html/google/gcm/ccs.jd index 90d8d4c6c02f..1c7c8021b766 100644 --- a/docs/html/google/gcm/ccs.jd +++ b/docs/html/google/gcm/ccs.jd @@ -40,8 +40,6 @@ page.title=GCM Cloud Connection Server (XMPP) <li><a href="{@docRoot}google/gcm/gs.html">Getting Started</a></li> <li><a href="{@docRoot}google/gcm/server.html">Implementing GCM Server</a></li> <li><a href="{@docRoot}google/gcm/client.html">Implementing GCM Client</a></li> -<li><a href="https://services.google.com/fb/forms/gcm/" class="external-link" -target="_android">CCS and User Notifications Signup Form</a></li> </ol> </div> diff --git a/docs/html/google/gcm/gs.jd b/docs/html/google/gcm/gs.jd index 4cfe1bc5101e..ae57b6d6e372 100644 --- a/docs/html/google/gcm/gs.jd +++ b/docs/html/google/gcm/gs.jd @@ -20,7 +20,6 @@ page.tags=cloud,push,messaging <ol class="toc"> <li><a href="https://cloud.google.com/console">Google Cloud Console</a></li> <li><a href="https://developers.google.com/console/help/new/">Google Cloud Console Help</a></li> -<li><a href="https://services.google.com/fb/forms/gcm/" class="external-link" target="_android">CCS and User Notifications Signup Form</a></li> </ol> </div> diff --git a/docs/html/training/volley/index.jd b/docs/html/training/volley/index.jd index ba5b09f8ca3a..97bddaead964 100644 --- a/docs/html/training/volley/index.jd +++ b/docs/html/training/volley/index.jd @@ -20,21 +20,6 @@ startpage=true <li>Android 1.6 (API Level 4) or higher</li> </ul> -<h2>You should also see</h2> -<ul> - <li>For a production quality app that uses Volley, see the 2013 Google I/O - <a href="https://github.com/google/iosched">schedule app</a>. In particular, see: - <ul> - <li><a - href="https://github.com/google/iosched/blob/master/android/src/main/java/com/google/android/apps/iosched/util/ImageLoader.java"> - ImageLoader</a></li> - <li><a - href="https://github.com/google/iosched/blob/master/android/src/main/java/com/google/android/apps/iosched/util/BitmapCache.java"> - BitmapCache</a></li> - </ul> - </li> -</ul> - </div> </div> diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 0dc903a9e626..06586ca85e2d 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -132,6 +132,9 @@ public class Typeface { * @return The best matching typeface. */ public static Typeface create(Typeface family, int style) { + if (style < 0 || style > 3) { + style = 0; + } long ni = 0; if (family != null) { // Return early if we're asked for the same face/style diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java index e3c03a95ae50..0bc4fdfb7877 100644 --- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java @@ -275,7 +275,7 @@ public class AnimatedRotateDrawable extends Drawable implements Drawable.Callbac final int res = a.getResourceId(R.styleable.AnimatedRotateDrawable_drawable, 0); Drawable drawable = null; if (res > 0) { - drawable = r.getDrawable(res); + drawable = r.getDrawable(res, theme); } a.recycle(); diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java index 2cb7b039d6ad..fc38e8a34dbf 100644 --- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java @@ -427,7 +427,7 @@ public class AnimatedStateListDrawable extends StateListDrawable { final Drawable dr; if (drawableRes != 0) { - dr = r.getDrawable(drawableRes); + dr = r.getDrawable(drawableRes, theme); } else { int type; while ((type = parser.next()) == XmlPullParser.TEXT) { @@ -473,7 +473,7 @@ public class AnimatedStateListDrawable extends StateListDrawable { final Drawable dr; if (drawableRes != 0) { - dr = r.getDrawable(drawableRes); + dr = r.getDrawable(drawableRes, theme); } else { int type; while ((type = parser.next()) == XmlPullParser.TEXT) { diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java index cef3377a8fac..5318fa7b0c94 100644 --- a/graphics/java/android/graphics/drawable/AnimationDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java @@ -313,7 +313,7 @@ public class AnimationDrawable extends DrawableContainer implements Runnable, An Drawable dr; if (drawableRes != 0) { - dr = r.getDrawable(drawableRes); + dr = r.getDrawable(drawableRes, theme); } else { while ((type=parser.next()) == XmlPullParser.TEXT) { // Empty diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java index 983eb3bad67f..63b9e0291815 100644 --- a/graphics/java/android/graphics/drawable/RotateDrawable.java +++ b/graphics/java/android/graphics/drawable/RotateDrawable.java @@ -436,7 +436,7 @@ public class RotateDrawable extends Drawable implements Drawable.Callback { com.android.internal.R.styleable.RotateDrawable_drawable, 0); Drawable drawable = null; if (res > 0) { - drawable = r.getDrawable(res); + drawable = r.getDrawable(res, theme); } a.recycle(); diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp index 181230ad7547..9cc83ed68755 100644 --- a/libs/hwui/AmbientShadow.cpp +++ b/libs/hwui/AmbientShadow.cpp @@ -117,10 +117,13 @@ void AmbientShadow::createAmbientShadow(bool isCasterOpaque, // inner ring of points float opacity = 1.0 / (1 + rayHeight[rayIndex] * heightFactor); + // NOTE: Shadow alpha values are transformed when stored in alphavertices, + // so that they can be consumed directly by gFS_Main_ApplyVertexAlphaShadowInterp + float transformedOpacity = acos(1.0f - 2.0f * opacity); AlphaVertex::set(&shadowVertices[rays + rayIndex], intersection.x, intersection.y, - opacity); + transformedOpacity); } if (isCasterOpaque) { diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 7bd0798cb53e..5689e170f5fd 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -703,6 +703,8 @@ void Caches::initTempProperties() { propertyLightPosY = -1.0f; propertyLightPosZ = -1.0f; propertyAmbientRatio = -1.0f; + propertyAmbientShadowStrength = -1; + propertySpotShadowStrength = -1; } void Caches::setTempProperty(const char* name, const char* value) { @@ -723,6 +725,14 @@ void Caches::setTempProperty(const char* name, const char* value) { propertyLightPosZ = fmin(fmax(atof(value), 0.0), 3000.0); ALOGD("lightPos Z = %.2f", propertyLightPosZ); return; + } else if (!strcmp(name, "ambientShadowStrength")) { + propertyAmbientShadowStrength = atoi(value); + ALOGD("ambient shadow strength = 0x%x out of 0xff", propertyAmbientShadowStrength); + return; + } else if (!strcmp(name, "spotShadowStrength")) { + propertySpotShadowStrength = atoi(value); + ALOGD("spot shadow strength = 0x%x out of 0xff", propertySpotShadowStrength); + return; } ALOGD(" failed"); } diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index e00cb0b78ff8..0482430f404a 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -366,6 +366,9 @@ public: float propertyLightPosY; float propertyLightPosZ; float propertyAmbientRatio; + int propertyAmbientShadowStrength; + int propertySpotShadowStrength; + private: enum OverdrawColorSet { kColorSet_Default = 0, diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 7123bfe76216..3fcfbc1f3fed 100755 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1641,9 +1641,9 @@ void OpenGLRenderer::setupDrawNoTexture() { mCaches.disableTexCoordsVertexArray(); } -void OpenGLRenderer::setupDrawAA(bool useShadowInterp) { - mDescription.isAA = true; - mDescription.isShadowAA = useShadowInterp; +void OpenGLRenderer::setupDrawVertexAlpha(bool useShadowAlphaInterp) { + mDescription.hasVertexAlpha = true; + mDescription.useShadowAlphaInterp = useShadowAlphaInterp; } void OpenGLRenderer::setupDrawColor(int color, int alpha) { @@ -2382,7 +2382,7 @@ status_t OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, setupDraw(); setupDrawNoTexture(); - if (isAA) setupDrawAA((displayFlags & kVertexBuffer_ShadowAA)); + if (isAA) setupDrawVertexAlpha((displayFlags & kVertexBuffer_ShadowInterp)); setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha); setupDrawColorFilter(getColorFilter(paint)); setupDrawShader(getShader(paint)); @@ -3166,14 +3166,23 @@ status_t OpenGLRenderer::drawShadow(float casterAlpha, SkPaint paint; paint.setAntiAlias(true); // want to use AlphaVertex - if (ambientShadowVertexBuffer && mAmbientShadowAlpha > 0) { - paint.setARGB(casterAlpha * mAmbientShadowAlpha, 0, 0, 0); - drawVertexBuffer(*ambientShadowVertexBuffer, &paint, kVertexBuffer_ShadowAA); + // The caller has made sure casterAlpha > 0. + float ambientShadowAlpha = mAmbientShadowAlpha; + if (CC_UNLIKELY(mCaches.propertyAmbientShadowStrength >= 0)) { + ambientShadowAlpha = mCaches.propertyAmbientShadowStrength; + } + if (ambientShadowVertexBuffer && ambientShadowAlpha > 0) { + paint.setARGB(casterAlpha * ambientShadowAlpha, 0, 0, 0); + drawVertexBuffer(*ambientShadowVertexBuffer, &paint, kVertexBuffer_ShadowInterp); } - if (spotShadowVertexBuffer && mSpotShadowAlpha > 0) { - paint.setARGB(casterAlpha * mSpotShadowAlpha, 0, 0, 0); - drawVertexBuffer(*spotShadowVertexBuffer, &paint, kVertexBuffer_ShadowAA); + float spotShadowAlpha = mSpotShadowAlpha; + if (CC_UNLIKELY(mCaches.propertySpotShadowStrength >= 0)) { + spotShadowAlpha = mCaches.propertySpotShadowStrength; + } + if (spotShadowVertexBuffer && spotShadowAlpha > 0) { + paint.setARGB(casterAlpha * spotShadowAlpha, 0, 0, 0); + drawVertexBuffer(*spotShadowVertexBuffer, &paint, kVertexBuffer_ShadowInterp); } return DrawGlInfo::kStatusDrew; diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 2a9badda7783..fc95c18e81b8 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -96,7 +96,7 @@ enum ClipSideFlags { enum VertexBufferDisplayFlags { kVertexBuffer_Offset = 0x1, - kVertexBuffer_ShadowAA = 0x2, + kVertexBuffer_ShadowInterp = 0x2, }; /** @@ -847,7 +847,7 @@ private: void setupDrawWithTextureAndColor(bool isAlpha8 = false); void setupDrawWithExternalTexture(); void setupDrawNoTexture(); - void setupDrawAA(bool useShadowInterp); + void setupDrawVertexAlpha(bool useShadowAlphaInterp); void setupDrawColor(int color, int alpha); void setupDrawColor(float r, float g, float b, float a); void setupDrawAlpha8Color(int color, int alpha); diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index 1d95c40b6233..56773f44f9b5 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -71,8 +71,8 @@ namespace uirenderer { #define PROGRAM_GRADIENT_TYPE_SHIFT 33 // 2 bits for gradient type #define PROGRAM_MODULATE_SHIFT 35 -#define PROGRAM_HAS_AA_SHIFT 36 -#define PROGRAM_HAS_SHADOW_AA_SHIFT 37 +#define PROGRAM_HAS_VERTEX_ALPHA_SHIFT 36 +#define PROGRAM_USE_SHADOW_ALPHA_INTERP_SHIFT 37 #define PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT 38 #define PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT 39 @@ -135,8 +135,8 @@ struct ProgramDescription { bool hasBitmap; bool isBitmapNpot; - bool isAA; // drawing with a per-vertex alpha - bool isShadowAA; // drawing per vertex alpha with shadow interpolation + bool hasVertexAlpha; + bool useShadowAlphaInterp; bool hasGradient; Gradient gradientType; @@ -176,8 +176,8 @@ struct ProgramDescription { hasColors = false; - isAA = false; - isShadowAA = false; + hasVertexAlpha = false; + useShadowAlphaInterp = false; modulate = false; @@ -264,8 +264,8 @@ struct ProgramDescription { key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT; if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST; if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT; - if (isAA) key |= programid(0x1) << PROGRAM_HAS_AA_SHIFT; - if (isShadowAA) key |= programid(0x1) << PROGRAM_HAS_SHADOW_AA_SHIFT; + if (hasVertexAlpha) key |= programid(0x1) << PROGRAM_HAS_VERTEX_ALPHA_SHIFT; + if (useShadowAlphaInterp) key |= programid(0x1) << PROGRAM_USE_SHADOW_ALPHA_INTERP_SHIFT; if (hasExternalTexture) key |= programid(0x1) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT; if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT; if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION; diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 2dd89b857107..c802b183d41c 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -46,7 +46,7 @@ const char* gVS_Header_Attributes_TexCoords = "attribute vec2 texCoords;\n"; const char* gVS_Header_Attributes_Colors = "attribute vec4 colors;\n"; -const char* gVS_Header_Attributes_AAVertexShapeParameters = +const char* gVS_Header_Attributes_VertexAlphaParameters = "attribute float vtxAlpha;\n"; const char* gVS_Header_Uniforms_TextureTransform = "uniform mat4 mainTextureTransform;\n"; @@ -64,7 +64,7 @@ const char* gVS_Header_Varyings_HasTexture = "varying vec2 outTexCoords;\n"; const char* gVS_Header_Varyings_HasColors = "varying vec4 outColors;\n"; -const char* gVS_Header_Varyings_IsAAVertexShape = +const char* gVS_Header_Varyings_HasVertexAlpha = "varying float alpha;\n"; const char* gVS_Header_Varyings_HasBitmap = "varying highp vec2 outBitmapTexCoords;\n"; @@ -122,9 +122,7 @@ const char* gVS_Main_Position = " vec4 transformedPosition = projection * transform * position;\n" " gl_Position = transformedPosition;\n"; -const char* gVS_Main_ShadowAAVertexShape = - " alpha = pow(vtxAlpha, 0.667);\n"; -const char* gVS_Main_AAVertexShape = +const char* gVS_Main_VertexAlpha = " alpha = vtxAlpha;\n"; const char* gVS_Main_HasRoundRectClip = @@ -239,10 +237,10 @@ const char* gFS_Main_FetchColor = " fragColor = color;\n"; const char* gFS_Main_ModulateColor = " fragColor *= color.a;\n"; -const char* gFS_Main_AccountForAAVertexShape = +const char* gFS_Main_ApplyVertexAlphaLinearInterp = " fragColor *= alpha;\n"; -const char* gFS_Main_AccountForShadowAAVertexShape = - " fragColor *= pow(alpha, 1.5);\n"; +const char* gFS_Main_ApplyVertexAlphaShadowInterp = + " fragColor *= (1.0 - cos(alpha)) / 2.0;\n"; const char* gFS_Main_FetchTexture[2] = { // Don't modulate @@ -473,8 +471,8 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description if (description.hasTexture || description.hasExternalTexture) { shader.append(gVS_Header_Attributes_TexCoords); } - if (description.isAA) { - shader.append(gVS_Header_Attributes_AAVertexShapeParameters); + if (description.hasVertexAlpha) { + shader.append(gVS_Header_Attributes_VertexAlphaParameters); } if (description.hasColors) { shader.append(gVS_Header_Attributes_Colors); @@ -497,8 +495,8 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description if (description.hasTexture || description.hasExternalTexture) { shader.append(gVS_Header_Varyings_HasTexture); } - if (description.isAA) { - shader.append(gVS_Header_Varyings_IsAAVertexShape); + if (description.hasVertexAlpha) { + shader.append(gVS_Header_Varyings_HasVertexAlpha); } if (description.hasColors) { shader.append(gVS_Header_Varyings_HasColors); @@ -520,12 +518,8 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description } else if (description.hasTexture || description.hasExternalTexture) { shader.append(gVS_Main_OutTexCoords); } - if (description.isAA) { - if (description.isShadowAA) { - shader.append(gVS_Main_ShadowAAVertexShape); - } else { - shader.append(gVS_Main_AAVertexShape); - } + if (description.hasVertexAlpha) { + shader.append(gVS_Main_VertexAlpha); } if (description.hasColors) { shader.append(gVS_Main_OutColors); @@ -575,8 +569,8 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti if (description.hasTexture || description.hasExternalTexture) { shader.append(gVS_Header_Varyings_HasTexture); } - if (description.isAA) { - shader.append(gVS_Header_Varyings_IsAAVertexShape); + if (description.hasVertexAlpha) { + shader.append(gVS_Header_Varyings_HasVertexAlpha); } if (description.hasColors) { shader.append(gVS_Header_Varyings_HasColors); @@ -617,7 +611,7 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti } // Optimization for common cases - if (!description.isAA + if (!description.hasVertexAlpha && !blendFramebuffer && !description.hasColors && description.colorOp == ProgramDescription::kColorNone @@ -759,11 +753,11 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti // Apply the color op if needed shader.append(gFS_Main_ApplyColorOp[description.colorOp]); - if (description.isAA) { - if (description.isShadowAA) { - shader.append(gFS_Main_AccountForShadowAAVertexShape); + if (description.hasVertexAlpha) { + if (description.useShadowAlphaInterp) { + shader.append(gFS_Main_ApplyVertexAlphaShadowInterp); } else { - shader.append(gFS_Main_AccountForAAVertexShape); + shader.append(gFS_Main_ApplyVertexAlphaLinearInterp); } } diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp index 8c3077b682be..d72653864d7b 100644 --- a/libs/hwui/SpotShadow.cpp +++ b/libs/hwui/SpotShadow.cpp @@ -754,9 +754,13 @@ void SpotShadow::generateTriangleStrip(bool isCasterOpaque, const Vector2* penum AlphaVertex* shadowVertices = shadowTriangleStrip.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT); + // NOTE: Shadow alpha values are transformed when stored in alphavertices, + // so that they can be consumed directly by gFS_Main_ApplyVertexAlphaShadowInterp + float transformedMaxAlpha = M_PI; + // Calculate the vertices (x, y, alpha) in the shadow area. AlphaVertex centroidXYA; - AlphaVertex::set(¢roidXYA, centroid.x, centroid.y, 1.0f); + AlphaVertex::set(¢roidXYA, centroid.x, centroid.y, transformedMaxAlpha); for (int rayIndex = 0; rayIndex < rays; rayIndex++) { float dx = cosf(step * rayIndex); float dy = sinf(step * rayIndex); @@ -770,14 +774,16 @@ void SpotShadow::generateTriangleStrip(bool isCasterOpaque, const Vector2* penum // umbra ring float umbraDistance = umbraDistPerRay[rayIndex]; AlphaVertex::set(&shadowVertices[rays + rayIndex], - dx * umbraDistance + centroid.x, dy * umbraDistance + centroid.y, 1.0f); + dx * umbraDistance + centroid.x, + dy * umbraDistance + centroid.y, + transformedMaxAlpha); // occluded umbra ring if (hasOccludedUmbraArea) { float occludedUmbraDistance = occludedUmbraDistPerRay[rayIndex]; AlphaVertex::set(&shadowVertices[2 * rays + rayIndex], dx * occludedUmbraDistance + centroid.x, - dy * occludedUmbraDistance + centroid.y, 1.0f); + dy * occludedUmbraDistance + centroid.y, transformedMaxAlpha); } else { // Put all vertices of the occluded umbra ring at the centroid. shadowVertices[2 * rays + rayIndex] = centroidXYA; diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index bd50142e2533..6a76a71c38f8 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1672,24 +1672,6 @@ public class AudioManager { /** * @hide - * Checks whether any local or remote media playback is active. - * Local playback refers to playback for instance on the device's speakers or wired headphones. - * Remote playback refers to playback for instance on a wireless display mirroring the - * devices's, or on a device using a Cast-like protocol. - * @return true if media playback, from which the device is aware, is active. - */ - public boolean isLocalOrRemoteMusicActive() { - IAudioService service = getService(); - try { - return service.isLocalOrRemoteMusicActive(); - } catch (RemoteException e) { - Log.e(TAG, "Dead object in isLocalOrRemoteMusicActive()", e); - return false; - } - } - - /** - * @hide * Checks whether the current audio focus is exclusive. * @return true if the top of the audio focus stack requested focus * with {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} diff --git a/telecomm/java/android/telecomm/SimpleResponse.java b/media/java/android/media/AudioManagerInternal.java index 8e84adb809c1..6f1bdef87303 100644 --- a/telecomm/java/android/telecomm/SimpleResponse.java +++ b/media/java/android/media/AudioManagerInternal.java @@ -13,26 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package android.media; -package android.telecomm; +import com.android.server.LocalServices; /** - * Used to inform a client of asynchronously returned results. + * Class for system services to access extra AudioManager functionality. The + * AudioService is responsible for registering an implementation with + * {@link LocalServices}. + * + * @hide */ -public interface SimpleResponse<IN, OUT> { +public abstract class AudioManagerInternal { - /** - * Provide a set of results. - * - * @param request The original request. - * @param result The results. - */ - void onResult(IN request, OUT result); + public abstract void adjustStreamVolumeForUid(int streamType, int direction, int flags, + String callingPackage, int uid); - /** - * Indicates the inability to provide results. - * - * @param request The original request. - */ - void onError(IN request); + public abstract void setStreamVolumeForUid(int streamType, int direction, int flags, + String callingPackage, int uid); } diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index c6489a63c3fd..0af24576012b 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -79,6 +79,7 @@ import android.view.WindowManager; import com.android.internal.telephony.ITelephony; import com.android.internal.util.XmlUtils; +import com.android.server.LocalServices; import org.xmlpull.v1.XmlPullParserException; @@ -481,11 +482,6 @@ public class AudioService extends IAudioService.Stub { final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers = new RemoteCallbackList<IAudioRoutesObserver>(); - /** - * A fake stream type to match the notion of remote media playback - */ - public final static int STREAM_REMOTE_MUSIC = -200; - // Devices for which the volume is fixed and VolumePanel slider should be disabled int mFixedVolumeDevices = AudioSystem.DEVICE_OUT_HDMI | AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET | @@ -635,6 +631,7 @@ public class AudioService extends IAudioService.Stub { mMasterVolumeRamp = context.getResources().getIntArray( com.android.internal.R.array.config_masterVolumeRamp); + LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); } public void systemReady() { @@ -896,27 +893,6 @@ public class AudioService extends IAudioService.Stub { /////////////////////////////////////////////////////////////////////////// // IPC methods /////////////////////////////////////////////////////////////////////////// - /** @see AudioManager#isLocalOrRemoteMusicActive() */ - public boolean isLocalOrRemoteMusicActive() { - if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) { - // local / wired / BT playback active - if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): local"); - return true; - } - if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) { - // remote "cast-like" playback active - if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): has PLAYBACK_TYPE_REMOTE"); - return true; - } - if (AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0)) { - // remote submix playback active - if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): remote submix"); - return true; - } - if (DEBUG_VOL) Log.d(TAG, "isLocalOrRemoteMusicActive(): no"); - return false; - } - /** @see AudioManager#adjustVolume(int, int) */ public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage) { @@ -930,9 +906,8 @@ public class AudioService extends IAudioService.Stub { } final int resolvedStream = mStreamVolumeAlias[streamType]; - // Play sounds on STREAM_RING and STREAM_REMOTE_MUSIC only. - if ((streamType != STREAM_REMOTE_MUSIC) && - (flags & AudioManager.FLAG_PLAY_SOUND) != 0 && + // Play sounds on STREAM_RING only. + if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && resolvedStream != AudioSystem.STREAM_RING) { flags &= ~AudioManager.FLAG_PLAY_SOUND; } @@ -945,17 +920,17 @@ public class AudioService extends IAudioService.Stub { if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment"); } - if (streamType == STREAM_REMOTE_MUSIC) { - // TODO bounce it to MediaSessionService to find an appropriate - // session - } else { - adjustStreamVolume(streamType, direction, flags, callingPackage); - } + adjustStreamVolume(streamType, direction, flags, callingPackage); } /** @see AudioManager#adjustStreamVolume(int, int, int) */ public void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage) { + adjustStreamVolume(streamType, direction, flags, callingPackage, Binder.getCallingUid()); + } + + private void adjustStreamVolume(int streamType, int direction, int flags, + String callingPackage, int uid) { if (mUseFixedVolume) { return; } @@ -984,8 +959,8 @@ public class AudioService extends IAudioService.Stub { return; } - if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], Binder.getCallingUid(), - callingPackage) != AppOpsManager.MODE_ALLOWED) { + if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage) + != AppOpsManager.MODE_ALLOWED) { return; } @@ -1161,6 +1136,11 @@ public class AudioService extends IAudioService.Stub { /** @see AudioManager#setStreamVolume(int, int, int) */ public void setStreamVolume(int streamType, int index, int flags, String callingPackage) { + setStreamVolume(streamType, index, flags, callingPackage, Binder.getCallingUid()); + } + + private void setStreamVolume(int streamType, int index, int flags, String callingPackage, + int uid) { if (mUseFixedVolume) { return; } @@ -1179,8 +1159,8 @@ public class AudioService extends IAudioService.Stub { return; } - if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], Binder.getCallingUid(), - callingPackage) != AppOpsManager.MODE_ALLOWED) { + if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage) + != AppOpsManager.MODE_ALLOWED) { return; } @@ -1885,10 +1865,6 @@ public class AudioService extends IAudioService.Stub { } } int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); - if (streamType == STREAM_REMOTE_MUSIC) { - // here handle remote media playback the same way as local playback - streamType = AudioManager.STREAM_MUSIC; - } int device = getDeviceForStream(streamType); int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device); setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true); @@ -2973,12 +2949,6 @@ public class AudioService extends IAudioService.Stub { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active"); return AudioSystem.STREAM_MUSIC; - } else - if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) - { - if (DEBUG_VOL) - Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); - return STREAM_REMOTE_MUSIC; } else { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING b/c default"); @@ -2992,19 +2962,8 @@ public class AudioService extends IAudioService.Stub { break; case PLATFORM_TELEVISION: if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { - if (isAfMusicActiveRecently(DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS)) { - if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: forcing STREAM_MUSIC"); - return AudioSystem.STREAM_MUSIC; - } else if (mMediaFocusControl.checkUpdateRemoteStateIfActive( - AudioSystem.STREAM_MUSIC)) { - if (DEBUG_VOL) - Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); - return STREAM_REMOTE_MUSIC; - } else { - if (DEBUG_VOL) Log.v(TAG, - "getActiveStreamType: using STREAM_MUSIC as default"); + // TV always defaults to STREAM_MUSIC return AudioSystem.STREAM_MUSIC; - } } break; default: @@ -3027,12 +2986,6 @@ public class AudioService extends IAudioService.Stub { if (isAfMusicActiveRecently(DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: forcing STREAM_MUSIC"); return AudioSystem.STREAM_MUSIC; - } else - if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) - { - if (DEBUG_VOL) - Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC"); - return STREAM_REMOTE_MUSIC; } else { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: using STREAM_NOTIFICATION as default"); @@ -4618,8 +4571,8 @@ public class AudioService extends IAudioService.Stub { // in SettingsObserver. Here we should log that a USB device is connected // and disconnected with its address (card , device) and force the // connection or disconnection when the setting changes. - int isDisabled = Settings.System.getInt(mContentResolver, - Settings.System.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 0); + int isDisabled = Settings.Secure.getInt(mContentResolver, + Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 0); if (isDisabled != 0) { return; } @@ -5347,6 +5300,24 @@ public class AudioService extends IAudioService.Stub { } } + /** + * Interface for system components to get some extra functionality through + * LocalServices. + */ + final class AudioServiceInternal extends AudioManagerInternal { + @Override + public void adjustStreamVolumeForUid(int streamType, int direction, int flags, + String callingPackage, int uid) { + adjustStreamVolume(streamType, direction, flags, callingPackage, uid); + } + + @Override + public void setStreamVolumeForUid(int streamType, int direction, int flags, + String callingPackage, int uid) { + setStreamVolume(streamType, direction, flags, callingPackage, uid); + } + } + //========================================================================================== // Audio policy management //========================================================================================== diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 731866069f69..6477055fa305 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -37,8 +37,6 @@ import android.view.KeyEvent; */ interface IAudioService { - boolean isLocalOrRemoteMusicActive(); - void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage); diff --git a/media/java/android/media/IRingtonePlayer.aidl b/media/java/android/media/IRingtonePlayer.aidl index 0872f1dcc86c..7c011e6206e6 100644 --- a/media/java/android/media/IRingtonePlayer.aidl +++ b/media/java/android/media/IRingtonePlayer.aidl @@ -16,6 +16,7 @@ package android.media; +import android.media.AudioAttributes; import android.net.Uri; import android.os.UserHandle; @@ -24,11 +25,11 @@ import android.os.UserHandle; */ interface IRingtonePlayer { /** Used for Ringtone.java playback */ - void play(IBinder token, in Uri uri, int streamType); + void play(IBinder token, in Uri uri, in AudioAttributes aa); void stop(IBinder token); boolean isPlaying(IBinder token); /** Used for Notification sound playback. */ - void playAsync(in Uri uri, in UserHandle user, boolean looping, int streamType); + void playAsync(in Uri uri, in UserHandle user, boolean looping, in AudioAttributes aa); void stopAsync(); } diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java index 0aaaf46bebd9..adc839167df8 100644 --- a/media/java/android/media/RemoteController.java +++ b/media/java/android/media/RemoteController.java @@ -793,7 +793,7 @@ import java.util.List; final ComponentName listenerComponent = new ComponentName(mContext, mOnClientUpdateListener.getClass()); mSessionManager.addActiveSessionsListener(mSessionListener, listenerComponent, - UserHandle.myUserId()); + UserHandle.myUserId(), null); mSessionListener.onActiveSessionsChanged(mSessionManager .getActiveSessions(listenerComponent)); if (DEBUG) { diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java index 2616b6cca437..a22110401b07 100644 --- a/media/java/android/media/Ringtone.java +++ b/media/java/android/media/Ringtone.java @@ -60,7 +60,10 @@ public class Ringtone { private Uri mUri; private String mTitle; - private int mStreamType = AudioManager.STREAM_RING; + private AudioAttributes mAudioAttributes = new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .build(); /** {@hide} */ public Ringtone(Context context, boolean allowRemote) { @@ -75,22 +78,40 @@ public class Ringtone { * Sets the stream type where this ringtone will be played. * * @param streamType The stream, see {@link AudioManager}. + * @deprecated use {@link #setAudioAttributes(AudioAttributes)} */ + @Deprecated public void setStreamType(int streamType) { - mStreamType = streamType; - - // The stream type has to be set before the media player is prepared. - // Re-initialize it. - setUri(mUri); + setAudioAttributes(new AudioAttributes.Builder() + .setInternalLegacyStreamType(streamType) + .build()); } /** * Gets the stream type where this ringtone will be played. * * @return The stream type, see {@link AudioManager}. + * @deprecated use of stream types is deprecated, see + * {@link #setAudioAttributes(AudioAttributes)} */ + @Deprecated public int getStreamType() { - return mStreamType; + return AudioAttributes.toLegacyStreamType(mAudioAttributes); + } + + /** + * Sets the {@link AudioAttributes} for this ringtone. + * @param attributes the non-null attributes characterizing this ringtone. + */ + public void setAudioAttributes(AudioAttributes attributes) + throws IllegalArgumentException { + if (attributes == null) { + throw new IllegalArgumentException("Invalid null AudioAttributes for Ringtone"); + } + mAudioAttributes = attributes; + // The audio attributes have to be set before the media player is prepared. + // Re-initialize it. + setUri(mUri); } /** @@ -178,7 +199,7 @@ public class Ringtone { mLocalPlayer = new MediaPlayer(); try { mLocalPlayer.setDataSource(mContext, mUri); - mLocalPlayer.setAudioStreamType(mStreamType); + mLocalPlayer.setAudioAttributes(mAudioAttributes); mLocalPlayer.prepare(); } catch (SecurityException e) { @@ -214,13 +235,14 @@ public class Ringtone { if (mLocalPlayer != null) { // do not play ringtones if stream volume is 0 // (typically because ringer mode is silent). - if (mAudioManager.getStreamVolume(mStreamType) != 0) { + if (mAudioManager.getStreamVolume( + AudioAttributes.toLegacyStreamType(mAudioAttributes)) != 0) { mLocalPlayer.start(); } } else if (mAllowRemote && (mRemotePlayer != null)) { final Uri canonicalUri = mUri.getCanonicalUri(); try { - mRemotePlayer.play(mRemoteToken, canonicalUri, mStreamType); + mRemotePlayer.play(mRemoteToken, canonicalUri, mAudioAttributes); } catch (RemoteException e) { if (!playFallbackRingtone()) { Log.w(TAG, "Problem playing ringtone: " + e); @@ -278,7 +300,8 @@ public class Ringtone { } private boolean playFallbackRingtone() { - if (mAudioManager.getStreamVolume(mStreamType) != 0) { + if (mAudioManager.getStreamVolume(AudioAttributes.toLegacyStreamType(mAudioAttributes)) + != 0) { int ringtoneType = RingtoneManager.getDefaultType(mUri); if (ringtoneType == -1 || RingtoneManager.getActualDefaultRingtoneUri(mContext, ringtoneType) != null) { @@ -295,7 +318,7 @@ public class Ringtone { afd.getStartOffset(), afd.getDeclaredLength()); } - mLocalPlayer.setAudioStreamType(mStreamType); + mLocalPlayer.setAudioAttributes(mAudioAttributes); mLocalPlayer.prepare(); mLocalPlayer.start(); afd.close(); diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl index 3518458fe706..5764bd15cc10 100644 --- a/media/java/android/media/session/ISessionController.aidl +++ b/media/java/android/media/session/ISessionController.aidl @@ -48,8 +48,8 @@ interface ISessionController { PendingIntent getLaunchPendingIntent(); long getFlags(); ParcelableVolumeInfo getVolumeAttributes(); - void adjustVolume(int direction, int flags); - void setVolumeTo(int value, int flags); + void adjustVolume(int direction, int flags, String packageName); + void setVolumeTo(int value, int flags, String packageName); IMediaRouterDelegate createMediaRouterDelegate(IMediaRouterStateCallback callback); diff --git a/media/java/android/media/session/ISessionControllerCallback.aidl b/media/java/android/media/session/ISessionControllerCallback.aidl index 78cd699b9799..cf3176706d7e 100644 --- a/media/java/android/media/session/ISessionControllerCallback.aidl +++ b/media/java/android/media/session/ISessionControllerCallback.aidl @@ -27,6 +27,7 @@ import android.os.Bundle; */ oneway interface ISessionControllerCallback { void onEvent(String event, in Bundle extras); + void onSessionDestroyed(); // These callbacks are for the TransportController void onPlaybackStateChanged(in PlaybackState state); diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java index f6e189aade1e..63c85f885215 100644 --- a/media/java/android/media/session/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -63,6 +63,7 @@ public final class MediaController { private static final int MSG_UPDATE_QUEUE = 5; private static final int MSG_UPDATE_QUEUE_TITLE = 6; private static final int MSG_UPDATE_EXTRAS = 7; + private static final int MSG_DESTROYED = 8; private final ISessionController mSessionBinder; @@ -310,7 +311,7 @@ public final class MediaController { */ public void setVolumeTo(int value, int flags) { try { - mSessionBinder.setVolumeTo(value, flags); + mSessionBinder.setVolumeTo(value, flags, mContext.getPackageName()); } catch (RemoteException e) { Log.wtf(TAG, "Error calling setVolumeTo.", e); } @@ -331,7 +332,7 @@ public final class MediaController { */ public void adjustVolume(int direction, int flags) { try { - mSessionBinder.adjustVolume(direction, flags); + mSessionBinder.adjustVolume(direction, flags, mContext.getPackageName()); } catch (RemoteException e) { Log.wtf(TAG, "Error calling adjustVolumeBy.", e); } @@ -508,6 +509,13 @@ public final class MediaController { */ public static abstract class Callback { /** + * Override to handle the session being destroyed. The session is no + * longer valid after this call and calls to it will be ignored. + */ + public void onSessionDestroyed() { + } + + /** * Override to handle custom events sent by the session owner without a * specified interface. Controllers should only handle these for * sessions they own. @@ -863,6 +871,14 @@ public final class MediaController { } @Override + public void onSessionDestroyed() { + MediaController controller = mController.get(); + if (controller != null) { + controller.postMessage(MSG_DESTROYED, null, null); + } + } + + @Override public void onEvent(String event, Bundle extras) { MediaController controller = mController.get(); if (controller != null) { @@ -955,6 +971,9 @@ public final class MediaController { case MSG_UPDATE_VOLUME: mCallback.onVolumeInfoChanged((VolumeInfo) msg.obj); break; + case MSG_DESTROYED: + mCallback.onSessionDestroyed(); + break; } } diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index 84983b91a36a..c2fb5a36193e 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -23,6 +23,7 @@ import android.content.Context; import android.media.AudioManager; import android.media.IRemoteVolumeController; import android.media.session.ISessionManager; +import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; @@ -37,11 +38,11 @@ import java.util.List; /** * Provides support for interacting with {@link MediaSession media sessions} - * that applications have published to express their ongoing media playback state. + * that applications have published to express their ongoing media playback + * state. * <p> * Use <code>Context.getSystemService(Context.MEDIA_SESSION_SERVICE)</code> to * get an instance of this class. - * <p> * * @see MediaSession * @see MediaController @@ -133,15 +134,17 @@ public final class MediaSessionManager { * the calling app. You may also retrieve this list if your app is an * enabled notification listener using the * {@link NotificationListenerService} APIs, in which case you must pass the - * {@link ComponentName} of your enabled listener. + * {@link ComponentName} of your enabled listener. Updates will be posted to + * the thread that registered the listener. * * @param sessionListener The listener to add. * @param notificationListener The enabled notification listener component. * May be null. */ - public void addActiveSessionsListener(SessionListener sessionListener, - ComponentName notificationListener) { - addActiveSessionsListener(sessionListener, notificationListener, UserHandle.myUserId()); + public void addActiveSessionsListener(@NonNull SessionListener sessionListener, + @Nullable ComponentName notificationListener) { + addActiveSessionsListener(sessionListener, notificationListener, UserHandle.myUserId(), + null); } /** @@ -157,13 +160,18 @@ public final class MediaSessionManager { * @param notificationListener The enabled notification listener component. * May be null. * @param userId The userId to listen for changes on. + * @param handler The handler to post updates on. * @hide */ public void addActiveSessionsListener(@NonNull SessionListener sessionListener, - @Nullable ComponentName notificationListener, int userId) { + @Nullable ComponentName notificationListener, int userId, @Nullable Handler handler) { if (sessionListener == null) { throw new IllegalArgumentException("listener may not be null"); } + if (handler == null) { + handler = new Handler(); + } + sessionListener.setHandler(handler); try { mService.addSessionsListener(sessionListener.mStub, notificationListener, userId); } catch (RemoteException e) { @@ -253,6 +261,7 @@ public final class MediaSessionManager { */ public static abstract class SessionListener { private final Context mContext; + private Handler mHandler; public SessionListener(Context context) { mContext = context; @@ -269,15 +278,27 @@ public final class MediaSessionManager { public abstract void onActiveSessionsChanged( @Nullable List<MediaController> controllers); + private final void setHandler(Handler handler) { + mHandler = handler; + } + private final IActiveSessionsListener.Stub mStub = new IActiveSessionsListener.Stub() { @Override - public void onActiveSessionsChanged(List<MediaSession.Token> tokens) { - ArrayList<MediaController> controllers = new ArrayList<MediaController>(); - int size = tokens.size(); - for (int i = 0; i < size; i++) { - controllers.add(new MediaController(mContext, tokens.get(i))); + public void onActiveSessionsChanged(final List<MediaSession.Token> tokens) { + if (mHandler != null) { + mHandler.post(new Runnable() { + @Override + public void run() { + ArrayList<MediaController> controllers + = new ArrayList<MediaController>(); + int size = tokens.size(); + for (int i = 0; i < size; i++) { + controllers.add(new MediaController(mContext, tokens.get(i))); + } + SessionListener.this.onActiveSessionsChanged(controllers); + } + }); } - SessionListener.this.onActiveSessionsChanged(controllers); } }; } diff --git a/media/java/android/media/tv/TvContentRating.java b/media/java/android/media/tv/TvContentRating.java index 25252ed7b61d..405ef22b786e 100644 --- a/media/java/android/media/tv/TvContentRating.java +++ b/media/java/android/media/tv/TvContentRating.java @@ -34,42 +34,87 @@ import java.util.Objects; * strings, or a TV input service defined strings. * TV input service defined strings are in an xml file defined in <code><{@link * android.R.styleable#TvInputService tv-input}></code> with the {@link - * android.R.attr#contentRatingSystemXml contentRatingSystemXml} attribute by the TV input service. + * android.R.attr#tvContentRatingDescription tvContentRatingDescription} attribute by the TV input + * service. * - * <h3> Content Rating System XML format </h3> - * The XML file for publishing content rating system should follow the DTD bellow: + * <h3> Example: Rating system definition for the TV Parental Guidelines</h3> + * The following XML example shows how the TV Parental Guidelines in United States can be defined: * <p><pre class="prettyprint"> - * <?xml version="1.0" encoding="UTF-8"?> - * <!DOCTYPE rating-systems [ - * <!ELEMENT rating-system-definitions (rating-system-definition+)> - * <!ATTLIST rating-system-definitions - * version CDATA #REQUIRED> - * <!ELEMENT rating-system-definition ( - * (sub-rating-definition*, rating-definition, sub-rating-definition*)+, order*)> - * <!ATTLIST rating-system-definition - * id ID #REQUIRED - * displayName CDATA #IMPLIED - * description CDATA #IMPLIED - * country CDATA #IMPLIED> - * <!ELEMENT sub-rating-definition EMPTY> - * <!ATTLIST sub-rating-definition - * id ID #REQUIRED - * displayName CDATA #IMPLIED - * icon CDATA #IMPLIED - * description CDATA #IMPLIED> - * <!ELEMENT rating-definition (sub-rating*))> - * <!ATTLIST rating-definition - * id ID #REQUIRED - * displayName CDATA #IMPLIED - * icon CDATA #IMPLIED - * description CDATA #IMPLIED> - * <!ELEMENT sub-rating EMPTY> - * <!ATTLIST sub-rating id IDREF #REQUIRED> - * <!ELEMENT order (rating, rating+)> - * <!ELEMENT rating EMPTY> - * <!ATTLIST rating id IDREF #REQUIRED> - * ]> - * </pre></p> + * {@literal + * <?xml version="1.0" encoding="UTF-8"?> + * <rating-system-definitions version="1.0"> + * <rating-system-definition id="US_TV" + * displayName="US-TV" + * description="The TV Parental Guidelines" + * country="US"> + * <sub-rating-definition id="US_TV_D" + * displayName="D" + * description="Suggestive dialogue (Usually means talks about sex)" /> + * <sub-rating-definition id="US_TV_L" + * displayName="L" + * description="Coarse language" /> + * <sub-rating-definition id="US_TV_S" + * displayName="S" + * description="Sexual content" /> + * <sub-rating-definition id="US_TV_V" + * displayName="V" + * description="Violence" /> + * <sub-rating-definition id="US_TV_FV" + * displayName="FV" + * description="Fantasy violence (Children\'s programming only)" /> + * + * <rating-definition id="US_TV_Y" + * displayName="TV-Y" + * description="This program is designed to be appropriate for all children" + * ageHint="0" /> + * <rating-definition id="US_TV_Y7" + * displayName="TV-Y7" + * description="This program is designed for children age 7 and above" + * ageHint="7"> + * <sub-rating id="US_TV_FV" /> + * </rating-definition> + * <rating-definition id="US_TV_G" + * displayName="TV-G" + * description="Most parents would find this program suitable for all ages" + * ageHint="0" /> + * <rating-definition id="US_TV_PG" + * displayName="TV-PG" + * description="This program contains material that parents may find unsuitable for younger children" + * ageHint="14"> + * <sub-rating id="US_TV_D" /> + * <sub-rating id="US_TV_L" /> + * <sub-rating id="US_TV_S" /> + * <sub-rating id="US_TV_V" /> + * </rating-definition> + * <rating-definition id="US_TV_14" + * displayName="TV-14" + * description="This program contains some material that many parents would find unsuitable for children under 14 years of age" + * ageHint="14"> + * <sub-rating id="US_TV_D" /> + * <sub-rating id="US_TV_L" /> + * <sub-rating id="US_TV_S" /> + * <sub-rating id="US_TV_V" /> + * </rating-definition> + * <rating-definition id="US_TV_MA" + * displayName="TV-MA" + * description="This program is specifically designed to be viewed by adults and therefore may be unsuitable for children under 17" + * ageHint="17"> + * <sub-rating id="US_TV_L" /> + * <sub-rating id="US_TV_S" /> + * <sub-rating id="US_TV_V" /> + * </rating-definition> + * <order> + * <rating id="US_TV_Y" /> + * <rating id="US_TV_Y7" /> + * </order> + * <order> + * <rating id="US_TV_G" /> + * <rating id="US_TV_PG" /> + * <rating id="US_TV_14" /> + * <rating id="US_TV_MA" /> + * </order> + * </rating-system-definition> + * </rating-system-definitions>}</pre></p> * * <h3>System defined rating strings</h3> * @@ -86,9 +131,9 @@ import java.util.Objects; * </table> * * <u>System defined string for {@code ratingSystem}</u> - * <table border="0" cellspacing="0" cellpadding="0"> + * <table border="1" cellspacing="0" cellpadding="0"> * <tr> - * <td width=10%>String value</td> + * <td width="10%">String value</td> * <td>Comments</td> * </tr> * <tr> @@ -101,111 +146,111 @@ import java.util.Objects; * </tr> * <tr> * <td>AR_TV</td> - * <td>TV content rating system for Argentina TV</td> + * <td>TV content rating system for Argentina</td> * </tr> * <tr> * <td>AU_TV</td> - * <td>TV content rating system for Australia TV</td> + * <td>TV content rating system for Australia</td> * </tr> * <tr> * <td>BG_TV</td> - * <td>TV content rating system for Bulgaria TV</td> + * <td>TV content rating system for Bulgaria</td> * </tr> * <tr> * <td>BR_TV</td> - * <td>TV content rating system for Brazil TV</td> + * <td>TV content rating system for Brazil</td> * </tr> * <tr> * <td>CA_TV</td> - * <td>TV content rating system for Canada TV</td> + * <td>TV content rating system for Canada</td> * </tr> * <tr> * <td>CH_TV</td> - * <td>TV content rating system for Switzerland TV</td> + * <td>TV content rating system for Switzerland</td> * </tr> * <tr> * <td>CL_TV</td> - * <td>TV content rating system for Chile TV</td> + * <td>TV content rating system for Chile</td> * </tr> * <tr> * <td>DE_TV</td> - * <td>TV content rating system for Germany TV</td> + * <td>TV content rating system for Germany</td> * </tr> * <tr> * <td>DK_TV</td> - * <td>TV content rating system for Denmark TV</td> + * <td>TV content rating system for Denmark</td> * </tr> * <tr> * <td>ES_TV</td> - * <td>TV content rating system for Spain TV</td> + * <td>TV content rating system for Spain</td> * </tr> * <tr> * <td>FI_TV</td> - * <td>TV content rating system for Finland TV</td> + * <td>TV content rating system for Finland</td> * </tr> * <tr> * <td>FR_TV</td> - * <td>TV content rating system for France TV</td> + * <td>TV content rating system for France</td> * </tr> * <tr> * <td>GR_TV</td> - * <td>TV content rating system for Greece TV</td> + * <td>TV content rating system for Greece</td> * </tr> * <tr> * <td>HK_TV</td> - * <td>TV content rating system for Hong Kong TV</td> + * <td>TV content rating system for Hong Kong</td> * </tr> * <tr> * <td>HU_TV</td> - * <td>TV content rating system for Hungary TV</td> + * <td>TV content rating system for Hungary</td> * </tr> * <tr> * <td>ID_TV</td> - * <td>TV content rating system for Indonesia TV</td> + * <td>TV content rating system for Indonesia</td> * </tr> * <tr> * <td>IE_TV</td> - * <td>TV content rating system for Ireland TV</td> + * <td>TV content rating system for Ireland</td> * </tr> * <tr> * <td>IL_TV</td> - * <td>TV content rating system for Israel TV</td> + * <td>TV content rating system for Israel</td> * </tr> * <tr> * <td>IN_TV</td> - * <td>TV content rating system for India TV</td> + * <td>TV content rating system for India</td> * </tr> * <tr> * <td>IS_TV</td> - * <td>TV content rating system for Iceland TV</td> + * <td>TV content rating system for Iceland</td> * </tr> * <tr> * <td>KR_TV</td> - * <td>TV content rating system for South Korea TV</td> + * <td>TV content rating system for South Korea</td> * </tr> * <tr> * <td>MV_TV</td> - * <td>TV content rating system for Maldives TV</td> + * <td>TV content rating system for Maldives</td> * </tr> * <tr> * <td>MX_TV</td> - * <td>TV content rating system for Mexico TV</td> + * <td>TV content rating system for Mexico</td> * </tr> * <tr> * <td>MY_TV</td> - * <td>TV content rating system for Malaysia TV</td> + * <td>TV content rating system for Malaysia</td> * </tr> * <tr> * <td>NL_TV</td> - * <td>TV content rating system for Netherlands TV</td> + * <td>TV content rating system for Netherlands</td> * </tr> * <tr> * <td>NZ_FTV</td> - * <td>New Zealand\'s free-to-air TV content rating system</td> + * <td>TV content rating system for free-to-air channels in New Zealand</td> * </tr> * <tr> * <td>NZ_PTV</td> - * <td>New Zealand\'s pay TV content rating system</td> + * <td>TV content rating system for Pay TV channels in New Zealand</td> * </tr> * <tr> * <td>PE_TV</td> @@ -214,87 +259,89 @@ import java.util.Objects; * <tr> * <td>PE_ATV</td> * <td>TV content rating system for America Television in Peru that uses its own rating - * </td> + * system</td> * </tr> * <tr> * <td>PH_TV</td> - * <td>TV content rating system for Philippines TV</td> + * <td>TV content rating system for Philippines</td> * </tr> * <tr> * <td>PL_TV</td> - * <td>TV content rating system for Poland TV</td> + * <td>TV content rating system for Poland</td> * </tr> * <tr> * <td>PT_TV</td> - * <td>TV content rating system for Portugal TV</td> + * <td>TV content rating system for Portugal</td> * </tr> * <tr> * <td>RO_TV</td> - * <td>TV content rating system for Romania TV</td> + * <td>TV content rating system for Romania</td> * </tr> * <tr> * <td>RU_TV</td> - * <td>TV content rating system for Russia TV</td> + * <td>TV content rating system for Russia</td> * </tr> * <tr> * <td>RS_TV</td> - * <td>TV content rating system for Serbia TV</td> + * <td>TV content rating system for Serbia</td> * </tr> * <tr> * <td>SG_FTV</td> - * <td>TV content rating system for Singapore TV</td> + * <td>TV content rating system for Singapore</td> * </tr> * <tr> * <td>SG_PTV</td> - * <td>TV content rating system for Singapore TV</td> + * <td>TV content rating system for Singapore</td> * </tr> * <tr> * <td>SI_TV</td> - * <td>TV content rating system for Slovenia TV</td> + * <td>TV content rating system for Slovenia</td> * </tr> * <tr> * <td>TH_TV</td> - * <td>TV content rating system for Thailand TV</td> + * <td>TV content rating system for Thailand</td> * </tr> * <tr> * <td>TR_TV</td> - * <td>TV content rating system for Turkey TV</td> + * <td>TV content rating system for Turkey</td> * </tr> * <tr> * <td>TW_TV</td> - * <td>TV content rating system for Taiwan TV</td> + * <td>TV content rating system for Taiwan</td> * </tr> * <tr> * <td>UA_TV</td> - * <td>TV content rating system for Ukraine TV</td> + * <td>TV content rating system for Ukraine</td> * </tr> * <tr> - * <td>US_TVPG</td> - * <td>The TV Parental Guidelines</td> + * <td>US_TV</td> + * <td>TV content rating system for United States</td> * </tr> * <tr> * <td>VE_TV</td> - * <td>TV content rating system for Venezuela TV</td> + * <td>TV content rating system for Venezuela</td> * </tr> * <tr> * <td>ZA_TV</td> - * <td>TV content rating system for South Africa TV</td> + * <td>TV content rating system for South Africa</td> * </tr> * </table> * * <u>System defined string for {@code rating}</u> - * <table border="0" cellspacing="0" cellpadding="0"> + * <table border="1" cellspacing="0" cellpadding="0"> * <tr> - * <td width=10%>String value</td> + * <td width="10%">RatingSystem code</td> + * <td width="10%">Rating string value</td> * <td>Comments</td> * </tr> * <tr> + * <td valign="top" rowspan="6">AM_TV_RS</td> * <td>AM_TV_RS_Y</td> - * <td>Suitable for ages 2–11</td> + * <td>Suitable for ages 2-11</td> * </tr> * <tr> * <td>AM_TV_RS_Y7</td> - * <td>Suitable for ages 7–16</td> + * <td>Suitable for ages 7-16</td> * </tr> * <tr> * <td>AM_TV_RS_GA</td> @@ -313,6 +360,7 @@ import java.util.Objects; * <td>Suitable only for adults ages 18 and up</td> * </tr> * <tr> + * <td valign="top" rowspan="6">AM_TV_AS</td> * <td>AM_TV_AS_EC</td> * <td>Suitable for ages 2 and up</td> * </tr> @@ -337,26 +385,28 @@ import java.util.Objects; * <td>Suitable for ages 17 and up</td> * </tr> * <tr> + * <td valign="top" rowspan="4">AR_TV</td> * <td>AR_TV_ALL</td> * <td>Suitable for all audiences. Programs may contain mild violence, language and mature - * </td> + * situations</td> * </tr> * <tr> * <td>AR_TV_13</td> * <td>Suitable for ages 13 and up. Programs may contain mild to moderate language and mild - * and sexual references</td> + * violence and sexual references</td> * </tr> * <tr> * <td>AR_TV_16</td> * <td>Suitable for ages 16 and up. Programs may contain more intensive violence and coarse - * partial nudity and moderate sexual references</td> + * language, partial nudity and moderate sexual references</td> * </tr> * <tr> * <td>AR_TV_18</td> * <td>Suitable for mature audiences only. Programs contain strong violence, coarse language - * explicit sexual references</td> + * and explicit sexual references</td> * </tr> * <tr> + * <td valign="top" rowspan="7">AU_TV</td> * <td>AU_TV_CTC</td> * <td>This has advertising approval, but is not yet classified</td> * </tr> @@ -367,17 +417,17 @@ import java.util.Objects; * <tr> * <td>AU_TV_PG</td> * <td>The content is mild in impact, but it may contain content that children find - * or upsetting and may require the guidance or parents and guardians</td> + * confusing or upsetting and may require the guidance or parents and guardians</td> * </tr> * <tr> * <td>AU_TV_M</td> * <td>The content is moderate in impact, and it is recommended for teenagers aged 15 years - * over</td> + * and over</td> * </tr> * <tr> * <td>AU_TV_MA15</td> * <td>The content is strong in impact, and it is legally restricted to persons 15 years and - * </td> + * over</td> * </tr> * <tr> * <td>AU_TV_R18</td> @@ -386,37 +436,39 @@ import java.util.Objects; * <tr> * <td>AU_TV_X18</td> * <td>The content is restricted to adults. This classification is a special and legally - * category which contains only sexually explicit content</td> + * restricted category which contains only sexually explicit content</td> * </tr> * <tr> + * <td valign="top" rowspan="5">BG_TV</td> * <td>BG_TV_A</td> * <td>Recommended to children. When the film confirms the ideals of humanism or popularizes - * national and world cultures or contributes to upbringing children</td> + * the national and world cultures or contributes to upbringing children</td> * </tr> * <tr> * <td>BG_TV_B</td> * <td>No restrictive recommendations from the Committee. When the film is in no way - * to the universal rules of morality in this country, has no restrictive recommendations - * the Committee and does not fall in rating A</td> + * contrary to the universal rules of morality in this country, has no restrictive + * recommendations from the Committee and does not fall in rating A</td> * </tr> * <tr> * <td>BG_TV_C</td> * <td>No persons under the age of 12 are admitted unless accompanied by an adult. When the - * contains certain erotic scenes or scenes with drinking, taking drugs or stimulants or a - * scenes of violence</td> + * film contains certain erotic scenes or scenes with drinking, taking drugs or stimulants + * or a few scenes of violence</td> * </tr> * <tr> * <td>BG_TV_D</td> * <td>No persons under the age of 16 are admitted. When the film contains quite a number of - * scenes or scenes with drinking, taking drugs or stimulants or a considerable number of - * showing violence</td> + * erotic scenes or scenes with drinking, taking drugs or stimulants or a considerable + * number of scenes showing violence</td> * </tr> * <tr> * <td>BG_TV_X</td> * <td>No persons under the age of 18 are admitted. When the film is naturalistically erotic - * shows violence in an ostentatious manner</td> + * or shows violence in an ostentatious manner</td> * </tr> * <tr> + * <td valign="top" rowspan="6">BR_TV</td> * <td>BR_TV_L</td> * <td>Content is suitable for all audiences</td> * </tr> @@ -441,52 +493,55 @@ import java.util.Objects; * <td>Content suitable for viewers over the age of 18</td> * </tr> * <tr> + * <td valign="top" rowspan="7">CA_TV</td> * <td>CA_TV_EXEMPT</td> * <td>Shows which are exempt from ratings (such as news and sports programming) will not - * an on-screen rating at all</td> + * display an on-screen rating at all</td> * </tr> * <tr> * <td>CA_TV_C</td> - * <td>Programming suitable for children ages of 2–7 years. No profanity or sexual content - * any level allowed. Contains little violence</td> + * <td>Programming suitable for children ages of 2-7 years. No profanity or sexual content + * of any level allowed. Contains little violence</td> * </tr> * <tr> * <td>CA_TV_C8</td> * <td>Suitable for children ages 8+. Low level violence and fantasy horror is allowed. No - * language is allowed, but occasional "socially offensive and discriminatory" language is - * if in the context of the story. No sexual content of any level allowed</td> + * foul language is allowed, but occasional "socially offensive and discriminatory" language + * is allowed if in the context of the story. No sexual content of any level allowed</td> * </tr> * <tr> * <td>CA_TV_G</td> * <td>Suitable for general audiences. Programming suitable for the entire family with mild - * and mild profanity and/or censored language</td> + * violence, and mild profanity and/or censored language</td> * </tr> * <tr> * <td>CA_TV_PG</td> * <td>Parental guidance. Moderate violence and moderate profanity is allowed, as is brief - * and sexual references if important to the context of the story</td> + * nudity and sexual references if important to the context of the story</td> * </tr> * <tr> * <td>CA_TV_14</td> * <td>Programming intended for viewers ages 14 and older. May contain strong violence and - * profanity, and depictions of sexual activity as long as they are within the context of a - * </td> + * strong profanity, and depictions of sexual activity as long as they are within the + * context of a story</td> * </tr> * <tr> * <td>CA_TV_18</td> * <td>Programming intended for viewers ages 18 and older. May contain explicit violence and - * activity</td> + * sexual activity</td> * </tr> * <tr> + * <td valign="top" rowspan="2">CH_TV</td> * <td>CH_TV_ALL</td> * <td>This program is suitable for all ages</td> * </tr> * <tr> * <td>CH_TV_RED</td> * <td>This program contains scenes that may hurt sensitive people, therefore the red symbol - * be displayed</td> + * will be displayed</td> * </tr> * <tr> + * <td valign="top" rowspan="7">CL_TV</td> * <td>CL_TV_I</td> * <td>Programs suitable for all children</td> * </tr> @@ -513,9 +568,10 @@ import java.util.Objects; * <tr> * <td>CL_TV_A</td> * <td>Programs suitable for adult audiences only (ages 18 or older), may contain coarse - * and sexual or explicit situations</td> + * language, and sexual or explicit situations</td> * </tr> * <tr> + * <td valign="top" rowspan="4">DE_TV</td> * <td>DE_TV_ALL</td> * <td>The program is suitable for all ages</td> * </tr> @@ -532,6 +588,7 @@ import java.util.Objects; * <td>The program is not suitable for viewers under the age of 18</td> * </tr> * <tr> + * <td valign="top" rowspan="4">DK_TV</td> * <td>DK_TV_G</td> * <td>programs suitable for all ages</td> * </tr> @@ -548,6 +605,7 @@ import java.util.Objects; * <td>programs containing explicit content and strictly for adults only</td> * </tr> * <tr> + * <td valign="top" rowspan="7">ES_TV</td> * <td>ES_TV_TP</td> * <td>Recommended for all ages</td> * </tr> @@ -576,6 +634,7 @@ import java.util.Objects; * <td>Recommended for people older than 18 years old</td> * </tr> * <tr> + * <td valign="top" rowspan="5">FI_TV</td> * <td>FI_TV_S</td> * <td>Allowed at all times</td> * </tr> @@ -596,6 +655,7 @@ import java.util.Objects; * <td>Not recommended for children under 18</td> * </tr> * <tr> + * <td valign="top" rowspan="5">FR_TV</td> * <td>FR_TV_ALL</td> * <td>Appropriate for all ages</td> * </tr> @@ -616,6 +676,7 @@ import java.util.Objects; * <td>Not recommended for persons under 18</td> * </tr> * <tr> + * <td valign="top" rowspan="5">GR_TV</td> * <td>GR_TV_all</td> * <td>Suitable for all ages</td> * </tr> @@ -634,9 +695,10 @@ import java.util.Objects; * <tr> * <td>GR_TV_18</td> * <td>Suitable only for adults profanity before midnight is punishable by fine, except when - * in the context of the program</td> + * used in the context of the program</td> * </tr> * <tr> + * <td valign="top" rowspan="3">HK_TV</td> * <td>HK_TV_G</td> * <td>For general audiences</td> * </tr> @@ -649,35 +711,37 @@ import java.util.Objects; * <td>Programs are recommended only for adult viewers above the age of 18</td> * </tr> * <tr> + * <td valign="top" rowspan="6">HU_TV</td> * <td>HU_TV_U</td> * <td>Programs can be viewed by any age</td> * </tr> * <tr> * <td>HU_TV_CF</td> * <td>Programs recommended for children. It is an optional rating, there is no obligation - * broadcasters to indicate it</td> + * for broadcasters to indicate it</td> * </tr> * <tr> * <td>HU_TV_6</td> * <td>Programs not recommended for children below the age of 6, may not contain any - * or sexual content</td> + * violence or sexual content</td> * </tr> * <tr> * <td>HU_TV_12</td> * <td>Programs not recommended for children below the age of 12, may contain light sexual - * or explicit language</td> + * content or explicit language</td> * </tr> * <tr> * <td>HU_TV_16</td> * <td>Programs not recommended for teens and children below the age of 16, may contain more - * violence and sexual content</td> + * intensive violence and sexual content</td> * </tr> * <tr> * <td>HU_TV_18</td> * <td>The program is recommended only for adult viewers (for ages 18 and up), may contain - * violence and explicit sexual content</td> + * explicit violence and explicit sexual content</td> * </tr> * <tr> + * <td valign="top" rowspan="8">ID_TV</td> * <td>ID_TV_P</td> * <td>Suitable for children from ages 2 through 11</td> * </tr> @@ -710,18 +774,19 @@ import java.util.Objects; * <td>Suitable for viewers over 18 and older only</td> * </tr> * <tr> + * <td valign="top" rowspan="5">IE_TV</td> * <td>IE_TV_GA</td> * <td>Suitable for all ages</td> * </tr> * <tr> * <td>IE_TV_Ch</td> * <td>Suitable for children ages 5 to 10, may contain comedic violence or action fantasy - * </td> + * violence</td> * </tr> * <tr> * <td>IE_TV_YA</td> * <td>Suitable for adolescent audiences, may contain thematic elements that would appeal to - * </td> + * teenagers</td> * </tr> * <tr> * <td>IE_TV_PS</td> @@ -730,17 +795,18 @@ import java.util.Objects; * <tr> * <td>IE_TV_MA</td> * <td>Most restrictive classification, allowing for heavy subject matter and coarse - * </td> + * language</td> * </tr> * <tr> + * <td valign="top" rowspan="5">IL_TV</td> * <td>IL_TV_G</td> * <td>General audience; anyone, regardless of age, can view the program, usually news and - * programming</td> + * children's programming</td> * </tr> * <tr> * <td>IL_TV_12</td> * <td>Suitable for teens and children ages 12 and over, no child under 12 are permitted to - * the program</td> + * view the program</td> * </tr> * <tr> * <td>IL_TV_15</td> @@ -755,13 +821,14 @@ import java.util.Objects; * <td>Exempt from classification</td> * </tr> * <tr> + * <td valign="top" rowspan="4">IN_TV</td> * <td>IN_TV_U</td> * <td>Unrestricted public exhibition</td> * </tr> * <tr> * <td>IN_TV_U/A</td> * <td>Unrestricted public exhibition, but with a caution regarding parental guidance to - * under 12 years of age</td> + * those under 12 years of age</td> * </tr> * <tr> * <td>IN_TV_A</td> @@ -773,6 +840,7 @@ import java.util.Objects; * </td> * </tr> * <tr> + * <td valign="top" rowspan="7">IS_TV</td> * <td>IS_TV_L</td> * <td>Programs suitable for all ages</td> * </tr> @@ -801,29 +869,31 @@ import java.util.Objects; * <td>Programs suitable for ages 18 and older</td> * </tr> * <tr> + * <td valign="top" rowspan="5">KR_TV</td> * <td>KR_TV_All</td> * <td>Appropriate for all ages</td> * </tr> * <tr> * <td>KR_TV_7</td> * <td>May contain material inappropriate for children younger than 7, and parental - * should be used</td> + * discretion should be used</td> * </tr> * <tr> * <td>KR_TV_12</td> * <td>May deemed inappropriate for those younger than 12, and parental discretion should be - * </td> + * used</td> * </tr> * <tr> * <td>KR_TV_15</td> * <td>May be inappropriate for children under 15, and that parental discretion should be - * </td> + * used</td> * </tr> * <tr> * <td>KR_TV_19</td> * <td>For adults only</td> * </tr> * <tr> + * <td valign="top" rowspan="9">MV_TV</td> * <td>MV_TV_Y</td> * <td>Young children</td> * </tr> @@ -860,6 +930,7 @@ import java.util.Objects; * <td>Most restrictive classification, only adults ages 25 and above may view</td> * </tr> * <tr> + * <td valign="top" rowspan="6">MX_TV</td> * <td>MX_TV_A</td> * <td>Appropriate for all ages, parental guidance is recommended for children under 7 years * </td> @@ -867,41 +938,43 @@ import java.util.Objects; * <tr> * <td>MX_TV_B</td> * <td>Designed for ages 12 and older, may contain some sexual situations, mild violence, - * mild language</td> + * and mild language</td> * </tr> * <tr> * <td>MX_TV_B-15</td> - * <td>Designed for ages 15 and up, slightly more intensive than the \'A\' and \'B\' ratings + * <td>Designed for ages 15 and up, slightly more intensive than the 'A' and 'B' ratings * </td> * </tr> * <tr> * <td>MX_TV_C</td> * <td>Designed to be viewed by adults aged 18 or older only, generally more intensive - * </td> + * content</td> * </tr> * <tr> * <td>MX_TV_D</td> * <td>Designed to be viewed only by mature adults (at least 21 years of age and over), - * extreme content matter</td> + * contains extreme content matter</td> * </tr> * <tr> * <td>MX_TV_RC</td> * <td>Banned from public television in Mexico</td> * </tr> * <tr> + * <td valign="top" rowspan="3">MY_TV</td> * <td>MY_TV_U</td> * <td>General viewing for all ages, can be broadcast anytime</td> * </tr> * <tr> * <td>MY_TV_P13</td> * <td>For viewers ages 13 and above, children under 13 needs parental guidance, can be - * anytime, but some elements may only be broadcast at night</td> + * broadcast anytime, but some elements may only be broadcast at night</td> * </tr> * <tr> * <td>MY_TV_18</td> * <td>For viewers ages 18 and above only</td> * </tr> * <tr> + * <td valign="top" rowspan="5">NL_TV</td> * <td>NL_TV_AL</td> * <td>All Ages</td> * </tr> @@ -922,23 +995,25 @@ import java.util.Objects; * <td>Parental advisory for children under 16</td> * </tr> * <tr> + * <td valign="top" rowspan="3">NZ_FTV</td> * <td>NZ_FTV_G</td> * <td>These exclude material likely to harm children under 14 and can screen at any time. - * may not necessarily be designed for younger viewers, but must not contain material likely - * cause them undue distress or discomfort</td> + * Programmes may not necessarily be designed for younger viewers, but must not contain + * material likely to cause them undue distress or discomfort</td> * </tr> * <tr> * <td>NZ_FTV_PGR</td> * <td>Programmes more suited to more mature viewers. These are not necessarily unsuitable - * children, but viewer discretion is advised, and parents and guardians are encouraged to - * younger viewers</td> + * for children, but viewer discretion is advised, and parents and guardians are encouraged + * to supervise younger viewers</td> * </tr> * <tr> * <td>NZ_FTV_AO</td> * <td>Contain material of an adult nature handled in such a way that it is unsuitable for - * </td> + * children</td> * </tr> * <tr> + * <td valign="top" rowspan="5">NZ_PTV</td> * <td>NZ_PTV_G</td> * <td>suitable for general audiences</td> * </tr> @@ -959,6 +1034,7 @@ import java.util.Objects; * <td>Suitable for viewers 18 and up</td> * </tr> * <tr> + * <td valign="top" rowspan="3">PE_TV</td> * <td>PE_TV_A</td> * <td>Suitable for all audiences</td> * </tr> @@ -971,6 +1047,7 @@ import java.util.Objects; * <td>Suitable for people aged 18 and above only</td> * </tr> * <tr> + * <td valign="top" rowspan="4">PE_ATV</td> * <td>PE_ATV_GP</td> * <td>General audience</td> * </tr> @@ -987,48 +1064,52 @@ import java.util.Objects; * <td>Suitable for people aged 18 and above only</td> * </tr> * <tr> + * <td valign="top" rowspan="3">PH_TV</td> * <td>PH_TV_G</td> * <td>Suitable for all public viewers</td> * </tr> * <tr> * <td>PH_TV_PG</td> * <td>Programmes rated PG may contain scenes or other content that are unsuitable for - * without the guidance of a parent</td> + * children without the guidance of a parent</td> * </tr> * <tr> * <td>PH_TV_SPG</td> * <td>Contains mature themes or moderate to intense violence, which may be deemed unfit for - * to watch without strict parental supervision</td> + * children to watch without strict parental supervision</td> * </tr> * <tr> + * <td valign="top" rowspan="5">PL_TV</td> * <td>PL_TV_G</td> * <td>Positive or neutral view of the world, little to no violence, non-sexual love, and no - * content</td> + * sexual content</td> * </tr> * <tr> * <td>PL_TV_7</td> * <td>Age 7 and above. May additionally contain some mild language, bloodless violence, and - * more negative view of the world</td> + * a more negative view of the world</td> * </tr> * <tr> * <td>PL_TV_12</td> * <td>Age 12 and above. May contain some foul language, some violence, and some sexual - * </td> + * content</td> * </tr> * <tr> * <td>PL_TV_16</td> * <td>Age 16 and above. Deviant social behaviour, world filled with violence and sexuality, - * picture of adulthood, display of physical force, especially in controversial social - * immoral behaviour without ethic dilemma, putting the blame on the victim, excessive - * on material possessions</td> + * simplified picture of adulthood, display of physical force, especially in controversial + * social context, immoral behaviour without ethic dilemma, putting the blame on the victim, + * excessive concentration on material possessions</td> * </tr> * <tr> * <td>PL_TV_18</td> * <td>Age 18 and above. One-sided display of the joys of adult life without showing - * social justification of violent behaviour, excessive vulgarity, use of racial slurs and - * stereotypes, explicit sexual content, praise of aggression or vulgarity</td> + * responsibilities, social justification of violent behaviour, excessive vulgarity, use of + * racial slurs and social stereotypes, explicit sexual content, praise of aggression or + * vulgarity</td> * </tr> * <tr> + * <td valign="top" rowspan="4">PT_TV</td> * <td>PT_TV_T</td> * <td>Suitable for all</td> * </tr> @@ -1045,6 +1126,7 @@ import java.util.Objects; * <td>Not suitable for children under 16</td> * </tr> * <tr> + * <td valign="top" rowspan="6">RO_TV</td> * <td>RO_TV_Y</td> * <td>Young Ages</td> * </tr> @@ -1069,6 +1151,7 @@ import java.util.Objects; * <td>Forbidden for children under 18 years of age</td> * </tr> * <tr> + * <td valign="top" rowspan="5">RU_TV</td> * <td>RU_TV_0</td> * <td>Can be watched by Any Age</td> * </tr> @@ -1089,6 +1172,7 @@ import java.util.Objects; * <td>Restricted to children ONLY people 18 or older</td> * </tr> * <tr> + * <td valign="top" rowspan="7">RS_TV</td> * <td>RS_TV_G</td> * <td>Program suitable for all ages</td> * </tr> @@ -1117,14 +1201,16 @@ import java.util.Objects; * <td>Program not suitable for minors under the age of 18</td> * </tr> * <tr> + * <td valign="top" rowspan="2">SG_FTV</td> * <td>SG_FTV_PG</td> * <td>Suitable for most but parents should guide their young</td> * </tr> * <tr> * <td>SG_FTV_PG13</td> - * <td>Parental Guidance Strongly Cautioned – Suitable for 13 And Above</td> + * <td>Parental Guidance Strongly Cautioned - Suitable for 13 And Above</td> * </tr> * <tr> + * <td valign="top" rowspan="2">SG_PTV</td> * <td>SG_PTV_NC16</td> * <td>No Children Under 16</td> * </tr> @@ -1133,6 +1219,7 @@ import java.util.Objects; * <td>Nobody under age 18 is admitted</td> * </tr> * <tr> + * <td valign="top" rowspan="4">SI_TV</td> * <td>SI_TV_VS</td> * <td>Parental guidance suggested (for children under 6)</td> * </tr> @@ -1149,12 +1236,13 @@ import java.util.Objects; * <td>Content exclusively for adults</td> * </tr> * <tr> + * <td valign="top" rowspan="6">TH_TV</td> * <td>TH_TV_P</td> * <td>Content suitable for primary school aged children</td> * </tr> * <tr> * <td>TH_TV_C</td> - * <td>Content suitable for children between 6–12 years old</td> + * <td>Content suitable for children between 6-12 years old</td> * </tr> * <tr> * <td>TH_TV_G</td> @@ -1163,18 +1251,19 @@ import java.util.Objects; * <tr> * <td>TH_TV_PG13</td> * <td>Content suitable for people aged 13 and above, but can be watched by those who are - * the recommended age if parental guidance is provided</td> + * under the recommended age if parental guidance is provided</td> * </tr> * <tr> * <td>TH_TV_PG18</td> * <td>Content suitable for people aged above 18 years old; those who are younger that 18 - * be provided with parental guidance</td> + * must be provided with parental guidance</td> * </tr> * <tr> * <td>TH_TV_A</td> * <td>Content unsuitable for children and youngsters</td> * </tr> * <tr> + * <td valign="top" rowspan="4">TR_TV</td> * <td>TR_TV_G</td> * <td>General audience. Suitable for all ages</td> * </tr> @@ -1191,65 +1280,69 @@ import java.util.Objects; * <td>Suitable for ages 13 and over</td> * </tr> * <tr> + * <td valign="top" rowspan="4">TW_TV</td> * <td>TW_TV_G</td> * <td>For all ages</td> * </tr> * <tr> * <td>TW_TV_P</td> * <td>Not suitable for children under 6 years old. People aged 6 but under 12 require - * from accompanying adults to watch</td> + * guidance from accompanying adults to watch</td> * </tr> * <tr> * <td>TW_TV_PG</td> * <td>Not suitable for people under 12 years of age. Parental guidance is required for - * aged 12 but under 18</td> + * people aged 12 but under 18</td> * </tr> * <tr> * <td>TW_TV_R</td> * <td>For adults only and people under 18 years of age must not watch</td> * </tr> * <tr> + * <td valign="top" rowspan="3">UA_TV</td> * <td>UA_TV_G</td> * <td>This program does not have age restrictions</td> * </tr> * <tr> * <td>UA_TV_Y</td> * <td>Children must view this program with parents. In it program there are fragments, - * unsuitable for children</td> + * which unsuitable for children</td> * </tr> * <tr> * <td>UA_TV_R</td> * <td>This program is only for adult viewers. In it there are scenes with nudity, drug use, - * violence</td> + * or violence</td> * </tr> * <tr> - * <td>US_TVPG_TV_Y</td> + * <td valign="top" rowspan="6">US_TV</td> + * <td>US_TV_Y</td> * <td>This program is designed to be appropriate for all children</td> * </tr> * <tr> - * <td>US_TVPG_TV_Y7</td> + * <td>US_TV_Y7</td> * <td>This program is designed for children age 7 and above</td> * </tr> * <tr> - * <td>US_TVPG_TV_G</td> + * <td>US_TV_G</td> * <td>Most parents would find this program suitable for all ages</td> * </tr> * <tr> - * <td>US_TVPG_TV_PG</td> + * <td>US_TV_PG</td> * <td>This program contains material that parents may find unsuitable for younger children * </td> * </tr> * <tr> - * <td>US_TVPG_TV_14</td> + * <td>US_TV_14</td> * <td>This program contains some material that many parents would find unsuitable for - * under 14 years of age</td> + * children under 14 years of age</td> * </tr> * <tr> - * <td>US_TVPG_TV_MA</td> + * <td>US_TV_MA</td> * <td>This program is specifically designed to be viewed by adults and therefore may be - * for children under 17</td> + * unsuitable for children under 17</td> * </tr> * <tr> + * <td valign="top" rowspan="3">VE_TV</td> * <td>VE_TV_TU</td> * <td>For all ages</td> * </tr> @@ -1262,139 +1355,153 @@ import java.util.Objects; * <td>Mature viewers</td> * </tr> * <tr> + * <td valign="top" rowspan="6">ZA_TV</td> * <td>ZA_TV_F</td> * <td>This is a program/film that does not contain any obscenity, and is suitable for - * viewing. A logo must be displayed in the corner of the screen for 30 seconds after each - * break</td> + * family viewing. A logo must be displayed in the corner of the screen for 30 seconds after + * each commercial break</td> * </tr> * <tr> * <td>ZA_TV_PG</td> * <td>Children under 6 may watch this program/film, but must be accompanied by an adult. - * program contains an adult related theme, which might include very mild language, violence - * sexual innuendo. A logo must be displayed in the corner of the screen for one minute - * each commercial break</td> + * This program contains an adult related theme, which might include very mild language, + * violence and sexual innuendo. A logo must be displayed in the corner of the screen for + * one minute after each commercial break</td> * </tr> * <tr> * <td>ZA_TV_13</td> * <td>Children under 13 are prohibited from watching this program/film. This program - * mild language, violence and sexual innuendo. A logo must be displayed in the corner of - * screen for two minutes after each commercial break</td> + * contains mild language, violence and sexual innuendo. A logo must be displayed in the + * corner of the screen for two minutes after each commercial break</td> * </tr> * <tr> * <td>ZA_TV_16</td> * <td>Children under 16 are prohibited from watching this program/film. It contains - * violence, language, and some sexual situations. In the case of television, this program - * only be broadcast after 9pm–4:30am. A logo must be displayed in the corner of the screen - * five minutes after each commercial break. A full-screen warning must be issued before the - * of the program. If the program is longer than an hour, a warning must be displayed every - * an hour</td> + * moderate violence, language, and some sexual situations. In the case of television, this + * program may only be broadcast after 9pm-4:30am. A logo must be displayed in the corner of + * the screen for five minutes after each commercial break. A full-screen warning must be + * issued before the start of the program. If the program is longer than an hour, a warning + * must be displayed every half an hour</td> * </tr> * <tr> * <td>ZA_TV_18</td> * <td>Children under 18 are prohibited from watching this program/film. It contains extreme - * language and/or graphic sexual content. In the case of television, this program may only - * broadcast from 10pm–4:30am. A logo must be displayed in the corner of the screen for the - * of the program. A full-screen warning must be issued before the start of the program and - * each commercial break</td> + * violence, language and/or graphic sexual content. In the case of television, this program + * may only be broadcast from 10pm-4:30am. A logo must be displayed in the corner of the + * screen for the duration of the program. A full-screen warning must be issued before the + * start of the program and after each commercial break</td> * </tr> * <tr> * <td>ZA_TV_R18</td> * <td>This is reserved for films of an extreme sexual nature (pornography). R18 films may - * be distributed in the form of video and DVD in a controlled environment (e.g. Adult - * No public viewing of this film may take place. R18 films may not be broadcast on - * and in cinemas</td> + * only be distributed in the form of video and DVD in a controlled environment (e.g. Adult + * Shops). No public viewing of this film may take place. R18 films may not be broadcast on + * television and in cinemas</td> * </tr> * </table> * * <u>System defined string for {@code subRating}</u> - * <table border="0" cellspacing="0" cellpadding="0"> + * <table border="1" cellspacing="0" cellpadding="0"> * <tr> - * <td width=10%>String value</td> + * <td width="10%">RatingSystem code</td> + * <td width="10%">Rating string value</td> * <td>Comments</td> * </tr> * <tr> + * <td valign="top" rowspan="6">NL_TV</td> * <td>NL_TV_V</td> - * <td>Violence</td> + * <td>Violence<br/>Applicable to NL_TV_AL, NL_TV_6, NL_TV_9, NL_TV_12, NL_TV_16</td> * </tr> * <tr> * <td>NL_TV_F</td> - * <td>Scary or Disturbing Content</td> + * <td>Scary or Disturbing ContentViolence<br/>Applicable to NL_TV_AL, NL_TV_6, NL_TV_9, + * NL_TV_12, NL_TV_16</td> * </tr> * <tr> * <td>NL_TV_S</td> - * <td>Sexual Content</td> + * <td>Sexual Content<br/>Applicable to NL_TV_AL, NL_TV_6, NL_TV_9, NL_TV_12, NL_TV_16</td> * </tr> * <tr> * <td>NL_TV_D</td> - * <td>Discrimination</td> + * <td>Discrimination<br/>Applicable to NL_TV_AL, NL_TV_6, NL_TV_9, NL_TV_12, NL_TV_16</td> * </tr> * <tr> * <td>NL_TV_DA</td> - * <td>Drug and/or Alcohol abuse</td> + * <td>Drug and/or Alcohol abuse<br/>Applicable to NL_TV_AL, NL_TV_6, NL_TV_9, NL_TV_12, + * NL_TV_16</td> * </tr> * <tr> * <td>NL_TV_L</td> - * <td>Bad Language</td> + * <td>Bad Language<br/>Applicable to NL_TV_AL, NL_TV_6, NL_TV_9, NL_TV_12, NL_TV_16</td> * </tr> * <tr> + * <td valign="top" rowspan="4">NZ_PTV</td> * <td>NZ_PTV_C</td> - * <td>Content may offend</td> + * <td>Content may offend<br/>Applicable to NZ_PTV_PG, NZ_PTV_M, NZ_PTV_16, NZ_PTV_18</td> * </tr> * <tr> * <td>NZ_PTV_V</td> - * <td>Violence</td> + * <td>Violence<br/>Applicable to NZ_PTV_PG, NZ_PTV_M, NZ_PTV_16, NZ_PTV_18</td> * </tr> * <tr> * <td>NZ_PTV_L</td> - * <td>Language</td> + * <td>Language<br/>Applicable to NZ_PTV_PG, NZ_PTV_M, NZ_PTV_16, NZ_PTV_18</td> * </tr> * <tr> * <td>NZ_PTV_S</td> - * <td>Sexual content</td> + * <td>Sexual content<br/>Applicable to NZ_PTV_PG, NZ_PTV_M, NZ_PTV_16, NZ_PTV_18</td> * </tr> * <tr> - * <td>US_TVPG_D</td> - * <td>Suggestive dialogue (Usually means talks about sex)</td> + * <td valign="top" rowspan="5">US_TV</td> + * <td>US_TV_D</td> + * <td>Suggestive dialogue (Usually means talks about sex)<br/>Applicable to US_TV_PG, + * US_TV_14, US_TV</td> * </tr> * <tr> - * <td>US_TVPG_L</td> - * <td>Coarse language</td> + * <td>US_TV_L</td> + * <td>Coarse language<br/>Applicable to US_TV_PG, US_TV_14</td> * </tr> * <tr> - * <td>US_TVPG_S</td> - * <td>Sexual content</td> + * <td>US_TV_S</td> + * <td>Sexual content<br/>Applicable to US_TV_PG, US_TV_14, US_TV_MA</td> * </tr> * <tr> - * <td>US_TVPG_V</td> - * <td>Violence</td> + * <td>US_TV_V</td> + * <td>Violence<br/>Applicable to US_TV_PG, US_TV_14, US_TV_MA</td> * </tr> * <tr> - * <td>US_TVPG_FV</td> - * <td>Fantasy violence (Children\'s programming only)</td> + * <td>US_TV_FV</td> + * <td>Fantasy violence (Children's programming only)<br/>Applicable to US_TV_Y7</td> * </tr> * <tr> + * <td valign="top" rowspan="6">ZA_TV</td> * <td>ZA_TV_D</td> - * <td>Drug</td> + * <td>Drug<br/>Applicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, ZA_TV_R18 + * </td> * </tr> * <tr> * <td>ZA_TV_V</td> - * <td>Violence</td> + * <td>Violence<br/>Applicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, ZA_TV_R18 + * </td> * </tr> * <tr> * <td>ZA_TV_N</td> - * <td>Nudity</td> + * <td>Nudity<br/>Applicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, ZA_TV_R18 + * </td> * </tr> * <tr> * <td>ZA_TV_P</td> - * <td>Prejudice</td> + * <td>Prejudice<br/>Applicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, + * ZA_TV_R18</td> * </tr> * <tr> * <td>ZA_TV_S</td> - * <td>Sex</td> + * <td>Sex<br/>Applicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, ZA_TV_R18</td> * </tr> * <tr> * <td>ZA_TV_L</td> - * <td>Language</td> + * <td>Language<br/>Applicable to ZA_TV_F, ZA_TV_PG, ZA_TV_13, ZA_TV_16, ZA_TV_18, ZA_TV_R18 + * </td> * </tr> * </table> */ @@ -1480,7 +1587,7 @@ public final class TvContentRating { Arrays.sort(subRatings); mSubRatings = subRatings; } - mHashCode = Objects.hash(mDomain, mRating, mSubRatings); + mHashCode = 31 * Objects.hash(mDomain, mRating) + Arrays.hashCode(mSubRatings); } /** diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java index e975676c811e..9a32bd667712 100644 --- a/media/java/android/media/tv/TvContract.java +++ b/media/java/android/media/tv/TvContract.java @@ -153,7 +153,8 @@ public final class TvContract { /** * Builds a URI that points to all channels from a given TV input. * - * @param inputId The ID of the TV input to build a channels URI for. + * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a + * URI for all the TV inputs. */ public static final Uri buildChannelsUriForInput(String inputId) { return buildChannelsUriForInput(inputId, false); @@ -162,43 +163,46 @@ public final class TvContract { /** * Builds a URI that points to all or browsable-only channels from a given TV input. * - * @param inputId The ID of the TV input to build a channels URI for. + * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a + * URI for all the TV inputs. * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set * to {@code false} the URI points to all channels regardless of whether they are * browsable or not. * @hide */ + @SystemApi public static final Uri buildChannelsUriForInput(String inputId, boolean browsableOnly) { - return Channels.CONTENT_URI.buildUpon() - .appendQueryParameter(PARAM_INPUT, inputId) - .appendQueryParameter(PARAM_BROWSABLE_ONLY, String.valueOf(browsableOnly)).build(); + Uri.Builder builder = Channels.CONTENT_URI.buildUpon(); + if (inputId != null) { + builder.appendQueryParameter(PARAM_INPUT, inputId); + } + return builder.appendQueryParameter(PARAM_BROWSABLE_ONLY, String.valueOf(browsableOnly)) + .build(); } /** * Builds a URI that points to all or browsable-only channels which have programs with the given * genre from the given TV input. * - * @param inputId The ID of the TV input to build a channels URI for. If null, builds a URI for - * all the TV inputs. - * @param genre {@link Programs.Genres} to search. + * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a + * URI for all the TV inputs. + * @param genre {@link Programs.Genres} to search. If {@code null}, builds a URI for all genres. * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set * to {@code false} the URI points to all channels regardless of whether they are * browsable or not. * @hide */ - public static final Uri buildChannelsUriForCanonicalGenre(String inputId, String genre, + @SystemApi + public static final Uri buildChannelsUriForInput(String inputId, String genre, boolean browsableOnly) { + if (genre == null) { + return buildChannelsUriForInput(inputId, browsableOnly); + } if (!Programs.Genres.isCanonical(genre)) { throw new IllegalArgumentException("Not a canonical genre: '" + genre + "'"); } - - Uri uri; - if (inputId == null) { - uri = Channels.CONTENT_URI; - } else { - uri = buildChannelsUriForInput(inputId, browsableOnly); - } - return uri.buildUpon().appendQueryParameter(PARAM_CANONICAL_GENRE, genre).build(); + return buildChannelsUriForInput(inputId, browsableOnly).buildUpon() + .appendQueryParameter(PARAM_CANONICAL_GENRE, genre).build(); } /** diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java index e735e4e3f579..6ed758073222 100644 --- a/media/java/android/media/tv/TvInputInfo.java +++ b/media/java/android/media/tv/TvInputInfo.java @@ -38,7 +38,6 @@ import android.provider.Settings; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; -import android.util.Pair; import android.util.SparseIntArray; import android.util.Xml; @@ -47,9 +46,11 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; /** * This class is used to specify meta information of a TV input. @@ -245,17 +246,17 @@ public final class TvInputInfo implements Parcelable { Log.d(TAG, "Settings activity loaded. [" + input.mSettingsActivity + "] for " + si.name); } - int contentRatingSystemXml = sa.getResourceId( - com.android.internal.R.styleable.TvInputService_contentRatingSystemXml, -1); - if (contentRatingSystemXml != -1) { + int tvContentRatingDescription = sa.getResourceId( + com.android.internal.R.styleable.TvInputService_tvContentRatingDescription, -1); + if (tvContentRatingDescription != -1) { input.mRatingSystemXmlUri = new Uri.Builder() .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) .authority(si.packageName) - .appendPath(Integer.toString(contentRatingSystemXml)) + .appendPath(Integer.toString(tvContentRatingDescription)) .build(); if (DEBUG) { - Log.d(TAG, "Content rating xml loaded. [" + contentRatingSystemXml + "] for " - + si.name); + Log.d(TAG, "Content rating xml loaded. [" + tvContentRatingDescription + + "] for " + si.name); } } sa.recycle(); @@ -405,7 +406,7 @@ public final class TvInputInfo implements Parcelable { */ @SystemApi public boolean isHidden(Context context) { - return TvInputSettings.isHidden(context, mId, UserHandle.USER_CURRENT); + return TvInputSettings.isHidden(context, mId, UserHandle.myUserId()); } /** @@ -433,7 +434,7 @@ public final class TvInputInfo implements Parcelable { */ @SystemApi public CharSequence loadCustomLabel(Context context) { - return TvInputSettings.getCustomLabel(context, mId, UserHandle.USER_CURRENT); + return TvInputSettings.getCustomLabel(context, mId, UserHandle.myUserId()); } /** @@ -601,66 +602,61 @@ public final class TvInputInfo implements Parcelable { } private static String getCustomLabel(Context context, String inputId, int userId) { - for (Pair<String, String> pair : getCustomLabelList(context, userId)) { - if (pair.first.equals(inputId)) { - return pair.second; - } - } - return null; + return getCustomLabels(context, userId).get(inputId); } /** - * Returns a list of TV input IDs which are marked as hidden by user in the settings. + * Returns a set of TV input IDs which are marked as hidden by user in the settings. * * @param context The application context - * @param userId The user ID for the stored hidden input list + * @param userId The user ID for the stored hidden input set * @hide */ @SystemApi - public static List<String> getHiddenTvInputIds(Context context, int userId) { + public static Set<String> getHiddenTvInputIds(Context context, int userId) { String hiddenIdsString = Settings.Secure.getStringForUser( context.getContentResolver(), Settings.Secure.TV_INPUT_HIDDEN_INPUTS, userId); if (TextUtils.isEmpty(hiddenIdsString)) { - return new ArrayList<String>(); + return new HashSet<String>(); } String[] ids = hiddenIdsString.split(TV_INPUT_SEPARATOR); - return new ArrayList(Arrays.asList(ids)); + return new HashSet(Arrays.asList(ids)); } /** - * Returns a list of TV input ID/custom label pairs set by the user in the settings. + * Returns a map of TV input ID/custom label pairs set by the user in the settings. * * @param context The application context - * @param userId The user ID for the stored hidden input list + * @param userId The user ID for the stored hidden input map * @hide */ @SystemApi - public static List<Pair<String, String>> getCustomLabelList(Context context, int userId) { + public static Map<String, String> getCustomLabels(Context context, int userId) { String labelsString = Settings.Secure.getStringForUser( context.getContentResolver(), Settings.Secure.TV_INPUT_CUSTOM_LABELS, userId); - List<Pair<String, String>> list = new ArrayList<Pair<String, String>>(); + Map<String, String> map = new HashMap<String, String>(); if (TextUtils.isEmpty(labelsString)) { - return list; + return map; } String[] pairs = labelsString.split(TV_INPUT_SEPARATOR); for (String pairString : pairs) { String[] pair = pairString.split(CUSTOM_NAME_SEPARATOR); - list.add(new Pair<String, String>(pair[0], pair[1])); + map.put(pair[0], pair[1]); } - return list; + return map; } /** - * Stores a list of TV input IDs which are marked as hidden by user. This is expected to + * Stores a set of TV input IDs which are marked as hidden by user. This is expected to * be called from the settings app. * * @param context The application context - * @param hiddenInputIds A list including all the hidden TV input IDs - * @param userId The user ID for the stored hidden input list + * @param hiddenInputIds A set including all the hidden TV input IDs + * @param userId The user ID for the stored hidden input set * @hide */ @SystemApi - public static void putHiddenTvInputList(Context context, List<String> hiddenInputIds, + public static void putHiddenTvInputs(Context context, Set<String> hiddenInputIds, int userId) { StringBuilder builder = new StringBuilder(); boolean firstItem = true; @@ -678,30 +674,30 @@ public final class TvInputInfo implements Parcelable { } /** - * Stores a list of TV input ID/custom label pairs set by user. This is expected to be + * Stores a map of TV input ID/custom label set by user. This is expected to be * called from the settings app. * * @param context The application context. - * @param customLabels A list of TV input ID/custom label pairs - * @param userId The user ID for the stored hidden input list + * @param customLabels A map of TV input ID/custom label pairs + * @param userId The user ID for the stored hidden input map * @hide */ @SystemApi - public static void putCustomLabelList(Context context, - List<Pair<String, String>> customLabels, int userId) { + public static void putCustomLabels(Context context, + Map<String, String> customLabels, int userId) { StringBuilder builder = new StringBuilder(); boolean firstItem = true; - for (Pair<String, String> pair : customLabels) { - ensureValidField(pair.first); - ensureValidField(pair.second); + for (Map.Entry<String, String> entry: customLabels.entrySet()) { + ensureValidField(entry.getKey()); + ensureValidField(entry.getValue()); if (firstItem) { firstItem = false; } else { builder.append(TV_INPUT_SEPARATOR); } - builder.append(pair.first); + builder.append(entry.getKey()); builder.append(CUSTOM_NAME_SEPARATOR); - builder.append(pair.second); + builder.append(entry.getValue()); } Settings.Secure.putStringForUser(context.getContentResolver(), Settings.Secure.TV_INPUT_CUSTOM_LABELS, builder.toString(), userId); diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp index ecba02abb934..12eb7d24aed4 100644 --- a/media/jni/android_media_MediaCodecList.cpp +++ b/media/jni/android_media_MediaCodecList.cpp @@ -85,6 +85,7 @@ static jint android_media_MediaCodecList_findCodecByName( sp<IMediaCodecList> mcl = getCodecList(env); if (mcl == NULL) { // Runtime exception already pending. + env->ReleaseStringUTFChars(name, nameStr); return -ENOENT; } @@ -162,7 +163,6 @@ static jobject android_media_MediaCodecList_getCodecCapabilities( } const char *typeStr = env->GetStringUTFChars(type, NULL); - if (typeStr == NULL) { // Out of memory exception already pending. return NULL; @@ -177,12 +177,12 @@ static jobject android_media_MediaCodecList_getCodecCapabilities( // TODO query default-format also from codec/codec list const sp<MediaCodecInfo::Capabilities> &capabilities = info->getCapabilitiesFor(typeStr); + env->ReleaseStringUTFChars(type, typeStr); + typeStr = NULL; if (capabilities == NULL) { jniThrowException(env, "java/lang/IllegalArgumentException", NULL); return NULL; } - env->ReleaseStringUTFChars(type, typeStr); - typeStr = NULL; capabilities->getSupportedColorFormats(&colorFormats); capabilities->getSupportedProfileLevels(&profileLevels); diff --git a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java index 30383230db98..b2e38fc83c0c 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java +++ b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java @@ -210,7 +210,7 @@ public class IconUtils { return pm.getDrawable(info.packageName, icon, info.applicationInfo); } } else { - return context.getResources().getDrawable(icon); + return context.getDrawable(icon); } } return null; @@ -218,19 +218,17 @@ public class IconUtils { public static Drawable loadMimeIcon( Context context, String mimeType, String authority, String docId, int mode) { - final Resources res = context.getResources(); - if (Document.MIME_TYPE_DIR.equals(mimeType)) { // TODO: eventually move these hacky assets into that package if ("com.android.providers.media.documents".equals(authority) && docId.startsWith("album")) { - return res.getDrawable(R.drawable.ic_doc_album); + return context.getDrawable(R.drawable.ic_doc_album); } if (mode == DocumentsActivity.State.MODE_GRID) { - return res.getDrawable(R.drawable.ic_grid_folder); + return context.getDrawable(R.drawable.ic_grid_folder); } else { - return res.getDrawable(R.drawable.ic_doc_folder); + return context.getDrawable(R.drawable.ic_doc_folder); } } @@ -238,16 +236,14 @@ public class IconUtils { } public static Drawable loadMimeIcon(Context context, String mimeType) { - final Resources res = context.getResources(); - if (Document.MIME_TYPE_DIR.equals(mimeType)) { - return res.getDrawable(R.drawable.ic_doc_folder); + return context.getDrawable(R.drawable.ic_doc_folder); } // Look for exact match first Integer resId = sMimeIcons.get(mimeType); if (resId != null) { - return res.getDrawable(resId); + return context.getDrawable(resId); } if (mimeType == null) { @@ -258,15 +254,15 @@ public class IconUtils { // Otherwise look for partial match final String typeOnly = mimeType.split("/")[0]; if ("audio".equals(typeOnly)) { - return res.getDrawable(R.drawable.ic_doc_audio); + return context.getDrawable(R.drawable.ic_doc_audio); } else if ("image".equals(typeOnly)) { - return res.getDrawable(R.drawable.ic_doc_image); + return context.getDrawable(R.drawable.ic_doc_image); } else if ("text".equals(typeOnly)) { - return res.getDrawable(R.drawable.ic_doc_text); + return context.getDrawable(R.drawable.ic_doc_text); } else if ("video".equals(typeOnly)) { - return res.getDrawable(R.drawable.ic_doc_video); + return context.getDrawable(R.drawable.ic_doc_video); } else { - return res.getDrawable(R.drawable.ic_doc_generic); + return context.getDrawable(R.drawable.ic_doc_generic); } } @@ -276,7 +272,7 @@ public class IconUtils { final TypedValue outValue = new TypedValue(); context.getTheme().resolveAttribute(tintAttrId, outValue, true); - final Drawable icon = res.getDrawable(drawableId); + final Drawable icon = context.getDrawable(drawableId); icon.mutate(); icon.setTintList(res.getColorStateList(outValue.resourceId)); return icon; diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java index 82c3048ae2bc..dd75dbdba635 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java @@ -221,8 +221,7 @@ public class RecentsCreateFragment extends Fragment { final DocumentStack stack = getItem(position); iconMime.setImageDrawable(stack.root.loadIcon(context)); - final Drawable crumb = context.getResources() - .getDrawable(R.drawable.ic_breadcrumb_arrow); + final Drawable crumb = context.getDrawable(R.drawable.ic_breadcrumb_arrow); crumb.setBounds(0, 0, crumb.getIntrinsicWidth(), crumb.getIntrinsicHeight()); final SpannableStringBuilder builder = new SpannableStringBuilder(); diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java index a358798c9c87..fcfe518c1501 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java +++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java @@ -205,7 +205,7 @@ public class RootInfo implements Durable, Parcelable { public Drawable loadIcon(Context context) { if (derivedIcon != 0) { - return context.getResources().getDrawable(derivedIcon); + return context.getDrawable(derivedIcon); } else { return IconUtils.loadPackageIcon(context, authority, icon); } diff --git a/packages/Keyguard/res/values-h560dp/dimens.xml b/packages/Keyguard/res/values-h560dp/dimens.xml new file mode 100644 index 000000000000..16831133c325 --- /dev/null +++ b/packages/Keyguard/res/values-h560dp/dimens.xml @@ -0,0 +1,20 @@ +<?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 + --> + +<resources> + <dimen name="widget_big_font_size">96dp</dimen> +</resources>
\ No newline at end of file diff --git a/packages/Keyguard/res/values-sw600dp-land/dimens.xml b/packages/Keyguard/res/values-sw600dp-land/dimens.xml index 13a6f628daed..89252cfd9b82 100644 --- a/packages/Keyguard/res/values-sw600dp-land/dimens.xml +++ b/packages/Keyguard/res/values-sw600dp-land/dimens.xml @@ -25,5 +25,5 @@ <dimen name="kg_status_line_font_right_margin">16dp</dimen> <!-- Overload default clock widget parameters --> - <dimen name="widget_big_font_size">88dp</dimen> + <dimen name="widget_big_font_size">100dp</dimen> </resources>
\ No newline at end of file diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml index 69bf44fa8008..74be1ff7feeb 100644 --- a/packages/Keyguard/res/values-sw600dp/dimens.xml +++ b/packages/Keyguard/res/values-sw600dp/dimens.xml @@ -63,7 +63,7 @@ <dimen name="keyguard_muliuser_selector_margin">12dp</dimen> <!-- Overload default clock widget parameters --> - <dimen name="widget_big_font_size">120dp</dimen> + <dimen name="widget_big_font_size">140dp</dimen> <dimen name="widget_label_font_size">16sp</dimen> <dimen name="bottom_text_spacing_digital">-16dp</dimen> diff --git a/packages/Keyguard/res/values-sw720dp-land/dimens.xml b/packages/Keyguard/res/values-sw720dp-land/dimens.xml index 14726ab3eb52..731bb64ef8ea 100644 --- a/packages/Keyguard/res/values-sw720dp-land/dimens.xml +++ b/packages/Keyguard/res/values-sw720dp-land/dimens.xml @@ -26,4 +26,6 @@ <!-- Horizontal padding for the widget pager --> <dimen name="kg_widget_pager_horizontal_padding">32dp</dimen> + + <dimen name="widget_big_font_size">150dp</dimen> </resources> diff --git a/packages/Keyguard/res/values-sw720dp/dimens.xml b/packages/Keyguard/res/values-sw720dp/dimens.xml index c487072349a1..3e89a84db2ce 100644 --- a/packages/Keyguard/res/values-sw720dp/dimens.xml +++ b/packages/Keyguard/res/values-sw720dp/dimens.xml @@ -61,4 +61,5 @@ <!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) --> <dimen name="keyguard_security_height">420dp</dimen> + <dimen name="widget_big_font_size">150dp</dimen> </resources> diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml index e822c8225619..bfc05317f65a 100644 --- a/packages/Keyguard/res/values/dimens.xml +++ b/packages/Keyguard/res/values/dimens.xml @@ -161,7 +161,7 @@ <dimen name="bottom_text_spacing_digital">-10dp</dimen> <dimen name="label_font_size">14dp</dimen> <dimen name="widget_label_font_size">16sp</dimen> - <dimen name="widget_big_font_size">96dp</dimen> + <dimen name="widget_big_font_size">88dp</dimen> <dimen name="big_font_size">120dp</dimen> <!-- The y translation to apply at the start in appear animations. --> diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java b/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java index 25f33832ea59..32f7a1e7f2e0 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java @@ -36,6 +36,7 @@ import android.os.UserHandle; import android.provider.MediaStore; import android.util.Log; import android.view.WindowManager; +import android.view.WindowManagerGlobal; import com.android.keyguard.KeyguardHostView.OnDismissAction; @@ -214,9 +215,9 @@ public abstract class KeyguardActivityLauncher { private void dismissKeyguardOnNextActivity() { try { - ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); + WindowManagerGlobal.getWindowManagerService().dismissKeyguard(); } catch (RemoteException e) { - Log.w(TAG, "can't dismiss keyguard on launch"); + Log.w(TAG, "Error dismissing keyguard", e); } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java index bc159cb4f155..f00978779681 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java @@ -68,5 +68,17 @@ public class KeyguardSimpleHostView extends KeyguardViewBase { public void onUserSwitchComplete(int userId) { getSecurityContainer().showPrimarySecurityScreen(false /* turning off */); } + + @Override + public void onTrustInitiatedByUser(int userId) { + if (userId != mLockPatternUtils.getCurrentUser()) return; + if (!isAttachedToWindow()) return; + + if (isVisibleToUser()) { + dismiss(false /* authenticated */); + } else { + // TODO: Play first half of unlock sound. + } + } }; } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java index daba0a22598f..51a276e5128d 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java @@ -16,9 +16,10 @@ package com.android.keyguard; -import android.app.AlarmClockInfo; +import android.app.AlarmManager; import android.content.ContentResolver; import android.content.Context; +import android.content.res.Configuration; import android.content.res.Resources; import android.provider.AlarmClock; import android.text.TextUtils; @@ -26,6 +27,7 @@ import android.text.format.DateFormat; import android.util.AttributeSet; import android.util.Log; import android.util.Slog; +import android.util.TypedValue; import android.view.View; import android.widget.GridLayout; import android.widget.TextClock; @@ -115,8 +117,19 @@ public class KeyguardStatusView extends GridLayout { mClockView.setElegantTextHeight(false); } + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize(R.dimen.widget_big_font_size)); + mDateView.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize(R.dimen.widget_label_font_size)); + mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize(R.dimen.widget_label_font_size)); + } + protected void refresh() { - AlarmClockInfo nextAlarm = mLockPatternUtils.getNextAlarm(); + AlarmManager.AlarmClockInfo nextAlarm = mLockPatternUtils.getNextAlarm(); Patterns.update(mContext, nextAlarm != null); mDateView.setFormat24Hour(Patterns.dateView); @@ -128,7 +141,7 @@ public class KeyguardStatusView extends GridLayout { refreshAlarmStatus(nextAlarm); } - void refreshAlarmStatus(AlarmClockInfo nextAlarm) { + void refreshAlarmStatus(AlarmManager.AlarmClockInfo nextAlarm) { if (nextAlarm != null) { mAlarmStatusView.setText(formatNextAlarm(mContext, nextAlarm)); mAlarmStatusView.setVisibility(View.VISIBLE); @@ -137,7 +150,7 @@ public class KeyguardStatusView extends GridLayout { } } - public static String formatNextAlarm(Context context, AlarmClockInfo info) { + public static String formatNextAlarm(Context context, AlarmManager.AlarmClockInfo info) { if (info == null) { return ""; } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java index d9c5a536b450..e35b2b2fe9ab 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java @@ -237,7 +237,7 @@ public abstract class KeyguardViewBase extends FrameLayout implements SecurityCa } public void startDisappearAnimation(Runnable finishRunnable) { - if (!mSecurityContainer.startDisappearAnimation(finishRunnable)) { + if (!mSecurityContainer.startDisappearAnimation(finishRunnable) && finishRunnable != null) { finishRunnable.run(); } } diff --git a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java index f74843e89f5a..2e5450de1d1d 100644 --- a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java +++ b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java @@ -61,4 +61,9 @@ public interface ViewMediatorCallback { * Report when keyguard is actually gone */ void keyguardGone(); + + /** + * Report when the UI is ready for dismissing the whole Keyguard. + */ + void readyForKeyguardDone(); } diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java index ed17494a7fce..4ea1c772806c 100644 --- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java +++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java @@ -31,6 +31,16 @@ import android.widget.Toast; public class SampleTrustAgent extends TrustAgentService implements SharedPreferences.OnSharedPreferenceChangeListener { + /** + * If true, allows anyone to control this trust agent, e.g. using adb: + * <pre> + * $ adb shell am broadcast -a action.sample_trust_agent.grant_trust\ + * -e extra.message SampleTrust\ + * --el extra.duration 1000 --ez extra.init_by_user false + * </pre> + */ + private static final boolean ALLOW_EXTERNAL_BROADCASTS = false; + LocalBroadcastManager mLocalBroadcastManager; private static final String ACTION_GRANT_TRUST = "action.sample_trust_agent.grant_trust"; @@ -38,7 +48,7 @@ public class SampleTrustAgent extends TrustAgentService private static final String EXTRA_MESSAGE = "extra.message"; private static final String EXTRA_DURATION = "extra.duration"; - private static final String EXTRA_EXTRA = "extra.extra"; + private static final String EXTRA_INITIATED_BY_USER = "extra.init_by_user"; private static final String PREFERENCE_REPORT_UNLOCK_ATTEMPTS = "preference.report_unlock_attempts"; @@ -50,11 +60,16 @@ public class SampleTrustAgent extends TrustAgentService @Override public void onCreate() { super.onCreate(); + mLocalBroadcastManager = LocalBroadcastManager.getInstance(this); + IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_GRANT_TRUST); filter.addAction(ACTION_REVOKE_TRUST); - mLocalBroadcastManager = LocalBroadcastManager.getInstance(this); mLocalBroadcastManager.registerReceiver(mReceiver, filter); + if (ALLOW_EXTERNAL_BROADCASTS) { + registerReceiver(mReceiver, filter); + } + setManagingTrust(getIsManagingTrust(this)); PreferenceManager.getDefaultSharedPreferences(this) .registerOnSharedPreferenceChangeListener(this); @@ -79,6 +94,9 @@ public class SampleTrustAgent extends TrustAgentService public void onDestroy() { super.onDestroy(); mLocalBroadcastManager.unregisterReceiver(mReceiver); + if (ALLOW_EXTERNAL_BROADCASTS) { + unregisterReceiver(mReceiver); + } PreferenceManager.getDefaultSharedPreferences(this) .unregisterOnSharedPreferenceChangeListener(this); } @@ -91,7 +109,7 @@ public class SampleTrustAgent extends TrustAgentService try { grantTrust(intent.getStringExtra(EXTRA_MESSAGE), intent.getLongExtra(EXTRA_DURATION, 0), - false /* initiatedByUser */); + intent.getBooleanExtra(EXTRA_INITIATED_BY_USER, false)); } catch (IllegalStateException e) { Toast.makeText(context, "IllegalStateException: " + e.getMessage(), Toast.LENGTH_SHORT).show(); @@ -103,11 +121,11 @@ public class SampleTrustAgent extends TrustAgentService }; public static void sendGrantTrust(Context context, - String message, long durationMs, Bundle extra) { + String message, long durationMs, boolean initiatedByUser) { Intent intent = new Intent(ACTION_GRANT_TRUST); intent.putExtra(EXTRA_MESSAGE, message); intent.putExtra(EXTRA_DURATION, durationMs); - intent.putExtra(EXTRA_EXTRA, extra); + intent.putExtra(EXTRA_INITIATED_BY_USER, initiatedByUser); LocalBroadcastManager.getInstance(context).sendBroadcast(intent); } diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java index 2c856099c708..bea74ab00655 100644 --- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java +++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java @@ -59,7 +59,7 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi int id = v.getId(); if (id == R.id.enable_trust) { SampleTrustAgent.sendGrantTrust(this, "SampleTrustAgent", TRUST_DURATION_MS, - null /* extra */); + false /* initiatedByUser */); } else if (id == R.id.revoke_trust) { SampleTrustAgent.sendRevokeTrust(this); } else if (id == R.id.crash) { diff --git a/packages/PrintSpooler/res/drawable/ic_savetopdf.xml b/packages/PrintSpooler/res/drawable/ic_savetopdf.xml new file mode 100644 index 000000000000..60ed33aceca2 --- /dev/null +++ b/packages/PrintSpooler/res/drawable/ic_savetopdf.xml @@ -0,0 +1,19 @@ +<?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. +--> + +<bitmap xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/ic_menu_savetopdf" + android:tint="@color/promoted_action_background_color" /> diff --git a/packages/PrintSpooler/res/layout/preview_page.xml b/packages/PrintSpooler/res/layout/preview_page.xml index 509a1d2d090b..76dd76bfa956 100644 --- a/packages/PrintSpooler/res/layout/preview_page.xml +++ b/packages/PrintSpooler/res/layout/preview_page.xml @@ -31,7 +31,7 @@ <RelativeLayout android:id="@+id/page_footer" android:layout_width="fill_parent" - android:layout_height="32dip" + android:layout_height="@dimen/preview_page_footer_height" android:background="@*android:color/material_grey_500" android:orientation="horizontal"> diff --git a/packages/PrintSpooler/res/layout/print_activity.xml b/packages/PrintSpooler/res/layout/print_activity.xml index 3905646c1f65..ee5d42a0cdc1 100644 --- a/packages/PrintSpooler/res/layout/print_activity.xml +++ b/packages/PrintSpooler/res/layout/print_activity.xml @@ -27,7 +27,6 @@ android:id="@+id/static_content" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:padding="16dip" android:elevation="@dimen/preview_controls_elevation" android:background="?android:attr/colorPrimary"> @@ -35,6 +34,7 @@ android:id="@+id/destination_spinner" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginTop="4dip" android:dropDownWidth="wrap_content" android:minHeight="?android:attr/listPreferredItemHeightSmall"> </Spinner> @@ -56,7 +56,6 @@ <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="8dip" android:layout_marginStart="12dip" android:textAppearance="?android:attr/textAppearanceSmall" android:labelFor="@+id/copies_count_summary" @@ -67,7 +66,6 @@ android:id="@+id/copies_count_summary" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="8dip" android:layout_marginStart="16dip" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="?android:attr/textColorPrimary"> @@ -76,7 +74,6 @@ <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="8dip" android:layout_marginStart="32dip" android:textAppearance="?android:attr/textAppearanceSmall" android:labelFor="@+id/paper_size_summary" @@ -87,7 +84,6 @@ android:id="@+id/paper_size_summary" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="8dip" android:layout_marginStart="16dip" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="?android:attr/textColorPrimary"> diff --git a/packages/PrintSpooler/res/layout/print_activity_controls.xml b/packages/PrintSpooler/res/layout/print_activity_controls.xml index ef6044afb28c..31bda7e7be47 100644 --- a/packages/PrintSpooler/res/layout/print_activity_controls.xml +++ b/packages/PrintSpooler/res/layout/print_activity_controls.xml @@ -267,8 +267,8 @@ android:id="@+id/expand_collapse_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="8dip" - android:layout_marginBottom="8dip" + android:layout_marginTop="4dip" + android:layout_marginBottom="4dip" android:layout_gravity="center" android:background="@drawable/ic_expand_more"> </ImageView> diff --git a/packages/PrintSpooler/res/values/constants.xml b/packages/PrintSpooler/res/values/constants.xml index faad5278d63c..b95703b63b76 100644 --- a/packages/PrintSpooler/res/values/constants.xml +++ b/packages/PrintSpooler/res/values/constants.xml @@ -45,4 +45,7 @@ <fraction name="page_selected_alpha">100%</fraction> <fraction name="page_unselected_alpha">50%</fraction> + <dimen name="preview_page_footer_height">32dip</dimen> + <dimen name="preview_page_min_width">130dip</dimen> + </resources> diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java index e97693641c2c..5bcdb9f49d03 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java @@ -96,6 +96,7 @@ public final class PageAdapter extends Adapter implements private float mUnselectedPageAlpha; private int mPreviewPageMargin; + private int mPreviewPageMinWidth; private int mPreviewListPadding; private int mFooterHeight; @@ -141,17 +142,17 @@ public final class PageAdapter extends Adapter implements mPreviewPageMargin = mContext.getResources().getDimensionPixelSize( R.dimen.preview_page_margin); + mPreviewPageMinWidth = mContext.getResources().getDimensionPixelSize( + R.dimen.preview_page_min_width); + mPreviewListPadding = mContext.getResources().getDimensionPixelSize( R.dimen.preview_list_padding); mColumnCount = mContext.getResources().getInteger( R.integer.preview_page_per_row_count); - TypedValue outValue = new TypedValue(); - mContext.getTheme().resolveAttribute( - com.android.internal.R.attr.listPreferredItemHeightSmall, outValue, true); - mFooterHeight = TypedValue.complexToDimensionPixelSize(outValue.data, - mContext.getResources().getDisplayMetrics()); + mFooterHeight = mContext.getResources().getDimensionPixelSize( + R.dimen.preview_page_footer_height); mPreviewArea = previewArea; @@ -428,8 +429,12 @@ public final class PageAdapter extends Adapter implements // Compute max page height. final int pageContentDesiredHeight = (int) (((float) pageContentDesiredWidth / pageAspectRatio) + 0.5f); - final int pageContentMaxHeight = availableHeight - 2 * (mPreviewListPadding - + mPreviewPageMargin) - mFooterHeight; + + // If the page does not fit entirely in a vertial direction, + // we shirk it but not less than the minimal page width. + final int pageContentMinHeight = (int) (mPreviewPageMinWidth / pageAspectRatio + 0.5f); + final int pageContentMaxHeight = Math.max(pageContentMinHeight, + availableHeight - 2 * (mPreviewListPadding + mPreviewPageMargin) - mFooterHeight); mPageContentHeight = Math.min(pageContentDesiredHeight, pageContentMaxHeight); mPageContentWidth = (int) ((mPageContentHeight * pageAspectRatio) + 0.5f); @@ -439,10 +444,17 @@ public final class PageAdapter extends Adapter implements final int rowCount = mSelectedPageCount / columnCount + ((mSelectedPageCount % columnCount) > 0 ? 1 : 0); - final int totalContentHeight = rowCount* (mPageContentHeight + mFooterHeight + 2 + final int totalContentHeight = rowCount * (mPageContentHeight + mFooterHeight + 2 * mPreviewPageMargin); - final int verticalPadding = Math.max(mPreviewListPadding, - (availableHeight - totalContentHeight) / 2); + + final int verticalPadding; + if (mPageContentHeight + mFooterHeight + mPreviewListPadding > availableHeight) { + verticalPadding = Math.max(mPreviewPageMargin, + (availableHeight - totalContentHeight) / 2); + } else { + verticalPadding = Math.max(mPreviewListPadding, + (availableHeight - totalContentHeight) / 2); + } mPreviewArea.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding); diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java index a1b1aec5003f..6b29e5f2a6b0 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java @@ -1704,7 +1704,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat if (position == 0 && getPdfPrinter() != null) { PrinterHolder printerHolder = (PrinterHolder) getItem(position); title = printerHolder.printer.getName(); - icon = getResources().getDrawable(com.android.internal.R.drawable.ic_menu_save); + icon = getResources().getDrawable(R.drawable.ic_savetopdf); } else if (position == 1) { title = getString(R.string.all_printers); } @@ -1712,7 +1712,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat if (position == 1 && getPdfPrinter() != null) { PrinterHolder printerHolder = (PrinterHolder) getItem(position); title = printerHolder.printer.getName(); - icon = getResources().getDrawable(com.android.internal.R.drawable.ic_menu_save); + icon = getResources().getDrawable(R.drawable.ic_savetopdf); } else if (position == getCount() - 1) { title = getString(R.string.all_printers); } else { diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java index 4d2cb6ce8e29..83653731fba4 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java +++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java @@ -94,7 +94,7 @@ public class PageContentView extends View mMinMargins = minMargins; mContentRequested = false; - // If there is not provider we want immediately to switch to + // If there is no provider we want immediately to switch to // the empty state, so pages with no content appear blank. if (mProvider == null && getBackground() != mEmptyState) { setBackground(mEmptyState); diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PrintOptionsLayout.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PrintOptionsLayout.java index 01f4a044e153..71f4aa71d9c2 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/widget/PrintOptionsLayout.java +++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PrintOptionsLayout.java @@ -162,7 +162,7 @@ public final class PrintOptionsLayout extends ViewGroup { } cellStart = getPaddingStart(); - cellTop += cellTop + rowHeight; + cellTop += rowHeight; } } diff --git a/packages/SystemUI/res/drawable/trust_circle.xml b/packages/SystemUI/res/drawable/trust_circle.xml index 89f4a0b89e5a..56fc62ec89e7 100644 --- a/packages/SystemUI/res/drawable/trust_circle.xml +++ b/packages/SystemUI/res/drawable/trust_circle.xml @@ -17,6 +17,6 @@ --> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="ring" - android:innerRadius="24dp" android:thickness="1dp"> - <solid android:color="#66ffffff" /> + android:innerRadius="22dp" android:thickness="2dp"> + <solid android:color="#4cffffff" /> </shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml index fc6e9aeff8df..8e9b50197044 100644 --- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml +++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml @@ -27,7 +27,7 @@ android:id="@+id/keyguard_indication_text" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginBottom="70dp" + android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom" android:layout_gravity="bottom|center_horizontal" android:textStyle="italic" android:textColor="#ffffff" diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml index d4b121459df0..fcc0f4aaf459 100644 --- a/packages/SystemUI/res/layout/keyguard_status_bar.xml +++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml @@ -60,7 +60,7 @@ android:paddingEnd="@dimen/battery_level_padding_end" android:textColor="#ffffff" android:visibility="gone" - android:textSize="12sp"/> + android:textSize="@dimen/battery_level_text_size"/> </LinearLayout> <com.android.keyguard.CarrierText diff --git a/packages/SystemUI/res/layout/qs_detail_header.xml b/packages/SystemUI/res/layout/qs_detail_header.xml index fcbb32cd7b1d..f3f1918e3a0a 100644 --- a/packages/SystemUI/res/layout/qs_detail_header.xml +++ b/packages/SystemUI/res/layout/qs_detail_header.xml @@ -15,7 +15,10 @@ limitations under the License. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - style="@style/BrightnessDialogContainer" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:padding="@dimen/qs_panel_padding" android:background="@drawable/btn_borderless_rect" > <TextView diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml index 6cfff2e3670f..828065be866e 100644 --- a/packages/SystemUI/res/layout/recents_task_view.xml +++ b/packages/SystemUI/res/layout/recents_task_view.xml @@ -17,7 +17,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:focusable="true"> + android:focusable="true" + android:background="#FFffffff"> <com.android.systemui.recents.views.TaskViewThumbnail android:id="@+id/task_view_thumbnail" android:layout_width="match_parent" diff --git a/packages/SystemUI/res/layout/split_clock_view.xml b/packages/SystemUI/res/layout/split_clock_view.xml index d9ba35d26336..87b70516a463 100644 --- a/packages/SystemUI/res/layout/split_clock_view.xml +++ b/packages/SystemUI/res/layout/split_clock_view.xml @@ -34,5 +34,15 @@ android:layout_height="wrap_content" android:singleLine="true" android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock" + android:textSize="@dimen/qs_time_collapsed_size" + /> + + <!-- Empty text view so we have the same height when expanded/collapsed--> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="invisible" + android:singleLine="true" + android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock" /> </com.android.systemui.statusbar.policy.SplitClockView>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 4eab9c73a42b..cc449c58cb42 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -50,6 +50,10 @@ android:visibility="gone" /> + <include + layout="@layout/keyguard_bottom_area" + android:visibility="gone" /> + <com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer android:layout_width="match_parent" android:layout_height="match_parent" @@ -115,10 +119,6 @@ <include layout="@layout/status_bar_expanded_header" /> - <include - layout="@layout/keyguard_bottom_area" - android:visibility="gone" /> - <com.android.systemui.statusbar.AlphaOptimizedView android:id="@+id/qs_navbar_scrim" android:layout_height="96dp" diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml index 21d8457850f2..1226fc5ed2a7 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml @@ -51,7 +51,7 @@ android:layout_height="@dimen/status_bar_header_height" android:background="@drawable/ripple_drawable" android:src="@drawable/ic_settings" - android:contentDescription="@string/accessibility_desc_quick_settings"/> + android:contentDescription="@string/accessibility_desc_settings"/> <LinearLayout android:id="@+id/system_icons_super_container" android:layout_width="wrap_content" @@ -72,7 +72,7 @@ android:layout_marginStart="@dimen/header_battery_margin_expanded" android:paddingEnd="@dimen/battery_level_padding_end" android:textColor="#ffffff" - android:textSize="12sp"/> + android:textSize="@dimen/battery_level_text_size"/> </LinearLayout> <TextView diff --git a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml index 062e6cb0334a..a5bf68e286a4 100644 --- a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml +++ b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml @@ -45,6 +45,7 @@ android:paddingBottom="16dp" android:thumb="@drawable/ic_brightness_thumb" android:splitTrack="false" + android:contentDescription="@string/accessibility_brightness" /> <TextView android:id="@+id/label" diff --git a/packages/SystemUI/res/values-h560dp-xhdpi/config.xml b/packages/SystemUI/res/values-h560dp-xhdpi/config.xml new file mode 100644 index 000000000000..cf2017f1eb6f --- /dev/null +++ b/packages/SystemUI/res/values-h560dp-xhdpi/config.xml @@ -0,0 +1,23 @@ +<?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 + --> +<resources> + <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow + card. --> + <integer name="keyguard_max_notification_count">3</integer> +</resources> + diff --git a/packages/SystemUI/res/values-h560dp-xhdpi/dimens.xml b/packages/SystemUI/res/values-h560dp-xhdpi/dimens.xml new file mode 100644 index 000000000000..f6dbc3de2738 --- /dev/null +++ b/packages/SystemUI/res/values-h560dp-xhdpi/dimens.xml @@ -0,0 +1,21 @@ +<?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 + --> + +<resources> + <fraction name="keyguard_clock_y_fraction_max">32.5%</fraction> + <fraction name="keyguard_clock_y_fraction_min">24%</fraction> +</resources>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-h560dp-xxhdpi/config.xml b/packages/SystemUI/res/values-h560dp-xxhdpi/config.xml new file mode 100644 index 000000000000..b2231a6160a9 --- /dev/null +++ b/packages/SystemUI/res/values-h560dp-xxhdpi/config.xml @@ -0,0 +1,22 @@ +<?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 + --> +<resources> + <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow + card. --> + <integer name="keyguard_max_notification_count">4</integer> +</resources> + diff --git a/packages/SystemUI/res/values-h560dp-xxhdpi/dimens.xml b/packages/SystemUI/res/values-h560dp-xxhdpi/dimens.xml new file mode 100644 index 000000000000..905e9e3adb62 --- /dev/null +++ b/packages/SystemUI/res/values-h560dp-xxhdpi/dimens.xml @@ -0,0 +1,21 @@ +<?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 + --> + +<resources> + <fraction name="keyguard_clock_y_fraction_max">32.5%</fraction> + <fraction name="keyguard_clock_y_fraction_min">19.8%</fraction> +</resources>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-land/config.xml b/packages/SystemUI/res/values-land/config.xml index 2b1a4dc94076..d608e25ebeba 100644 --- a/packages/SystemUI/res/values-land/config.xml +++ b/packages/SystemUI/res/values-land/config.xml @@ -29,5 +29,7 @@ <!-- The number of columns that the top level tiles span in the QuickSettings --> <integer name="quick_settings_user_time_settings_tile_span">2</integer> -</resources> + <!-- We have only space for one notification on phone landscape layouts. --> + <integer name="keyguard_max_notification_count">1</integer> +</resources> diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml index 5367fbce1b06..2c22cef95eee 100644 --- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml @@ -27,4 +27,6 @@ <dimen name="keyguard_clock_notifications_margin_min">36dp</dimen> <dimen name="keyguard_clock_notifications_margin_max">36dp</dimen> + + <dimen name="keyguard_indication_margin_bottom">80dp</dimen> </resources> diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index 7cdc078e2aa6..9901e444216f 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -79,4 +79,6 @@ <!-- The width of the region on the left/right edge of the screen for performing the camera/ phone hints. --> <dimen name="edge_tap_area_width">80dp</dimen> + + <dimen name="keyguard_indication_margin_bottom">90dp</dimen> </resources> diff --git a/packages/SystemUI/res/values-sw720dp-land/config.xml b/packages/SystemUI/res/values-sw720dp-land/config.xml new file mode 100644 index 000000000000..1b502886d8da --- /dev/null +++ b/packages/SystemUI/res/values-sw720dp-land/config.xml @@ -0,0 +1,20 @@ +<?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 + --> +<resources> + <integer name="keyguard_max_notification_count">4</integer> +</resources> + diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml index 2532dd63c14d..511d45ffe71d 100644 --- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml +++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml @@ -19,5 +19,5 @@ min value is used when no notifications are displaying, and the max value is when the highest possible number of notifications are showing. --> <fraction name="keyguard_clock_y_fraction_max">35%</fraction> - <fraction name="keyguard_clock_y_fraction_min">20%</fraction> + <fraction name="keyguard_clock_y_fraction_min">24%</fraction> </resources> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 28d7e29d943a..f6280390f9ee 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -157,7 +157,7 @@ <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow card. --> - <integer name="keyguard_max_notification_count">4</integer> + <integer name="keyguard_max_notification_count">3</integer> <!-- Defines the implementation of the velocity tracker to be used for the panel expansion. Can be 'platform' or 'noisy' (i.e. for noisy touch screens). --> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 3db0a2bd0d07..5415d196c171 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -222,6 +222,9 @@ <!-- The amount to offset when animating into an affiliate group. --> <dimen name="recents_task_view_affiliate_group_enter_offset">64dp</dimen> + <!-- The alpha to apply to a task thumbnail. --> + <item name="recents_task_view_thumbnail_alpha" format="float" type="dimen">0.9</item> + <!-- The height of a task view bar. --> <dimen name="recents_task_bar_height">56dp</dimen> @@ -320,7 +323,7 @@ <dimen name="volume_panel_z">3dp</dimen> <!-- Distance between notifications and header when they are considered to be colliding. --> - <dimen name="header_notifications_collide_distance">24dp</dimen> + <dimen name="header_notifications_collide_distance">48dp</dimen> <!-- Distance the user needs to drag vertically such that a swipe is accepted to unlock the device. --> @@ -422,4 +425,9 @@ <!-- The width/height of the phone/camera/unlock icon on keyguard. --> <dimen name="keyguard_affordance_height">56dp</dimen> <dimen name="keyguard_affordance_width">56dp</dimen> + + <dimen name="keyguard_indication_margin_bottom">65dp</dimen> + + <!-- The text size for battery level --> + <dimen name="battery_level_text_size">12sp</dimen> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 72886c6065f6..c24fcae74ead 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -390,6 +390,8 @@ <string name="accessibility_desc_notification_shade">Notification shade.</string> <!-- Content description for the quick settings panel (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_desc_quick_settings">Quick settings.</string> + <!-- Content description for the settings button in the status bar header. [CHAR LIMIT=NONE] --> + <string name="accessibility_desc_settings">Settings</string> <!-- Content description for the recent apps panel (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_desc_recent_apps">Recent screens.</string> @@ -416,6 +418,9 @@ <!-- Content description of zen mode time condition minus button (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_quick_settings_less_time">Less time</string> + <!-- Content description of the display brightness slider (not shown on the screen). [CHAR LIMIT=NONE] --> + <string name="accessibility_brightness">Display brightness</string> + <!-- Title of dialog shown when 2G-3G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] --> <string name="data_usage_disabled_dialog_3g_title">2G-3G data is off</string> <!-- Title of dialog shown when 4G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] --> @@ -643,7 +648,7 @@ <string name="speed_bump_explanation">Less urgent notifications below</string> <!-- Shows to explain the double tap interaction with notifications: After tapping a notification on Keyguard, this will explain users to tap again to launch a notification. [CHAR LIMIT=60] --> - <string name="notification_tap_again">Tap again to open</string> + <string name="notification_tap_again">Touch again to open</string> <!-- Shows when people have pressed the unlock icon to explain how to unlock. [CHAR LIMIT=60] --> <string name="keyguard_unlock">Swipe up to unlock</string> @@ -673,6 +678,12 @@ <!-- Related to user switcher --><skip/> + <!-- Accessibility label for the button that opens the user switcher. --> + <string name="accessibility_multi_user_switch_switcher">Switch user</string> + + <!-- Accessibility label for the button that opens the quick contact of the user. --> + <string name="accessibility_multi_user_switch_quick_contact">Show profile</string> + <!-- Label for the adding a new user in the user switcher [CHAR LIMIT=35] --> <string name="user_add_user">Add user</string> @@ -685,8 +696,8 @@ <!-- Label for adding a new guest in the user switcher [CHAR LIMIT=35] --> <string name="guest_new_guest">Add guest</string> - <!-- Label for exiting guest session in the user switcher [CHAR LIMIT=35] --> - <string name="guest_exit_guest">Exit guest</string> + <!-- Label for exiting and removing the guest session in the user switcher [CHAR LIMIT=35] --> + <string name="guest_exit_guest">Remove guest</string> <!-- Title of the confirmation dialog when exiting guest session [CHAR LIMIT=NONE] --> <string name="guest_exit_guest_dialog_title">Exiting guest session?</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 0d3a48707271..27e58a47ab70 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -108,49 +108,6 @@ <style name="TextAppearance.StatusBar.Expanded.UserSwitcher.UserName" /> <style name="TextAppearance" /> - <style name="TextAppearance.QuickSettings" /> - - <style name="TextAppearance.QuickSettings.TileView"> - <item name="android:textSize">12dp</item> - <item name="android:textStyle">normal</item> - <item name="android:textColor">#CCCCCC</item> - <item name="android:textAllCaps">true</item> - <item name="android:paddingStart">6dp</item> - <item name="android:paddingEnd">6dp</item> - </style> - - <style name="TextAppearance.QuickSettings.TileView.AllInOne" parent="@style/TextAppearance.QuickSettings.TileView"> - <item name="android:lines">2</item> - <item name="android:gravity">top</item> - <item name="android:paddingBottom">2dp</item> - <item name="android:paddingTop">16dp</item> - <item name="android:drawablePadding">8dp</item> - </style> - - <style name="TextAppearance.QuickSettings.Clock" parent="@style/TextAppearance.QuickSettings.TileView"> - <item name="android:textSize">20dp</item> - <item name="android:textColor">@android:color/holo_blue_light</item> - </style> - - <style name="TextAppearance.QuickSettings.Date" parent="@style/TextAppearance.QuickSettings.TileView"> - <item name="android:textSize">14dp</item> - </style> - - <style name="TextAppearance.QuickSettings.Alarm" parent="@style/TextAppearance.QuickSettings.TileView"> - <item name="android:textSize">14dp</item> - <item name="android:textColor">#ff3a3b39</item> - </style> - - <style name="TextAppearance.QuickSettings.CaCertWarning" parent="@style/TextAppearance.QuickSettings.TileView"> - <item name="android:textAllCaps">false</item> - </style> - - <style name="TextAppearance.QuickSettings.TileView.User" parent="@style/TextAppearance.QuickSettings.TileView"> - <item name="android:background">#CC000000</item> - <item name="android:padding">4dp</item> - <item name="android:singleLine">true</item> - <item name="android:fadingEdge">horizontal</item> - </style> <style name="TextAppearance.QS"> <item name="android:textStyle">normal</item> @@ -211,7 +168,6 @@ <style name="BaseBrightnessDialogContainer"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> - <item name="android:layout_alignParentBottom">true</item> </style> <style name="BrightnessDialogContainer" parent="@style/BaseBrightnessDialogContainer" /> diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index b280ab7ba8df..ee699d25ef1a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -208,6 +208,12 @@ public class KeyguardService extends Service { checkPermission(); mKeyguardViewMediator.startKeyguardExitAnimation(startTime, fadeoutDuration); } + + @Override + public void onActivityDrawn() { + checkPermission(); + mKeyguardViewMediator.onActivityDrawn(); + } }; } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 117515b24308..be1122059635 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -133,6 +133,7 @@ public class KeyguardViewMediator extends SystemUI { private static final int KEYGUARD_TIMEOUT = 13; private static final int DISMISS = 17; private static final int START_KEYGUARD_EXIT_ANIM = 18; + private static final int ON_ACTIVITY_DRAWN = 19; /** * The default amount of time we stay awake (used for all key input) @@ -256,6 +257,7 @@ public class KeyguardViewMediator extends SystemUI { private boolean mWaitingUntilKeyguardVisible = false; private LockPatternUtils mLockPatternUtils; private boolean mKeyguardDonePending = false; + private boolean mHideAnimationRun = false; private SoundPool mLockSounds; private int mLockSoundId; @@ -287,6 +289,7 @@ public class KeyguardViewMediator extends SystemUI { // ActivityManagerService) will not reconstruct the keyguard if it is already showing. synchronized (KeyguardViewMediator.this) { mSwitchingUser = true; + mKeyguardDonePending = false; resetStateLocked(); adjustStatusBarLocked(); // When we switch users we want to bring the new user to the biometric unlock even @@ -431,12 +434,23 @@ public class KeyguardViewMediator extends SystemUI { @Override public void keyguardDonePending() { mKeyguardDonePending = true; + mHideAnimationRun = true; + mStatusBarKeyguardViewManager.startPreHideAnimation(null /* finishRunnable */); } @Override public void keyguardGone() { mKeyguardDisplayManager.hide(); } + + @Override + public void readyForKeyguardDone() { + if (mKeyguardDonePending) { + // Somebody has called keyguardDonePending before, which means that we are + // authenticated + KeyguardViewMediator.this.keyguardDone(true /* authenticated */, true /* wakeUp */); + } + } }; public void userActivity() { @@ -545,6 +559,7 @@ public class KeyguardViewMediator extends SystemUI { if (DEBUG) Log.d(TAG, "onScreenTurnedOff(" + why + ")"); mKeyguardDonePending = false; + mHideAnimationRun = false; // 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 @@ -1067,6 +1082,9 @@ public class KeyguardViewMediator extends SystemUI { StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj; handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration); break; + case ON_ACTIVITY_DRAWN: + handleOnActivityDrawn(); + break; } } }; @@ -1181,6 +1199,7 @@ public class KeyguardViewMediator extends SystemUI { mHiding = false; mShowing = true; mKeyguardDonePending = false; + mHideAnimationRun = false; updateActivityLockScreenState(); adjustStatusBarLocked(); userActivity(); @@ -1193,6 +1212,22 @@ public class KeyguardViewMediator extends SystemUI { mKeyguardDisplayManager.show(); } + private final Runnable mKeyguardGoingAwayRunnable = new Runnable() { + @Override + public void run() { + try { + // Don't actually hide the Keyguard at the moment, wait for window + // manager until it tells us it's safe to do so with + // startKeyguardExitAnimation. + mWM.keyguardGoingAway( + mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock(), + mStatusBarKeyguardViewManager.isGoingToNotificationShade()); + } catch (RemoteException e) { + Log.e(TAG, "Error while calling WindowManager", e); + } + } + }; + /** * Handle message sent by {@link #hideLocked()} * @see #HIDE @@ -1203,19 +1238,11 @@ public class KeyguardViewMediator extends SystemUI { mHiding = true; if (mShowing && !mOccluded) { - mStatusBarKeyguardViewManager.startPreHideAnimation(new Runnable() { - @Override - public void run() { - try { - // Don't actually hide the Keyguard at the moment, wait for window - // manager until it tells us it's safe to do so with - // startKeyguardExitAnimation. - mWM.keyguardGoingAway(); - } catch (RemoteException e) { - Log.e(TAG, "Error while calling WindowManager", e); - } - } - }); + if (!mHideAnimationRun) { + mStatusBarKeyguardViewManager.startPreHideAnimation(mKeyguardGoingAwayRunnable); + } else { + mKeyguardGoingAwayRunnable.run(); + } } else { // Don't try to rely on WindowManager - if Keyguard wasn't showing, window @@ -1227,6 +1254,12 @@ public class KeyguardViewMediator extends SystemUI { } } + private void handleOnActivityDrawn() { + if (mKeyguardDonePending) { + mStatusBarKeyguardViewManager.onActivityDrawn(); + } + } + private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration) { synchronized (KeyguardViewMediator.this) { @@ -1244,6 +1277,7 @@ public class KeyguardViewMediator extends SystemUI { mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration); mShowing = false; mKeyguardDonePending = false; + mHideAnimationRun = false; updateActivityLockScreenState(); adjustStatusBarLocked(); } @@ -1357,6 +1391,9 @@ public class KeyguardViewMediator extends SystemUI { mHandler.sendMessage(msg); } + public void onActivityDrawn() { + mHandler.sendEmptyMessage(ON_ACTIVITY_DRAWN); + } public ViewMediatorCallback getViewMediatorCallback() { return mViewMediatorCallback; } diff --git a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java index f8b347c6c5ec..803a01410b9f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java +++ b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java @@ -17,6 +17,7 @@ package com.android.systemui.media; import android.content.Context; +import android.media.AudioAttributes; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; @@ -45,11 +46,11 @@ public class NotificationPlayer implements OnCompletionListener { Context context; Uri uri; boolean looping; - int stream; + AudioAttributes attributes; long requestTime; public String toString() { - return "{ code=" + code + " looping=" + looping + " stream=" + stream + return "{ code=" + code + " looping=" + looping + " attributes=" + attributes + " uri=" + uri + " }"; } } @@ -79,7 +80,7 @@ public class NotificationPlayer implements OnCompletionListener { (AudioManager) mCmd.context.getSystemService(Context.AUDIO_SERVICE); try { MediaPlayer player = new MediaPlayer(); - player.setAudioStreamType(mCmd.stream); + player.setAudioAttributes(mCmd.attributes); player.setDataSource(mCmd.context, mCmd.uri); player.setLooping(mCmd.looping); player.prepare(); @@ -90,10 +91,12 @@ public class NotificationPlayer implements OnCompletionListener { if (mAudioManagerWithAudioFocus == null) { if (mDebug) Log.d(mTag, "requesting AudioFocus"); if (mCmd.looping) { - audioManager.requestAudioFocus(null, mCmd.stream, + audioManager.requestAudioFocus(null, + AudioAttributes.toLegacyStreamType(mCmd.attributes), AudioManager.AUDIOFOCUS_GAIN); } else { - audioManager.requestAudioFocus(null, mCmd.stream, + audioManager.requestAudioFocus(null, + AudioAttributes.toLegacyStreamType(mCmd.attributes), AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); } mAudioManagerWithAudioFocus = audioManager; @@ -280,7 +283,9 @@ public class NotificationPlayer implements OnCompletionListener { * (see {@link MediaPlayer#setLooping(boolean)}) * @param stream the AudioStream to use. * (see {@link MediaPlayer#setAudioStreamType(int)}) + * @deprecated use {@link #play(Context, Uri, boolean, AudioAttributes)} instead. */ + @Deprecated public void play(Context context, Uri uri, boolean looping, int stream) { Command cmd = new Command(); cmd.requestTime = SystemClock.uptimeMillis(); @@ -288,7 +293,34 @@ public class NotificationPlayer implements OnCompletionListener { cmd.context = context; cmd.uri = uri; cmd.looping = looping; - cmd.stream = stream; + cmd.attributes = new AudioAttributes.Builder().setInternalLegacyStreamType(stream).build(); + synchronized (mCmdQueue) { + enqueueLocked(cmd); + mState = PLAY; + } + } + + /** + * Start playing the sound. It will actually start playing at some + * point in the future. There are no guarantees about latency here. + * Calling this before another audio file is done playing will stop + * that one and start the new one. + * + * @param context Your application's context. + * @param uri The URI to play. (see {@link MediaPlayer#setDataSource(Context, Uri)}) + * @param looping Whether the audio should loop forever. + * (see {@link MediaPlayer#setLooping(boolean)}) + * @param attributes the AudioAttributes to use. + * (see {@link MediaPlayer#setAudioAttributes(AudioAttributes)}) + */ + public void play(Context context, Uri uri, boolean looping, AudioAttributes attributes) { + Command cmd = new Command(); + cmd.requestTime = SystemClock.uptimeMillis(); + cmd.code = PLAY; + cmd.context = context; + cmd.uri = uri; + cmd.looping = looping; + cmd.attributes = attributes; synchronized (mCmdQueue) { enqueueLocked(cmd); mState = PLAY; diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java index 5b4bb2c8b57c..7eed7f25715c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java +++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java @@ -18,6 +18,7 @@ package com.android.systemui.media; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; +import android.media.AudioAttributes; import android.media.IAudioService; import android.media.IRingtonePlayer; import android.media.Ringtone; @@ -71,11 +72,11 @@ public class RingtonePlayer extends SystemUI { private final IBinder mToken; private final Ringtone mRingtone; - public Client(IBinder token, Uri uri, UserHandle user, int streamType) { + public Client(IBinder token, Uri uri, UserHandle user, AudioAttributes aa) { mToken = token; mRingtone = new Ringtone(getContextForUser(user), false); - mRingtone.setStreamType(streamType); + mRingtone.setAudioAttributes(aa); mRingtone.setUri(uri); } @@ -91,7 +92,7 @@ public class RingtonePlayer extends SystemUI { private IRingtonePlayer mCallback = new IRingtonePlayer.Stub() { @Override - public void play(IBinder token, Uri uri, int streamType) throws RemoteException { + public void play(IBinder token, Uri uri, AudioAttributes aa) throws RemoteException { if (LOGD) { Log.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid=" + Binder.getCallingUid() + ")"); @@ -101,7 +102,7 @@ public class RingtonePlayer extends SystemUI { client = mClients.get(token); if (client == null) { final UserHandle user = Binder.getCallingUserHandle(); - client = new Client(token, uri, user, streamType); + client = new Client(token, uri, user, aa); token.linkToDeath(client, 0); mClients.put(token, client); } @@ -137,13 +138,13 @@ public class RingtonePlayer extends SystemUI { } @Override - public void playAsync(Uri uri, UserHandle user, boolean looping, int streamType) { + public void playAsync(Uri uri, UserHandle user, boolean looping, AudioAttributes aa) { if (LOGD) Log.d(TAG, "playAsync(uri=" + uri + ", user=" + user + ")"); if (Binder.getCallingUid() != Process.SYSTEM_UID) { throw new SecurityException("Async playback only available from system UID."); } - mAsyncPlayer.play(getContextForUser(user), uri, looping, streamType); + mAsyncPlayer.play(getContextForUser(user), uri, looping, aa); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java index 79fadbdb675a..8420dc0cb553 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java @@ -16,7 +16,6 @@ package com.android.systemui.power; -import android.app.ActivityManagerNative; import android.app.AlertDialog; import android.content.ContentResolver; import android.content.Context; @@ -26,15 +25,14 @@ import android.media.AudioManager; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; -import android.os.RemoteException; import android.os.SystemClock; -import android.os.UserHandle; import android.provider.Settings; import android.util.Slog; import android.view.ContextThemeWrapper; import android.view.WindowManager; import com.android.systemui.R; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import java.io.PrintWriter; @@ -43,6 +41,7 @@ public class PowerDialogWarnings implements PowerUI.WarningsUI { private static final boolean DEBUG = PowerUI.DEBUG; private final Context mContext; + private final PhoneStatusBar mPhoneStatusBar; private int mBatteryLevel; private int mBucket; @@ -52,8 +51,9 @@ public class PowerDialogWarnings implements PowerUI.WarningsUI { private AlertDialog mInvalidChargerDialog; private AlertDialog mLowBatteryDialog; - public PowerDialogWarnings(Context context) { + public PowerDialogWarnings(Context context, PhoneStatusBar phoneStatusBar) { mContext = new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light); + mPhoneStatusBar = phoneStatusBar; } @Override @@ -121,12 +121,7 @@ public class PowerDialogWarnings implements PowerUI.WarningsUI { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - try { - ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); - } catch (RemoteException e) { - // we tried - } - mContext.startActivityAsUser(intent, UserHandle.CURRENT); + mPhoneStatusBar.startActivity(intent, true /* dismissShade */); dismissLowBatteryWarning(); } }); diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java index dd923e3bc835..d455cec9886a 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java @@ -38,6 +38,7 @@ import android.util.Slog; import android.view.View; import com.android.systemui.R; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.phone.SystemUIDialog; import java.io.PrintWriter; @@ -93,10 +94,10 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { private boolean mInvalidCharger; private SystemUIDialog mSaverConfirmation; - public PowerNotificationWarnings(Context context) { + public PowerNotificationWarnings(Context context, PhoneStatusBar phoneStatusBar) { mContext = context; mNoMan = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - mFallbackDialogs = new PowerDialogWarnings(context); + mFallbackDialogs = new PowerDialogWarnings(context, phoneStatusBar); mReceiver.init(); } diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java index ccef8eb543ee..d3c7dee9e5bb 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java @@ -32,6 +32,7 @@ import android.util.Log; import android.util.Slog; import com.android.systemui.SystemUI; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -59,7 +60,7 @@ public class PowerUI extends SystemUI { public void start() { mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime(); - mWarnings = new PowerNotificationWarnings(mContext); + mWarnings = new PowerNotificationWarnings(mContext, getComponent(PhoneStatusBar.class)); ContentObserver obs = new ContentObserver(mHandler) { @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java index 1a555f1e435d..1df3d20a1765 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java @@ -89,11 +89,9 @@ public final class SignalTileView extends QSTileView { protected void handleStateChanged(QSTile.State state) { super.handleStateChanged(state); final SignalState s = (SignalState) state; - mSignal.setImageDrawable(null); // force refresh mSignal.setImageResource(s.iconId); if (s.overlayIconId > 0) { mOverlay.setVisibility(VISIBLE); - mOverlay.setImageDrawable(null); // force refresh mOverlay.setImageResource(s.overlayIconId); } else { mOverlay.setVisibility(GONE); diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java index 3d4d6c43a668..3709c4364184 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java @@ -39,6 +39,8 @@ public class Constants { public static final boolean EnableSearchLayout = true; // Enables the dynamic shadows behind each task public static final boolean EnableShadows = true; + // Enables the thumbnail alpha on the front-most task + public static final boolean EnableThumbnailAlphaOnFrontmost = false; // This disables the bitmap and icon caches public static final boolean DisableBackgroundCache = false; // Enables the simulated task affiliations diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index 41e06de80112..7fafe7aa28d1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -385,7 +385,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView // Private API calls to make the shadows look better try { Utilities.setShadowProperty("ambientShadowStrength", String.valueOf(35f)); - Utilities.setShadowProperty("ambientRatio", String.valueOf(0.5f)); + Utilities.setShadowProperty("ambientRatio", String.valueOf(1.5f)); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java index 3f5018d8290b..b7f6451e3ce2 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java @@ -81,6 +81,7 @@ public class RecentsConfiguration { public int taskViewRoundedCornerRadiusPx; public int taskViewHighlightPx; public int taskViewAffiliateGroupEnterOffsetPx; + public float taskViewThumbnailAlpha; /** Task bar colors */ public int taskBarViewDefaultBackgroundColor; @@ -217,6 +218,9 @@ public class RecentsConfiguration { taskViewTranslationZMaxPx = res.getDimensionPixelSize(R.dimen.recents_task_view_z_max); taskViewAffiliateGroupEnterOffsetPx = res.getDimensionPixelSize(R.dimen.recents_task_view_affiliate_group_enter_offset); + TypedValue thumbnailAlphaValue = new TypedValue(); + res.getValue(R.dimen.recents_task_view_thumbnail_alpha, thumbnailAlphaValue, true); + taskViewThumbnailAlpha = thumbnailAlphaValue.getFloat(); // Task bar colors taskBarViewDefaultBackgroundColor = diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java b/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java index 4c0ff481a289..c87a901341d1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/ReferenceCountedTrigger.java @@ -16,6 +16,8 @@ package com.android.systemui.recents.misc; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.content.Context; import java.util.ArrayList; @@ -98,10 +100,19 @@ public class ReferenceCountedTrigger { } } - /** Convenience method to decrement this trigger as a runnable */ + /** Convenience method to decrement this trigger as a runnable. */ public Runnable decrementAsRunnable() { return mDecrementRunnable; } + /** Convenience method to decrement this trigger as a animator listener. */ + public Animator.AnimatorListener decrementOnAnimationEnd() { + return new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + decrement(); + } + }; + } /** Returns the current ref count */ public int getCount() { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 4fd91366e308..aee558f88f65 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -73,6 +73,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal boolean mStackViewsDirty = true; boolean mAwaitingFirstLayout = true; boolean mStartEnterAnimationRequestedAfterLayout; + boolean mStartEnterAnimationCompleted; ViewAnimation.TaskViewEnterContext mStartEnterAnimationContext; int[] mTmpVisibleRange = new int[2]; TaskViewTransform mTmpTransform = new TaskViewTransform(); @@ -394,7 +395,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // Scroll the view into position (just center it in the curve) if (scrollToNewPosition) { - float newScroll = mLayoutAlgorithm.getStackScrollForTaskIndex(t) - 0.5f; + float newScroll = mLayoutAlgorithm.getStackScrollForTask(t) - 0.5f; newScroll = mStackScroller.getBoundedStackScroll(newScroll); mStackScroller.animateScroll(mStackScroller.getStackScroll(), newScroll, postScrollRunnable); } else { @@ -609,6 +610,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal ctx.postAnimationTrigger.addLastDecrementRunnable(new Runnable() { @Override public void run() { + mStartEnterAnimationCompleted = true; // Start dozing mUIDozeTrigger.startDozing(); } @@ -679,8 +681,28 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // Notify the callback that we've removed the task and it can clean up after it mCb.onTaskViewDismissed(removedTask); + // Get the stack scroll of the task to anchor to (since we are removing something, the front + // most task will be our anchor task) + Task anchorTask = null; + float prevAnchorTaskScroll = 0; + boolean pullStackForward = stack.getTaskCount() > 0; + if (pullStackForward) { + anchorTask = mStack.getFrontMostTask(); + prevAnchorTaskScroll = mLayoutAlgorithm.getStackScrollForTask(anchorTask); + } + // Update the min/max scroll and animate other task views into their new positions updateMinMaxScroll(true, mConfig.launchedWithAltTab, mConfig.launchedFromHome); + + // Offset the stack by as much as the anchor task would otherwise move back + if (pullStackForward) { + float anchorTaskScroll = mLayoutAlgorithm.getStackScrollForTask(anchorTask); + mStackScroller.setStackScroll(mStackScroller.getStackScroll() + (anchorTaskScroll + - prevAnchorTaskScroll)); + mStackScroller.boundScroll(); + } + + // Animate all the tasks into place requestSynchronizeStackViewsWithModel(200); // Update the new front most task @@ -814,6 +836,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal tv.setNoUserInteractionState(); } + // If we've finished the start animation, then ensure we always enable the focus animations + if (mStartEnterAnimationCompleted) { + tv.enableFocusAnimations(); + } + // Find the index where this task should be placed in the stack int insertIndex = -1; int taskIndex = mStack.indexOfTask(task); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java index 495d00b1fa31..667faa7dfbc9 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java @@ -202,7 +202,7 @@ public class TaskStackViewLayoutAlgorithm { /** * Returns the scroll to such task top = 1f; */ - float getStackScrollForTaskIndex(Task t) { + float getStackScrollForTask(Task t) { return mTaskProgressMap.get(t.key); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 236229e6984d..5914b392e671 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -17,7 +17,6 @@ package com.android.systemui.recents.views; import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; @@ -55,6 +54,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, float mTaskProgress; ObjectAnimator mTaskProgressAnimator; + ObjectAnimator mDimAnimator; float mMaxDimScale; int mDim; AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator(1.25f); @@ -222,6 +222,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, * first layout because the actual animation into recents may take a long time. */ void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask, boolean occludesLaunchTarget, int offscreenY) { + int initialDim = getDim(); if (mConfig.launchedFromAppWithScreenshot) { if (isTaskViewLaunchTargetTask) { mHeaderView.prepareEnterRecentsAnimation(); @@ -240,7 +241,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, // Hide the action button if it exists mActionButtonView.setAlpha(0f); // Set the dim to 0 so we can animate it in - setDim(0); + initialDim = 0; } else if (occludesLaunchTarget) { // Move the task view off screen (below) so we can animate it in setTranslationY(offscreenY); @@ -255,6 +256,10 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, setScaleX(1f); setScaleY(1f); } + // Apply the current dim + setDim(initialDim); + // Prepare the thumbnail view alpha + mThumbnailView.prepareEnterRecentsAnimation(isTaskViewLaunchTargetTask); } /** Animates this task view as it enters recents */ @@ -340,20 +345,24 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, // Animate the task bar of the first task view mHeaderView.startEnterRecentsAnimation(mConfig.taskBarEnterAnimDelay, mThumbnailView.enableTaskBarClipAsRunnable(mHeaderView)); - - // Animate the dim into view as well - ObjectAnimator anim = ObjectAnimator.ofInt(this, "dim", getDimFromTaskProgress()); - anim.setStartDelay(mConfig.taskBarEnterAnimDelay); - anim.setDuration(mConfig.taskBarEnterAnimDuration); - anim.setInterpolator(mConfig.fastOutLinearInInterpolator); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - // Decrement the post animation trigger - ctx.postAnimationTrigger.decrement(); - } - }); - anim.start(); + // Animate the dim/overlay + if (Constants.DebugFlags.App.EnableThumbnailAlphaOnFrontmost) { + // Animate the thumbnail alpha before the dim animation (to prevent updating the + // hardware layer) + mThumbnailView.startEnterRecentsAnimation(mConfig.taskBarEnterAnimDelay, + new Runnable() { + @Override + public void run() { + animateDimToProgress(0, mConfig.taskBarEnterAnimDuration, + ctx.postAnimationTrigger.decrementOnAnimationEnd()); + } + }); + } else { + // Immediately start the dim animation + animateDimToProgress(mConfig.taskBarEnterAnimDelay, + mConfig.taskBarEnterAnimDuration, + ctx.postAnimationTrigger.decrementOnAnimationEnd()); + } ctx.postAnimationTrigger.increment(); // Animate the footer into view @@ -459,8 +468,10 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, void startLaunchTaskAnimation(final Runnable r, boolean isLaunchingTask, boolean occludesLaunchTarget) { if (isLaunchingTask) { - // Disable the thumbnail clip and animate the bar out + // Disable the thumbnail clip and animate the bar out for the window animation out mHeaderView.startLaunchTaskAnimation(mThumbnailView.disableTaskBarClipAsRunnable(), r); + // Animate the thumbnail alpha back into full opacity for the window animation out + mThumbnailView.startLaunchTaskAnimation(); // Animate the dim if (mDim > 0) { @@ -612,10 +623,18 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, /** Returns the current dim. */ public void setDim(int dim) { mDim = dim; - int inverse = 255 - mDim; - mDimColorFilter.setColor(Color.argb(0xFF, inverse, inverse, inverse)); - mLayerPaint.setColorFilter(mDimColorFilter); - setLayerType(LAYER_TYPE_HARDWARE, mLayerPaint); + // Defer setting hardware layers if we have not yet measured, or there is no dim to draw + if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0 && dim > 0) { + if (mDimAnimator != null) { + mDimAnimator.removeAllListeners(); + mDimAnimator.cancel(); + } + + int inverse = 255 - mDim; + mDimColorFilter.setColor(Color.argb(0xFF, inverse, inverse, inverse)); + mLayerPaint.setColorFilter(mDimColorFilter); + setLayerType(LAYER_TYPE_HARDWARE, mLayerPaint); + } } /** Returns the current dim. */ @@ -623,6 +642,21 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, return mDim; } + /** Animates the dim to the task progress. */ + void animateDimToProgress(int delay, int duration, Animator.AnimatorListener postAnimRunnable) { + // Animate the dim into view as well + int toDim = getDimFromTaskProgress(); + if (toDim != getDim()) { + ObjectAnimator anim = ObjectAnimator.ofInt(TaskView.this, "dim", toDim); + anim.setStartDelay(delay); + anim.setDuration(duration); + if (postAnimRunnable != null) { + anim.addListener(postAnimRunnable); + } + anim.start(); + } + } + /** Compute the dim as a function of the scale of this view. */ int getDimFromTaskProgress() { float dim = mMaxDimScale * mDimInterpolator.getInterpolation(1f - mTaskProgress); @@ -647,6 +681,8 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, // Focus the header bar mHeaderView.onTaskViewFocusChanged(true); } + // Update the thumbnail alpha with the focus + mThumbnailView.onFocusChanged(true); // Call the callback mCb.onTaskViewFocusChanged(this, true); // Workaround, we don't always want it focusable in touch mode, but we want the first task @@ -670,6 +706,8 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, // Un-focus the header bar mHeaderView.onTaskViewFocusChanged(false); } + // Update the thumbnail alpha with the focus + mThumbnailView.onFocusChanged(false); // Call the callback mCb.onTaskViewFocusChanged(this, false); invalidate(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java index f836aa3e578b..f223bf3a990f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java @@ -21,12 +21,15 @@ import android.graphics.Bitmap; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; +import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.model.Task; /** The task thumbnail view */ public class TaskViewThumbnail extends FixedSizeImageView { + RecentsConfiguration mConfig; + // Task bar clipping Rect mClipRect = new Rect(); @@ -44,9 +47,15 @@ public class TaskViewThumbnail extends FixedSizeImageView { public TaskViewThumbnail(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); + mConfig = RecentsConfiguration.getInstance(); setScaleType(ScaleType.FIT_XY); } + @Override + protected void onFinishInflate() { + setAlpha(0.9f); + } + /** Updates the clip rect based on the given task bar. */ void enableTaskBarClip(View taskBar) { int top = (int) Math.max(0, taskBar.getTranslationY() + @@ -101,4 +110,51 @@ public class TaskViewThumbnail extends FixedSizeImageView { void unbindFromTask() { setImageDrawable(null); } + + /** Handles focus changes. */ + void onFocusChanged(boolean focused) { + if (focused) { + if (Float.compare(getAlpha(), 1f) != 0) { + startFadeAnimation(1f, 0, 150, null); + } + } else { + if (Float.compare(getAlpha(), mConfig.taskViewThumbnailAlpha) != 0) { + startFadeAnimation(mConfig.taskViewThumbnailAlpha, 0, 150, null); + } + } + } + + /** Prepares for the enter recents animation. */ + void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask) { + if (isTaskViewLaunchTargetTask) { + setAlpha(1f); + } else { + setAlpha(mConfig.taskViewThumbnailAlpha); + } + } + + /** Animates this task thumbnail as it enters recents */ + void startEnterRecentsAnimation(int delay, Runnable postAnimRunnable) { + startFadeAnimation(mConfig.taskViewThumbnailAlpha, delay, + mConfig.taskBarEnterAnimDuration, postAnimRunnable); + } + + /** Animates this task thumbnail as it exits recents */ + void startLaunchTaskAnimation() { + startFadeAnimation(1f, 0, mConfig.taskBarExitAnimDuration, null); + } + + /** Animates the thumbnail alpha. */ + void startFadeAnimation(float finalAlpha, int delay, int duration, Runnable postAnimRunnable) { + if (postAnimRunnable != null) { + animate().withEndAction(postAnimRunnable); + } + animate() + .alpha(finalAlpha) + .setStartDelay(delay) + .setInterpolator(mConfig.fastOutSlowInInterpolator) + .setDuration(duration) + .withLayer() + .start(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java index acfeb4ff48d2..35b574b8f36b 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java +++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java @@ -79,8 +79,9 @@ public class ToggleSlider extends RelativeLayout { public void setMirror(ToggleSlider toggleSlider) { mMirror = toggleSlider; if (mMirror != null) { - mMirror.mToggle.setChecked(mToggle.isChecked()); - mMirror.mSlider.setProgress(mSlider.getProgress()); + mMirror.setChecked(mToggle.isChecked()); + mMirror.setMax(mSlider.getMax()); + mMirror.setValue(mSlider.getProgress()); } } @@ -110,10 +111,16 @@ public class ToggleSlider extends RelativeLayout { public void setMax(int max) { mSlider.setMax(max); + if (mMirror != null) { + mMirror.setMax(max); + } } public void setValue(int value) { mSlider.setProgress(value); + if (mMirror != null) { + mMirror.setValue(value); + } } private final OnCheckedChangeListener mCheckListener = new OnCheckedChangeListener() { @@ -141,7 +148,7 @@ public class ToggleSlider extends RelativeLayout { } if (mMirror != null) { - mMirror.mSlider.setProgress(progress); + mMirror.setValue(progress); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index c23a4cdce0a5..8c5151b6391e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -42,6 +42,7 @@ import android.database.ContentObserver; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.AsyncTask; import android.os.Build; import android.os.Handler; import android.os.IBinder; @@ -89,6 +90,7 @@ import com.android.systemui.SwipeHelper; import com.android.systemui.SystemUI; import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.phone.KeyguardTouchDelegate; +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.HeadsUpNotificationView; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; @@ -130,9 +132,6 @@ public abstract class BaseStatusBar extends SystemUI implements public static final int EXPANDED_LEAVE_ALONE = -10000; public static final int EXPANDED_FULL_OPEN = -10001; - /** If true, delays dismissing the Keyguard until the ActivityManager calls back. */ - protected static final boolean DELAY_DISMISS_TO_ACTIVITY_LAUNCH = false; - protected CommandQueue mCommandQueue; protected IStatusBarService mBarService; protected H mHandler = createHandler(); @@ -156,6 +155,8 @@ public abstract class BaseStatusBar extends SystemUI implements protected int mLayoutDirection = -1; // invalid private Locale mLocale; + private float mFontScale; + protected boolean mUseHeadsUp = false; protected boolean mHeadsUpTicker = false; protected boolean mDisableNotificationAlerts = false; @@ -163,6 +164,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected DevicePolicyManager mDevicePolicyManager; protected IDreamManager mDreamManager; PowerManager mPowerManager; + protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; protected int mRowMinHeight; protected int mRowMaxHeight; @@ -252,27 +254,33 @@ public abstract class BaseStatusBar extends SystemUI implements } final boolean isActivity = pendingIntent.isActivity(); if (isActivity) { + final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing(); dismissKeyguardThenExecute(new OnDismissAction() { @Override public boolean onDismiss() { - try { - // The intent we are sending is for the application, which - // won't have permission to immediately start an activity after - // the user switches to home. We know it is safe to do at this - // point, so make sure new activity switches are now allowed. - ActivityManagerNative.getDefault().resumeAppSwitches(); - } catch (RemoteException e) { + if (keyguardShowing) { + try { + ActivityManagerNative.getDefault() + .keyguardWaitingForActivityDrawn(); + // The intent we are sending is for the application, which + // won't have permission to immediately start an activity after + // the user switches to home. We know it is safe to do at this + // point, so make sure new activity switches are now allowed. + ActivityManagerNative.getDefault().resumeAppSwitches(); + } catch (RemoteException e) { + } } boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent); + overrideActivityPendingAppTransition(keyguardShowing); // close the shade if it was open if (handled) { - animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); + animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */); visibilityChanged(false); } // Wait for activity start. - return handled && DELAY_DISMISS_TO_ACTIVITY_LAUNCH; + return handled; } }); return true; @@ -419,8 +427,10 @@ public abstract class BaseStatusBar extends SystemUI implements mRecents = getComponent(RecentsComponent.class); mRecents.setCallback(this); - mLocale = mContext.getResources().getConfiguration().locale; + final Configuration currentConfig = mContext.getResources().getConfiguration(); + mLocale = currentConfig.locale; mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale); + mFontScale = currentConfig.fontScale; mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); @@ -527,7 +537,9 @@ public abstract class BaseStatusBar extends SystemUI implements protected void onConfigurationChanged(Configuration newConfig) { final Locale locale = mContext.getResources().getConfiguration().locale; final int ld = TextUtils.getLayoutDirectionFromLocale(locale); - if (! locale.equals(mLocale) || ld != mLayoutDirection) { + final float fontScale = newConfig.fontScale; + + if (! locale.equals(mLocale) || ld != mLayoutDirection || fontScale != mFontScale) { if (DEBUG) { Log.v(TAG, String.format( "config changed locale/LD: %s (%d) -> %s (%d)", mLocale, mLayoutDirection, @@ -1064,7 +1076,7 @@ public abstract class BaseStatusBar extends SystemUI implements startAppNotificationSettingsActivity(pkg, appUidF); animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); visibilityChanged(false); - return DELAY_DISMISS_TO_ACTIVITY_LAUNCH; + return true; } }); } @@ -1208,8 +1220,6 @@ public abstract class BaseStatusBar extends SystemUI implements row.setClearable(sbn.isClearable()); - row.setDrawingCacheEnabled(true); - if (MULTIUSER_DEBUG) { TextView debug = (TextView) row.findViewById(R.id.debug_info); if (debug != null) { @@ -1254,54 +1264,74 @@ public abstract class BaseStatusBar extends SystemUI implements } public void onClick(final View v) { + final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing(); dismissKeyguardThenExecute(new OnDismissAction() { public boolean onDismiss() { - try { - // The intent we are sending is for the application, which - // won't have permission to immediately start an activity after - // the user switches to home. We know it is safe to do at this - // point, so make sure new activity switches are now allowed. - ActivityManagerNative.getDefault().resumeAppSwitches(); - } catch (RemoteException e) { + if (mIsHeadsUp) { + mHeadsUpNotificationView.clear(); } - - boolean sent = false; - if (mIntent != null) { - int[] pos = new int[2]; - v.getLocationOnScreen(pos); - Intent overlay = new Intent(); - overlay.setSourceBounds(new Rect(pos[0], pos[1], - pos[0] + v.getWidth(), pos[1] + v.getHeight())); - try { - mIntent.send(mContext, 0, overlay); - sent = true; - } catch (PendingIntent.CanceledException e) { - // the stack trace isn't very helpful here. - // Just log the exception message. - Log.w(TAG, "Sending contentIntent failed: " + e); - } - } - - try { - if (mIsHeadsUp) { - mHeadsUpNotificationView.clear(); + AsyncTask.execute(new Runnable() { + @Override + public void run() { + if (keyguardShowing) { + try { + ActivityManagerNative.getDefault() + .keyguardWaitingForActivityDrawn(); + // The intent we are sending is for the application, which + // won't have permission to immediately start an activity after + // the user switches to home. We know it is safe to do at this + // point, so make sure new activity switches are now allowed. + ActivityManagerNative.getDefault().resumeAppSwitches(); + } catch (RemoteException e) { + } + } + + if (mIntent != null) { + try { + mIntent.send(); + } catch (PendingIntent.CanceledException e) { + // the stack trace isn't very helpful here. + // Just log the exception message. + Log.w(TAG, "Sending contentIntent failed: " + e); + + // TODO: Dismiss Keyguard. + } + if (mIntent.isActivity()) { + overrideActivityPendingAppTransition(keyguardShowing); + } + } + + try { + mBarService.onNotificationClick(mNotificationKey); + } catch (RemoteException ex) { + // system process is dead if we're here. + } } - mBarService.onNotificationClick(mNotificationKey); - } catch (RemoteException ex) { - // system process is dead if we're here. - } + }); // close the shade if it was open - animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); + animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */); visibilityChanged(false); - boolean waitForActivityLaunch = sent && mIntent.isActivity(); - return waitForActivityLaunch && DELAY_DISMISS_TO_ACTIVITY_LAUNCH; + return mIntent != null && mIntent.isActivity(); } }); } } + public void animateCollapsePanels(int flags, boolean force) { + } + + public void overrideActivityPendingAppTransition(boolean keyguardShowing) { + if (keyguardShowing) { + try { + mWindowManagerService.overridePendingAppTransition(null, 0, 0, null); + } catch (RemoteException e) { + Log.w(TAG, "Error overriding app transition: " + e); + } + } + } + /** * The LEDs are turned o)ff when the notification panel is shown, even just a little bit. * This was added last-minute and is inconsistent with the way the rest of the notifications diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index a27557235cf6..43b77075c975 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -152,6 +152,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { logExpansionEvent(true, wasExpanded); } + public void resetUserExpansion() { + mHasUserChangedExpansion = false; + mUserExpanded = false; + } + public boolean isUserLocked() { return mUserLocked; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java index df64edfbeb48..5b0bf031596c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java @@ -256,7 +256,9 @@ public abstract class ExpandableView extends FrameLayout { } public void reset() { - mOnHeightChangedListener.onReset(this); + if (mOnHeightChangedListener != null) { + mOnHeightChangedListener.onReset(this); + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java index 5bc7e5a6e67d..23810f9cffa2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java @@ -24,5 +24,5 @@ import android.content.Intent; * Keyguard. */ public interface ActivityStarter { - public void startActivity(Intent intent); + public void startActivity(Intent intent, boolean dismissShade); } 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 e11f20fb6f40..b8ac3e781950 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -24,15 +24,18 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.res.Configuration; import android.os.RemoteException; import android.os.UserHandle; import android.provider.MediaStore; import android.util.AttributeSet; import android.util.Log; +import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; import android.widget.FrameLayout; +import android.widget.TextView; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; @@ -62,7 +65,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private KeyguardAffordanceView mCameraImageView; private KeyguardAffordanceView mPhoneImageView; private KeyguardAffordanceView mLockIcon; - private View mIndicationText; + private TextView mIndicationText; private ViewGroup mPreviewContainer; private View mPhonePreview; @@ -101,7 +104,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL mCameraImageView = (KeyguardAffordanceView) findViewById(R.id.camera_button); mPhoneImageView = (KeyguardAffordanceView) findViewById(R.id.phone_button); mLockIcon = (KeyguardAffordanceView) findViewById(R.id.lock_icon); - mIndicationText = findViewById(R.id.keyguard_indication_text); + mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text); watchForCameraPolicyChanges(); watchForAccessibilityChanges(); updateCameraVisibility(); @@ -116,6 +119,23 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL mLockIcon.setOnClickListener(this); } + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + int indicationBottomMargin = getResources().getDimensionPixelSize( + R.dimen.keyguard_indication_margin_bottom); + MarginLayoutParams mlp = (MarginLayoutParams) mIndicationText.getLayoutParams(); + if (mlp.bottomMargin != indicationBottomMargin) { + mlp.bottomMargin = indicationBottomMargin; + mIndicationText.setLayoutParams(mlp); + } + + // Respect font size setting. + mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize( + com.android.internal.R.dimen.text_size_small_material)); + } + public void setActivityStarter(ActivityStarter activityStarter) { mActivityStarter = activityStarter; } @@ -221,12 +241,12 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL !mPreviewInflater.wouldLaunchResolverActivity(intent)) { mContext.startActivityAsUser(intent, UserHandle.CURRENT); } else { - mActivityStarter.startActivity(intent); + mActivityStarter.startActivity(intent, false /* dismissShade */); } } public void launchPhone() { - mActivityStarter.startActivity(PHONE_INTENT); + mActivityStarter.startActivity(PHONE_INTENT, false /* dismissShade */); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index db42b9dad43b..fc737bee5e44 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -98,7 +98,7 @@ public class KeyguardBouncer { public void startPreHideAnimation(Runnable runnable) { if (mKeyguardView != null) { mKeyguardView.startDisappearAnimation(runnable); - } else { + } else if (runnable != null) { runnable.run(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java index b66c3101304f..5e5c3aa9dd00 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java @@ -18,8 +18,10 @@ package com.android.systemui.statusbar.phone; import android.animation.LayoutTransition; import android.content.Context; +import android.content.res.Configuration; import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.util.TypedValue; import android.view.View; import android.view.ViewTreeObserver; import android.view.animation.AnimationUtils; @@ -43,6 +45,7 @@ public class KeyguardStatusBarView extends RelativeLayout private boolean mKeyguardUserSwitcherShowing; private boolean mBatteryListening; + private TextView mCarrierLabel; private View mSystemIconsSuperContainer; private MultiUserSwitch mMultiUserSwitch; private ImageView mMultiUserAvatar; @@ -65,12 +68,25 @@ public class KeyguardStatusBarView extends RelativeLayout mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch); mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar); mBatteryLevel = (TextView) findViewById(R.id.battery_level); + mCarrierLabel = (TextView) findViewById(R.id.keyguard_carrier_text); loadDimens(); mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(), android.R.interpolator.fast_out_slow_in); updateUserSwitcher(); } + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + // Respect font size setting. + mCarrierLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize( + com.android.internal.R.dimen.text_size_small_material)); + mBatteryLevel.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize(R.dimen.battery_level_text_size)); + } + private void loadDimens() { mSystemIconsSwitcherHiddenExpandedMargin = getResources().getDimensionPixelSize( R.dimen.system_icons_switcher_hidden_expanded_margin); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java index 47325c82fab4..d7144dadcd9e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java @@ -21,10 +21,13 @@ import android.content.Intent; import android.os.UserHandle; import android.os.UserManager; import android.provider.ContactsContract; +import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; +import android.view.accessibility.AccessibilityEvent; import android.widget.FrameLayout; +import com.android.systemui.R; import com.android.systemui.qs.QSPanel; import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; @@ -36,9 +39,11 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener private QSPanel mQsPanel; private KeyguardUserSwitcher mKeyguardUserSwitcher; private boolean mKeyguardMode; + final UserManager mUserManager; public MultiUserSwitch(Context context, AttributeSet attrs) { super(context, attrs); + mUserManager = UserManager.get(getContext()); } @Override @@ -80,6 +85,22 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener } @Override + public void onPopulateAccessibilityEvent(AccessibilityEvent event) { + super.onPopulateAccessibilityEvent(event); + + if (isClickable()) { + final UserManager um = UserManager.get(getContext()); + String text = mContext.getString(um.isUserSwitcherEnabled() + ? R.string.accessibility_multi_user_switch_switcher + : R.string.accessibility_multi_user_switch_quick_contact); + if (!TextUtils.isEmpty(text)) { + event.getText().add(text); + } + } + + } + + @Override public boolean hasOverlappingRendering() { return false; } 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 acdc6bc59b20..42ae0c94fb8d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -24,6 +24,7 @@ import android.animation.ValueAnimator; import android.content.Context; import android.content.res.Configuration; import android.util.AttributeSet; +import android.util.MathUtils; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; @@ -104,7 +105,6 @@ public class NotificationPanelView extends PanelView implements private boolean mQsFullyExpanded; private boolean mKeyguardShowing; private boolean mDozing; - private boolean mKeyguardStatusBarTransparent; private int mStatusBarState; private float mInitialHeightOnTouch; private float mInitialTouchX; @@ -117,6 +117,7 @@ public class NotificationPanelView extends PanelView implements private int mQsPeekHeight; private boolean mStackScrollerOverscrolling; private boolean mQsExpansionFromOverscroll; + private float mLastOverscroll; private boolean mQsExpansionEnabled = true; private ValueAnimator mQsExpansionAnimator; private FlingAnimationUtils mFlingAnimationUtils; @@ -273,11 +274,10 @@ public class NotificationPanelView extends PanelView implements requestScrollerTopPaddingUpdate(false /* animate */); } } else { - if (!mStackScrollerOverscrolling) { - setQsExpansion(mQsMinExpansionHeight); - } + setQsExpansion(mQsMinExpansionHeight + mLastOverscroll); positionClockAndNotifications(); mNotificationStackScroller.setStackHeight(getExpandedHeight()); + updateHeader(); } mNotificationStackScroller.updateIsSmallScreen( mHeader.getCollapsedHeight() + mQsPeekHeight); @@ -414,12 +414,12 @@ public class NotificationPanelView extends PanelView implements } @Override - public void fling(float vel, boolean always) { + public void fling(float vel, boolean expand) { GestureRecorder gr = ((PhoneStatusBarView) mBar).mBar.getGestureRecorder(); if (gr != null) { gr.tag("fling " + ((vel > 0) ? "open" : "closed"), "notifications,v=" + vel); } - super.fling(vel, always); + super.fling(vel, expand); } @Override @@ -552,8 +552,8 @@ public class NotificationPanelView extends PanelView implements } private float getQsExpansionFraction() { - return (mQsExpansionHeight - mQsMinExpansionHeight) - / (getTempQsMaxExpansion() - mQsMinExpansionHeight); + return Math.min(1f, (mQsExpansionHeight - mQsMinExpansionHeight) + / (getTempQsMaxExpansion() - mQsMinExpansionHeight)); } @Override @@ -602,6 +602,10 @@ public class NotificationPanelView extends PanelView implements && event.getY(event.getActionIndex()) < mStatusBarMinHeight) { mTwoFingerQsExpand = true; requestPanelHeightUpdate(); + + // Normally, we start listening when the panel is expanded, but here we need to start + // earlier so the state is already up to date when dragging down. + setListening(true); } super.onTouchEvent(event); return true; @@ -621,6 +625,11 @@ public class NotificationPanelView extends PanelView implements mInitialHeightOnTouch = mQsExpansionHeight; mInitialTouchY = event.getX(); mInitialTouchX = event.getY(); + + // If we interrupt an expansion gesture here, make sure to update the state correctly. + if (mIsExpanding) { + onExpandingFinished(); + } } } @@ -718,6 +727,7 @@ public class NotificationPanelView extends PanelView implements float rounded = amount >= 1f ? amount : 0f; mStackScrollerOverscrolling = rounded != 0f && isRubberbanded; mQsExpansionFromOverscroll = rounded != 0f; + mLastOverscroll = rounded; updateQsState(); setQsExpansion(mQsMinExpansionHeight + rounded); } @@ -984,15 +994,7 @@ public class NotificationPanelView extends PanelView implements requestScrollerTopPaddingUpdate(false /* animate */); updateNotificationScrim(height); if (mKeyguardShowing) { - float alpha = getQsExpansionFraction(); - alpha *= 2; - alpha = Math.min(1, alpha); - alpha = 1 - alpha; - mKeyguardStatusBarTransparent = alpha == 0f; - updateKeyguardStatusBarVisibility(); - if (!mKeyguardStatusBarTransparent) { - mKeyguardStatusBar.setAlpha(alpha); - } + updateHeaderKeyguard(); } if (mStatusBarState == StatusBarState.SHADE && mQsExpanded && !mStackScrollerOverscrolling && mQsScrimEnabled) { @@ -1025,7 +1027,9 @@ public class NotificationPanelView extends PanelView implements } private float calculateQsTopPadding() { - if (mKeyguardShowing) { + // We can only do the smoother transition on Keyguard when we also are not collapsing from a + // scrolled quick settings. + if (mKeyguardShowing && mScrollYOverride == -1) { return interpolate(getQsExpansionFraction(), mNotificationStackScroller.getIntrinsicPadding() - mNotificationTopPadding, mQsMaxExpansionHeight); @@ -1081,6 +1085,7 @@ public class NotificationPanelView extends PanelView implements } return; } + mScrollView.setBlockFlinging(true); ValueAnimator animator = ValueAnimator.ofFloat(mQsExpansionHeight, target); mFlingAnimationUtils.apply(animator, mQsExpansionHeight, target, vel); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @@ -1092,6 +1097,7 @@ public class NotificationPanelView extends PanelView implements animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { + mScrollView.setBlockFlinging(false); mScrollYOverride = -1; mQsExpansionAnimator = null; if (onFinishRunnable != null) { @@ -1339,27 +1345,25 @@ public class NotificationPanelView extends PanelView implements } private void updateHeaderKeyguard() { - float alpha; + float alphaNotifications; if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) { // When on Keyguard, we hide the header as soon as the top card of the notification // stack scroller is close enough (collision distance) to the bottom of the header. - alpha = getNotificationsTopY() + alphaNotifications = getNotificationsTopY() / - (mQsMinExpansionHeight + mNotificationsHeaderCollideDistance); - + (mKeyguardStatusBar.getHeight() + mNotificationsHeaderCollideDistance); } else { // In SHADE_LOCKED, the top card is already really close to the header. Hide it as // soon as we start translating the stack. - alpha = getNotificationsTopY() / mQsMinExpansionHeight; - } - alpha = Math.max(0, Math.min(alpha, 1)); - alpha = (float) Math.pow(alpha, 0.75); - if (!mQsExpanded) { - mKeyguardStatusBar.setAlpha(alpha); + alphaNotifications = getNotificationsTopY() / mKeyguardStatusBar.getHeight(); } - mKeyguardBottomArea.setAlpha(alpha); + alphaNotifications = MathUtils.constrain(alphaNotifications, 0, 1); + alphaNotifications = (float) Math.pow(alphaNotifications, 0.75); + float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2); + mKeyguardStatusBar.setAlpha(Math.min(alphaNotifications, alphaQsExpansion)); + mKeyguardBottomArea.setAlpha(Math.min(1 - getQsExpansionFraction(), alphaNotifications)); setQsTranslation(mQsExpansionHeight); } @@ -1703,8 +1707,7 @@ public class NotificationPanelView extends PanelView implements } private void updateKeyguardStatusBarVisibility() { - mKeyguardStatusBar.setVisibility(mKeyguardShowing && !mKeyguardStatusBarTransparent - && !mDozing ? VISIBLE : INVISIBLE); + mKeyguardStatusBar.setVisibility(mKeyguardShowing && !mDozing ? VISIBLE : INVISIBLE); } public void setDozing(boolean dozing) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java index ee6b1a9de864..53361dcef591 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java @@ -33,6 +33,7 @@ public class ObservableScrollView extends ScrollView { private boolean mHandlingTouchEvent; private float mLastX; private float mLastY; + private boolean mBlockFlinging; public ObservableScrollView(Context context, AttributeSet attrs) { super(context, attrs); @@ -109,6 +110,17 @@ public class ObservableScrollView extends ScrollView { maxOverScrollX, maxOverScrollY, isTouchEvent); } + public void setBlockFlinging(boolean blockFlinging) { + mBlockFlinging = blockFlinging; + } + + @Override + public void fling(int velocityY) { + if (!mBlockFlinging) { + super.fling(velocityY); + } + } + @Override protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) { super.onOverScrolled(scrollX, scrollY, clampedX, clampedY); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index 59f94f225de0..f74d2f4baf70 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -140,7 +140,7 @@ public class PanelBar extends FrameLayout { mPanelHolder.setSelectedPanel(mTouchingPanel); for (PanelView pv : mPanels) { if (pv != panel) { - pv.collapse(); + pv.collapse(false /* delayed */); } } } @@ -191,7 +191,7 @@ public class PanelBar extends FrameLayout { boolean waiting = false; for (PanelView pv : mPanels) { if (animate && !pv.isFullyCollapsed()) { - pv.collapse(); + pv.collapse(true /* delayed */); waiting = true; } else { pv.resetViews(); 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 469a831e47a4..c8e943e07547 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -99,6 +99,7 @@ public abstract class PanelView extends FrameLayout { }; protected void onExpandingFinished() { + mClosing = false; mBar.onExpandingFinished(); } @@ -150,7 +151,7 @@ public abstract class PanelView extends FrameLayout { postOnAnimation(new Runnable() { @Override public void run() { - collapse(); + collapse(false /* delayed */); } }); } @@ -651,7 +652,7 @@ public abstract class PanelView extends FrameLayout { mBar = panelBar; } - public void collapse() { + public void collapse(boolean delayed) { if (DEBUG) logf("collapse: " + this); if (mPeekPending || mPeekAnimator != null) { mCollapseAfterPeek = true; @@ -668,7 +669,16 @@ public abstract class PanelView extends FrameLayout { } mClosing = true; notifyExpandingStarted(); - fling(0, false /* expand */); + if (delayed) { + postDelayed(new Runnable() { + @Override + public void run() { + fling(0, false /* expand */); + } + }, 120); + } else { + fling(0, false /* expand */); + } } } @@ -856,7 +866,7 @@ public abstract class PanelView extends FrameLayout { private final Runnable mPostCollapseRunnable = new Runnable() { @Override public void run() { - collapse(); + collapse(false /* delayed */); } }; private boolean onMiddleClicked() { 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 caecf1d0ee93..7a9cbef7e93b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -91,6 +91,8 @@ import android.view.ViewPropertyAnimator; import android.view.ViewStub; import android.view.ViewTreeObserver; import android.view.WindowManager; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateInterpolator; import android.view.animation.Animation; @@ -113,7 +115,6 @@ import com.android.systemui.R; import com.android.systemui.doze.DozeService; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.qs.QSPanel; -import com.android.systemui.qs.QSTile; import com.android.systemui.statusbar.ActivatableNotificationView; import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.CommandQueue; @@ -138,6 +139,7 @@ import com.android.systemui.statusbar.policy.CastControllerImpl; import com.android.systemui.statusbar.policy.FlashlightController; import com.android.systemui.statusbar.policy.HeadsUpNotificationView; import com.android.systemui.statusbar.policy.HotspotControllerImpl; +import com.android.systemui.statusbar.policy.KeyButtonView; import com.android.systemui.statusbar.policy.KeyguardMonitor; import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.LocationControllerImpl; @@ -211,6 +213,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public static final int FADE_KEYGUARD_START_DELAY = 100; public static final int FADE_KEYGUARD_DURATION = 300; + /** Allow some time inbetween the long press for back and recents. */ + private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200; + PhoneStatusBarPolicy mIconPolicy; // These are no longer handled by the policy, because we need custom strategies for them @@ -323,7 +328,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, VelocityTracker mVelocityTracker; int[] mAbsPos = new int[2]; - Runnable mPostCollapseCleanup = null; + ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>(); // for disabling the status bar int mDisabled = 0; @@ -395,7 +400,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private int mNavigationBarMode; private Boolean mScreenOn; - private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private ViewMediatorCallback mKeyguardViewMediatorCallback; private ScrimController mScrimController; @@ -575,6 +579,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mDozeServiceHost = new DozeServiceHost(); putComponent(DozeService.Host.class, mDozeServiceHost); + putComponent(PhoneStatusBar.class, this); setControllerUsers(); } @@ -887,14 +892,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, return; } - mPostCollapseCleanup = new Runnable() { + addPostCollapseAction(new Runnable() { @Override public void run() { try { mBarService.onClearAllNotifications(mCurrentUserId); } catch (Exception ex) { } } - }; + }); performDismissAllAnimations(viewsToHide); @@ -1055,10 +1060,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } }; - private View.OnLongClickListener mLockToAppClickListener = new View.OnLongClickListener() { + private long mLastLockToAppLongPress; + private AccessibilityManager mAccessibilityManager; + private View.OnLongClickListener mLongPressBackRecentsListener = + new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { - toggleLockedApp(); + handleLongPressBackRecents(v); return true; } }; @@ -1107,7 +1115,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener); mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener); mNavigationBarView.getRecentsButton().setLongClickable(true); - mNavigationBarView.getRecentsButton().setOnLongClickListener(mLockToAppClickListener); + mNavigationBarView.getRecentsButton().setOnLongClickListener(mLongPressBackRecentsListener); + mNavigationBarView.getBackButton().setLongClickable(true); + mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener); mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener); updateSearchPanel(); } @@ -1366,6 +1376,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void updateNotificationShade() { if (mStackScroller == null) return; + // Do not modify the notifications during collapse. + if (isCollapsing()) { + addPostCollapseAction(new Runnable() { + @Override + public void run() { + updateNotificationShade(); + } + }); + return; + } + ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications(); ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size()); final int N = activeNotifications.size(); @@ -2004,8 +2025,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override - public void startActivity(Intent intent) { - startActivityDismissingKeyguard(intent, false); + public void startActivity(Intent intent, boolean dismissShade) { + startActivityDismissingKeyguard(intent, false, dismissShade); } public ScrimController getScrimController() { @@ -2016,6 +2037,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStatusBarWindowManager.setQsExpanded(expanded); } + public boolean isGoingToNotificationShade() { + return mLeaveOpenOnKeyguardHide; + } + + public boolean isQsExpanded() { + return mNotificationPanel.isQsExpanded(); + } + /** * All changes to the status bar and notifications funnel through here and are batched. */ @@ -2126,10 +2155,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void animateCollapsePanels(int flags, boolean force) { if (!force && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) { - if (mPostCollapseCleanup != null) { - mPostCollapseCleanup.run(); - mPostCollapseCleanup = null; - } + runPostCollapseRunnables(); return; } if (SPEW) { @@ -2159,6 +2185,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } + private void runPostCollapseRunnables() { + int size = mPostCollapseRunnables.size(); + for (int i = 0; i < size; i++) { + mPostCollapseRunnables.get(i).run(); + } + mPostCollapseRunnables.clear(); + } + public ViewPropertyAnimator setVisibilityWhenDone( final ViewPropertyAnimator a, final View v, final int vis) { a.setListener(new AnimatorListenerAdapter() { @@ -2270,11 +2304,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Close any "App info" popups that might have snuck on-screen dismissPopups(); - if (mPostCollapseCleanup != null) { - mPostCollapseCleanup.run(); - mPostCollapseCleanup = null; - } - + runPostCollapseRunnables(); setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false); showBouncer(); disable(mDisabledUnmodified, true /* animate */); @@ -2874,7 +2904,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } - public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned) { + public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned, + final boolean dismissShade) { if (onlyProvisioned && !isDeviceProvisioned()) return; final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing(); @@ -2884,32 +2915,27 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, AsyncTask.execute(new Runnable() { public void run() { try { + if (keyguardShowing) { + ActivityManagerNative.getDefault() + .keyguardWaitingForActivityDrawn(); + } intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); mContext.startActivityAsUser( intent, new UserHandle(UserHandle.USER_CURRENT)); - if (keyguardShowing) { - mWindowManagerService.overridePendingAppTransition( - null, 0, 0, null); - } + overrideActivityPendingAppTransition(keyguardShowing); } catch (RemoteException e) { } } }); - animateCollapsePanels(); - - return DELAY_DISMISS_TO_ACTIVITY_LAUNCH; + if (dismissShade) { + animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */); + } + return true; } }); } - private View.OnClickListener mClockClickListener = new View.OnClickListener() { - public void onClick(View v) { - startActivityDismissingKeyguard( - new Intent(Intent.ACTION_QUICK_CLOCK), true); // have fun, everyone - } - }; - private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { if (DEBUG) Log.v(TAG, "onReceive: " + intent); @@ -2928,6 +2954,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, notifyHeadsUpScreenOn(false); finishBarAnimations(); stopNotificationLogging(); + resetUserExpandedStates(); } else if (Intent.ACTION_SCREEN_ON.equals(action)) { mScreenOn = true; @@ -2956,6 +2983,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } }; + private void resetUserExpandedStates() { + ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications(); + final int notificationCount = activeNotifications.size(); + for (int i = 0; i < notificationCount; i++) { + NotificationData.Entry entry = activeNotifications.get(i); + if (entry.row != null) { + entry.row.resetUserExpansion(); + } + } + } + @Override protected void dismissKeyguardThenExecute(final OnDismissAction action) { if (mStatusBarKeyguardViewManager.isShowing()) { @@ -3208,19 +3246,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } private void handleStartSettingsActivity(Intent intent, boolean onlyProvisioned) { - if (onlyProvisioned && !isDeviceProvisioned()) return; - try { - // Dismiss the lock screen when Settings starts. - ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); - } catch (RemoteException e) { - } - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); - animateCollapsePanels(); - } - - public void startSettingsActivity(String action) { - postStartSettingsActivity(new Intent(action), 0); + startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */); } private static class FastColorDrawable extends Drawable { @@ -3363,6 +3389,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } + public boolean isCollapsing() { + return mNotificationPanel.isCollapsing(); + } + + public void addPostCollapseAction(Runnable r) { + mPostCollapseRunnables.add(r); + } + public boolean isInLaunchTransition() { return mNotificationPanel.isLaunchTransitionRunning() || mNotificationPanel.isLaunchTransitionFinished(); @@ -3603,10 +3637,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } public void onTrackingStarted() { - if (mPostCollapseCleanup != null) { - mPostCollapseCleanup.run(); - mPostCollapseCleanup = null; - } + runPostCollapseRunnables(); } public void onUnlockHintStarted() { @@ -3753,15 +3784,58 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStackScroller.setAnimationsEnabled(true); } - public void toggleLockedApp() { - Log.d(TAG, "Trying to toggle lock-to-app"); + /** + * This handles long-press of both back and recents. They are + * handled together to capture them both being long-pressed + * at the same time to exit screen pinning (lock task). + * + * When accessibility mode is on, only a long-press from recents + * is required to exit. + * + * In all other circumstances we try to pass through long-press events + * for Back, so that apps can still use it. Which can be from two things. + * 1) Not currently in screen pinning (lock task). + * 2) Back is long-pressed without recents. + */ + private void handleLongPressBackRecents(View v) { try { + boolean sendBackLongPress = false; IActivityManager activityManager = ActivityManagerNative.getDefault(); - if (activityManager.isInLockTaskMode()) { - activityManager.stopLockTaskModeOnCurrent(); + if (mAccessibilityManager == null) { + mAccessibilityManager = (AccessibilityManager) + mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); + } + boolean isAccessiblityEnabled = mAccessibilityManager.isEnabled(); + if (activityManager.isInLockTaskMode() && !isAccessiblityEnabled) { + long time = System.currentTimeMillis(); + // If we recently long-pressed the other button then they were + // long-pressed 'together' + if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) { + activityManager.stopLockTaskModeOnCurrent(); + } else if ((v.getId() == R.id.back) + && !mNavigationBarView.getRecentsButton().isPressed()) { + // If we aren't pressing recents right now then they presses + // won't be together, so send the standard long-press action. + sendBackLongPress = true; + } + mLastLockToAppLongPress = time; + } else { + // If this is back still need to handle sending the long-press event. + if (v.getId() == R.id.back) { + sendBackLongPress = true; + } else if (isAccessiblityEnabled && activityManager.isInLockTaskMode()) { + // When in accessibility mode a long press that is recents (not back) + // should stop lock task. + activityManager.stopLockTaskModeOnCurrent(); + } + } + if (sendBackLongPress) { + KeyButtonView keyButtonView = (KeyButtonView) v; + keyButtonView.sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS); + keyButtonView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); } } catch (RemoteException e) { - Log.d(TAG, "Unable to toggle Lock-to-app", e); + Log.d(TAG, "Unable to reach activity manager", e); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java index 0c62fd3bbfce..39b20220f5fe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java @@ -16,7 +16,7 @@ package com.android.systemui.statusbar.phone; -import android.app.AlarmClockInfo; +import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; @@ -24,6 +24,7 @@ import android.graphics.Outline; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; @@ -54,7 +55,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private View mSystemIconsSuperContainer; private View mDateGroup; private View mClock; - private View mTime; + private TextView mTime; private View mAmPm; private MultiUserSwitch mMultiUserSwitch; private ImageView mMultiUserAvatar; @@ -73,7 +74,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private boolean mShowEmergencyCallsOnly; private boolean mAlarmShowing; - private AlarmClockInfo mNextAlarm; + private AlarmManager.AlarmClockInfo mNextAlarm; private int mCollapsedHeight; private int mExpandedHeight; @@ -86,6 +87,9 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private int mMultiUserSwitchWidthCollapsed; private int mMultiUserSwitchWidthExpanded; + private int mClockCollapsedSize; + private int mClockExpandedSize; + /** * In collapsed QS, the clock and avatar are scaled down a bit post-layout to allow for a nice * transition. These values determine that factor. @@ -121,7 +125,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mSystemIconsSuperContainer.setOnClickListener(this); mDateGroup = findViewById(R.id.date_group); mClock = findViewById(R.id.clock); - mTime = findViewById(R.id.time_view); + mTime = (TextView) findViewById(R.id.time_view); mAmPm = findViewById(R.id.am_pm_view); mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch); mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar); @@ -152,8 +156,6 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; mTime.setPivotX(rtl ? mTime.getWidth() : 0); mTime.setPivotY(mTime.getBaseline()); - mAmPm.setPivotX(rtl ? mAmPm.getWidth() : 0); - mAmPm.setPivotY(mAmPm.getBaseline()); updateAmPmTranslation(); } }); @@ -206,9 +208,10 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mAvatarCollapsedScaleFactor = getResources().getDimensionPixelSize(R.dimen.multi_user_avatar_collapsed_size) / (float) mMultiUserAvatar.getLayoutParams().width; - mClockCollapsedScaleFactor = - (float) getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size) - / (float) getResources().getDimensionPixelSize(R.dimen.qs_time_expanded_size); + mClockCollapsedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size); + mClockExpandedSize = getResources().getDimensionPixelSize(R.dimen.qs_time_expanded_size); + mClockCollapsedScaleFactor = (float) mClockCollapsedSize / (float) mClockExpandedSize; + } public void setActivityStarter(ActivityStarter activityStarter) { @@ -333,17 +336,14 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } private void updateClockScale() { - mAmPm.setScaleX(mClockCollapsedScaleFactor); - mAmPm.setScaleY(mClockCollapsedScaleFactor); - mTime.setScaleX(getTimeScale()); - mTime.setScaleY(getTimeScale()); + mTime.setTextSize(TypedValue.COMPLEX_UNIT_PX, mExpanded + ? mClockExpandedSize + : mClockCollapsedSize); + mTime.setScaleX(1f); + mTime.setScaleY(1f); updateAmPmTranslation(); } - private float getTimeScale() { - return !mExpanded ? mClockCollapsedScaleFactor : 1f; - } - private void updateAmPmTranslation() { boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; mAmPm.setTranslationX((rtl ? 1 : -1) * mTime.getWidth() * (1 - mTime.getScaleX())); @@ -360,13 +360,13 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } @Override - public void onNextAlarmChanged(AlarmClockInfo nextAlarm) { + public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) { mNextAlarm = nextAlarm; if (nextAlarm != null) { mAlarmStatus.setText(KeyguardStatusView.formatNextAlarm(getContext(), nextAlarm)); } mAlarmShowing = nextAlarm != null; - updateVisibilities(); + updateEverything(); requestCaptureValues(); } @@ -483,17 +483,19 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } else if (v == mAlarmStatus && mNextAlarm != null) { PendingIntent showIntent = mNextAlarm.getShowIntent(); if (showIntent != null && showIntent.isActivity()) { - mActivityStarter.startActivity(showIntent.getIntent()); + mActivityStarter.startActivity(showIntent.getIntent(), true /* dismissShade */); } } } private void startSettingsActivity() { - mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS)); + mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS), + true /* dismissShade */); } private void startBatteryActivity() { - mActivityStarter.startActivity(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY)); + mActivityStarter.startActivity(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY), + true /* dismissShade */); } public void setQSPanel(QSPanel qsp) { @@ -510,10 +512,13 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } public void setShowEmergencyCallsOnly(boolean show) { - mShowEmergencyCallsOnly = show; - if (mExpanded) { - updateVisibilities(); - requestCaptureValues(); + boolean changed = show != mShowEmergencyCallsOnly; + if (changed) { + mShowEmergencyCallsOnly = show; + if (mExpanded) { + updateEverything(); + requestCaptureValues(); + } } } @@ -524,8 +529,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } private void captureLayoutValues(LayoutValues target) { - target.timeScale = mTime.getScaleX(); - target.clockY = mClock.getTop(); + target.timeScale = mExpanded ? 1f : mClockCollapsedScaleFactor; + target.clockY = mClock.getBottom(); target.dateY = mDateGroup.getTop(); target.emergencyCallsOnlyAlpha = getAlphaForVisibility(mEmergencyCallsOnly); target.alarmStatusAlpha = getAlphaForVisibility(mAlarmStatus); @@ -550,7 +555,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } private void applyAlpha(View v, float alpha) { - if (v == null) { + if (v == null || v.getVisibility() == View.GONE) { return; } if (alpha == 0f) { @@ -564,7 +569,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private void applyLayoutValues(LayoutValues values) { mTime.setScaleX(values.timeScale); mTime.setScaleY(values.timeScale); - mClock.setY(values.clockY); + mClock.setY(values.clockY - mClock.getHeight()); mDateGroup.setY(values.dateY); mAlarmStatus.setY(values.dateY - mAlarmStatus.getPaddingTop()); mMultiUserAvatar.setScaleX(values.avatarScale); @@ -593,6 +598,10 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL applyAlpha(mBatteryLevel, values.batteryLevelAlpha); applyAlpha(mSettingsButton, values.settingsAlpha); applyAlpha(mSignalCluster, values.signalClusterAlpha); + if (!mExpanded) { + mTime.setScaleX(1f); + mTime.setScaleY(1f); + } updateAmPmTranslation(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 68dd4f90b376..f427ec458c07 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -188,6 +188,7 @@ public class StatusBarKeyguardViewManager { @Override public void run() { mStatusBarWindowManager.setKeyguardOccluded(true); + reset(); } }); return; @@ -206,12 +207,13 @@ public class StatusBarKeyguardViewManager { * Starts the animation before we dismiss Keyguard, i.e. an disappearing animation on the * security view of the bouncer. * - * @param finishRunnable the runnable to be run after the animation finished + * @param finishRunnable the runnable to be run after the animation finished, or {@code null} if + * no action should be run */ public void startPreHideAnimation(Runnable finishRunnable) { if (mBouncer.isShowing()) { mBouncer.startPreHideAnimation(finishRunnable); - } else { + } else if (finishRunnable != null) { finishRunnable.run(); } } @@ -362,4 +364,25 @@ public class StatusBarKeyguardViewManager { public boolean interceptMediaKey(KeyEvent event) { return mBouncer.interceptMediaKey(event); } + + public void onActivityDrawn() { + if (mPhoneStatusBar.isCollapsing()) { + mPhoneStatusBar.addPostCollapseAction(new Runnable() { + @Override + public void run() { + mViewMediatorCallback.readyForKeyguardDone(); + } + }); + } else { + mViewMediatorCallback.readyForKeyguardDone(); + } + } + + public boolean shouldDisableWindowAnimationsForUnlock() { + return mPhoneStatusBar.isInLaunchTransition(); + } + + public boolean isGoingToNotificationShade() { + return mPhoneStatusBar.isGoingToNotificationShade(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 2c5bcb79a712..04ee294f7f49 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -28,7 +28,6 @@ import android.view.View; import android.view.ViewRootImpl; import android.widget.FrameLayout; -import com.android.systemui.ExpandHelper; import com.android.systemui.R; import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.DragDownHelper; @@ -130,7 +129,7 @@ public class StatusBarWindowView extends FrameLayout { @Override public boolean onTouchEvent(MotionEvent ev) { boolean handled = false; - if (mService.getBarState() == StatusBarState.KEYGUARD) { + if (mService.getBarState() == StatusBarState.KEYGUARD && !mService.isQsExpanded()) { handled = mDragDownHelper.onTouchEvent(ev); } if (!handled) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java index 330b599fe3b9..e9581fcc4880 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -56,12 +56,12 @@ public class KeyButtonView extends ImageView { public void run() { if (isPressed()) { // Log.d("KeyButtonView", "longpressed: " + this); - if (mCode != 0) { - sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS); - sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); - } else { + if (isLongClickable()) { // Just an old-fashioned ImageView performLongClick(); + } else { + sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS); + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); } } } @@ -216,7 +216,7 @@ public class KeyButtonView extends ImageView { return true; } - void sendEvent(int action, int flags) { + public void sendEvent(int action, int flags) { sendEvent(action, flags, SystemClock.uptimeMillis()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmController.java index ca71521319b8..8f1f7c7b6ec7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmController.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.policy; -import android.app.AlarmClockInfo; import android.app.AlarmManager; import android.content.BroadcastReceiver; import android.content.Context; @@ -33,7 +32,7 @@ public class NextAlarmController extends BroadcastReceiver { private final ArrayList<NextAlarmChangeCallback> mChangeCallbacks = new ArrayList<>(); private AlarmManager mAlarmManager; - private AlarmClockInfo mNextAlarm; + private AlarmManager.AlarmClockInfo mNextAlarm; public NextAlarmController(Context context) { mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); @@ -79,6 +78,6 @@ public class NextAlarmController extends BroadcastReceiver { } public interface NextAlarmChangeCallback { - void onNextAlarmChanged(AlarmClockInfo nextAlarm); + void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index a1993f7bfdba..47e3e736b4ea 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -113,6 +113,7 @@ public class UserSwitcherController { * * @param forcePictureLoadForId forces the picture of the given user to be reloaded. */ + @SuppressWarnings("unchecked") private void refreshUsers(int forcePictureLoadForId) { SparseArray<Bitmap> bitmaps = new SparseArray<>(mUsers.size()); @@ -170,7 +171,7 @@ public class UserSwitcherController { boolean canCreateGuest = (currentUserCanCreateUsers || anyoneCanCreateUsers) && guestRecord == null; boolean canCreateUser = (currentUserCanCreateUsers || anyoneCanCreateUsers) - && records.size() < UserManager.getMaxSupportedUsers(); + && mUserManager.canAddMoreUsers(); boolean createIsRestricted = !addUsersWhenLocked; if (!mSimpleUserSwitcher) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java index 9d3dec80d421..b33e502c86ab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.policy; -import android.app.AlarmClockInfo; import android.app.AlarmManager; import android.app.INotificationManager; import android.content.BroadcastReceiver; @@ -146,7 +145,7 @@ public class ZenModeControllerImpl implements ZenModeController { @Override public long getNextAlarm() { - final AlarmClockInfo info = mAlarmManager.getNextAlarmClock(mUserId); + final AlarmManager.AlarmClockInfo info = mAlarmManager.getNextAlarmClock(mUserId); return info != null ? info.getTriggerTime() : 0; } 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 d25dda1edec1..8e5077cb20dd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -211,6 +211,15 @@ public class NotificationStackScrollLayout extends ViewGroup public NotificationStackScrollLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); + int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height); + int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height); + mExpandHelper = new ExpandHelper(getContext(), this, + minHeight, maxHeight); + mExpandHelper.setEventSource(this); + mExpandHelper.setScrollAdapter(this); + + mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, getContext()); + mSwipeHelper.setLongPressListener(mLongPressListener); initView(context); if (DEBUG) { setWillNotDraw(false); @@ -248,10 +257,6 @@ public class NotificationStackScrollLayout extends ViewGroup mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mOverflingDistance = configuration.getScaledOverflingDistance(); - float densityScale = getResources().getDisplayMetrics().density; - float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop(); - mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, getContext()); - mSwipeHelper.setLongPressListener(mLongPressListener); mSidePaddings = context.getResources() .getDimensionPixelSize(R.dimen.notification_side_padding); @@ -266,12 +271,6 @@ public class NotificationStackScrollLayout extends ViewGroup mPaddingBetweenElementsNormal = context.getResources() .getDimensionPixelSize(R.dimen.notification_padding); updatePadding(mAmbientState.isDimmed()); - int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height); - int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height); - mExpandHelper = new ExpandHelper(getContext(), this, - minHeight, maxHeight); - mExpandHelper.setEventSource(this); - mExpandHelper.setScrollAdapter(this); mMinTopOverScrollToEscape = getResources().getDimensionPixelSize( R.dimen.min_top_overscroll_to_qs); mNotificationTopPadding = getResources().getDimensionPixelSize( @@ -281,7 +280,7 @@ public class NotificationStackScrollLayout extends ViewGroup } private void updatePadding(boolean dimmed) { - mPaddingBetweenElements = dimmed + mPaddingBetweenElements = dimmed && mStackScrollAlgorithm.shouldScaleDimmed() ? mPaddingBetweenElementsDimmed : mPaddingBetweenElementsNormal; mBottomStackSlowDownHeight = mStackScrollAlgorithm.getBottomStackSlowDownLength(); 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 f984339b3c3d..fc2be1af7049 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.stack; import android.content.Context; +import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -73,6 +74,7 @@ public class StackScrollAlgorithm { private int mCollapseSecondCardPadding; private boolean mIsSmallScreen; private int mMaxNotificationHeight; + private boolean mScaleDimmed; public StackScrollAlgorithm(Context context) { initConstants(context); @@ -80,7 +82,7 @@ public class StackScrollAlgorithm { } private void updatePadding(boolean dimmed) { - mPaddingBetweenElements = dimmed + mPaddingBetweenElements = dimmed && mScaleDimmed ? mPaddingBetweenElementsDimmed : mPaddingBetweenElementsNormal; mTopStackTotalSize = mTopStackSlowDownLength + mPaddingBetweenElements @@ -125,8 +127,13 @@ public class StackScrollAlgorithm { R.dimen.notification_material_rounded_rect_radius); mCollapseSecondCardPadding = context.getResources().getDimensionPixelSize( R.dimen.notification_collapse_second_card_padding); + mScaleDimmed = context.getResources().getDisplayMetrics().densityDpi + >= DisplayMetrics.DENSITY_XXHIGH; } + public boolean shouldScaleDimmed() { + return mScaleDimmed; + } public void getStackScrollState(AmbientState ambientState, StackScrollState resultState) { // The state of the local variables are saved in an algorithmState to easily subdivide it @@ -271,7 +278,7 @@ public class StackScrollAlgorithm { childViewState.dark = dark; childViewState.hideSensitive = hideSensitive; boolean isActivatedChild = activatedChild == child; - childViewState.scale = !dimmed || isActivatedChild + childViewState.scale = !mScaleDimmed || !dimmed || isActivatedChild ? 1.0f : DIMMED_SCALE; if (dimmed && activatedChild != null) { diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java index 5233da26572b..b05c242bf66a 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java @@ -112,7 +112,8 @@ public class VolumePanel extends Handler { // Pseudo stream type for master volume private static final int STREAM_MASTER = -100; - // Pseudo stream type for remote volume is defined in AudioService.STREAM_REMOTE_MUSIC + // Pseudo stream type for remote volume + private static final int STREAM_REMOTE_MUSIC = -200; private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) @@ -192,7 +193,7 @@ public class VolumePanel extends Handler { R.drawable.ic_audio_vol, R.drawable.ic_audio_vol_mute, false), - RemoteStream(AudioService.STREAM_REMOTE_MUSIC, + RemoteStream(STREAM_REMOTE_MUSIC, R.string.volume_icon_description_media, //FIXME should have its own description R.drawable.ic_media_route_on_holo_dark, R.drawable.ic_media_route_disabled_holo_dark, @@ -521,7 +522,7 @@ public class VolumePanel extends Handler { private boolean isMuted(int streamType) { if (streamType == STREAM_MASTER) { return mAudioManager.isMasterMute(); - } else if (streamType == AudioService.STREAM_REMOTE_MUSIC) { + } else if (streamType == STREAM_REMOTE_MUSIC) { // TODO do we need to support a distinct mute property for remote? return false; } else { @@ -532,7 +533,7 @@ public class VolumePanel extends Handler { private int getStreamMaxVolume(int streamType) { if (streamType == STREAM_MASTER) { return mAudioManager.getMasterMaxVolume(); - } else if (streamType == AudioService.STREAM_REMOTE_MUSIC) { + } else if (streamType == STREAM_REMOTE_MUSIC) { if (mStreamControls != null) { StreamControl sc = mStreamControls.get(streamType); if (sc != null && sc.controller != null) { @@ -549,7 +550,7 @@ public class VolumePanel extends Handler { private int getStreamVolume(int streamType) { if (streamType == STREAM_MASTER) { return mAudioManager.getMasterVolume(); - } else if (streamType == AudioService.STREAM_REMOTE_MUSIC) { + } else if (streamType == STREAM_REMOTE_MUSIC) { if (mStreamControls != null) { StreamControl sc = mStreamControls.get(streamType); if (sc != null && sc.controller != null) { @@ -564,7 +565,7 @@ public class VolumePanel extends Handler { } private void setStreamVolume(StreamControl sc, int index, int flags) { - if (sc.streamType == AudioService.STREAM_REMOTE_MUSIC) { + if (sc.streamType == STREAM_REMOTE_MUSIC) { if (sc.controller != null) { sc.controller.setVolumeTo(index, flags); } else { @@ -690,7 +691,7 @@ public class VolumePanel extends Handler { private void updateSliderEnabled(final StreamControl sc, boolean muted, boolean fixedVolume) { final boolean wasEnabled = sc.seekbarView.isEnabled(); final boolean isRinger = isNotificationOrRing(sc.streamType); - if (sc.streamType == AudioService.STREAM_REMOTE_MUSIC) { + if (sc.streamType == STREAM_REMOTE_MUSIC) { // never disable touch interactions for remote playback, the muting is not tied to // the state of the phone. sc.seekbarView.setEnabled(!fixedVolume); @@ -805,7 +806,7 @@ public class VolumePanel extends Handler { public void postRemoteSliderVisibility(boolean visible) { obtainMessage(MSG_SLIDER_VISIBILITY_CHANGED, - AudioService.STREAM_REMOTE_MUSIC, visible ? 1 : 0).sendToTarget(); + STREAM_REMOTE_MUSIC, visible ? 1 : 0).sendToTarget(); } /** @@ -980,7 +981,7 @@ public class VolumePanel extends Handler { break; } - case AudioService.STREAM_REMOTE_MUSIC: { + case STREAM_REMOTE_MUSIC: { if (controller == null && sc != null) { // If we weren't passed one try using the last one set. controller = sc.controller; @@ -1003,7 +1004,7 @@ public class VolumePanel extends Handler { } if (sc != null) { - if (streamType == AudioService.STREAM_REMOTE_MUSIC && controller != sc.controller) { + if (streamType == STREAM_REMOTE_MUSIC && controller != sc.controller) { if (sc.controller != null) { sc.controller.removeCallback(mMediaControllerCb); } @@ -1021,7 +1022,7 @@ public class VolumePanel extends Handler { } if (!isShowing()) { - int stream = (streamType == AudioService.STREAM_REMOTE_MUSIC) ? -1 : streamType; + int stream = (streamType == STREAM_REMOTE_MUSIC) ? -1 : streamType; // when the stream is for remote playback, use -1 to reset the stream type evaluation mAudioManager.forceVolumeControlStream(stream); mDialog.show(); @@ -1031,7 +1032,7 @@ public class VolumePanel extends Handler { } // Do a little vibrate if applicable (only when going into vibrate mode) - if ((streamType != AudioService.STREAM_REMOTE_MUSIC) && + if ((streamType != STREAM_REMOTE_MUSIC) && ((flags & AudioManager.FLAG_VIBRATE) != 0) && mAudioManager.isStreamAffectedByRingerMode(streamType) && mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) { @@ -1094,10 +1095,10 @@ public class VolumePanel extends Handler { if (((flags & AudioManager.FLAG_SHOW_UI) != 0) || isShowing()) { synchronized (this) { - if (mActiveStreamType != AudioService.STREAM_REMOTE_MUSIC) { - reorderSliders(AudioService.STREAM_REMOTE_MUSIC); + if (mActiveStreamType != STREAM_REMOTE_MUSIC) { + reorderSliders(STREAM_REMOTE_MUSIC); } - onShowVolumeChanged(AudioService.STREAM_REMOTE_MUSIC, flags, controller); + onShowVolumeChanged(STREAM_REMOTE_MUSIC, flags, controller); } } else { if (LOGD) Log.d(mTag, "not calling onShowVolumeChanged(), no FLAG_SHOW_UI or no UI"); @@ -1111,9 +1112,9 @@ public class VolumePanel extends Handler { protected void onRemoteVolumeUpdateIfShown() { if (LOGD) Log.d(mTag, "onRemoteVolumeUpdateIfShown()"); if (isShowing() - && (mActiveStreamType == AudioService.STREAM_REMOTE_MUSIC) + && (mActiveStreamType == STREAM_REMOTE_MUSIC) && (mStreamControls != null)) { - onShowVolumeChanged(AudioService.STREAM_REMOTE_MUSIC, 0, null); + onShowVolumeChanged(STREAM_REMOTE_MUSIC, 0, null); } } @@ -1122,7 +1123,7 @@ public class VolumePanel extends Handler { */ private void clearRemoteStreamController() { if (mStreamControls != null) { - StreamControl sc = mStreamControls.get(AudioService.STREAM_REMOTE_MUSIC); + StreamControl sc = mStreamControls.get(STREAM_REMOTE_MUSIC); if (sc != null) { if (sc.controller != null) { sc.controller.removeCallback(mMediaControllerCb); @@ -1133,10 +1134,10 @@ public class VolumePanel extends Handler { } /** - * Handler for MSG_SLIDER_VISIBILITY_CHANGED - * Hide or show a slider - * @param streamType can be a valid stream type value, or VolumePanel.STREAM_MASTER, - * or AudioService.STREAM_REMOTE_MUSIC + * Handler for MSG_SLIDER_VISIBILITY_CHANGED Hide or show a slider + * + * @param streamType can be a valid stream type value, or + * VolumePanel.STREAM_MASTER, or VolumePanel.STREAM_REMOTE_MUSIC * @param visible */ synchronized protected void onSliderVisibilityChanged(int streamType, int visible) { diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java index 04a3b88345b7..0586a83d12ab 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java @@ -1,6 +1,5 @@ package com.android.systemui.volume; -import android.app.ActivityManagerNative; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; @@ -18,10 +17,12 @@ import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.util.Log; +import android.view.WindowManagerGlobal; import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.keyguard.KeyguardViewMediator; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.statusbar.policy.ZenModeControllerImpl; @@ -138,22 +139,8 @@ public class VolumeUI extends SystemUI { private final Runnable mStartZenSettings = new Runnable() { @Override public void run() { - AsyncTask.execute(new Runnable() { - @Override - public void run() { - try { - // Dismiss the lock screen when Settings starts. - ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); - } catch (RemoteException e) { - } - final Intent intent = ZenModePanel.ZEN_SETTINGS; - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); - - // dismiss shade if showing - mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); - } - }); + getComponent(PhoneStatusBar.class).startActivityDismissingKeyguard( + ZenModePanel.ZEN_SETTINGS, true /* onlyProvisioned */, true /* dismissShade */); mPanel.postDismiss(mDismissDelay); } }; diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index ca260ecf9ce2..3f7c72ec4300 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -845,16 +845,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { break; case SHORT_PRESS_POWER_GO_TO_SLEEP: mPowerManager.goToSleep(eventTime, - PowerManager.GO_TO_SLEEP_REASON_USER, 0); + PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); break; case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP: mPowerManager.goToSleep(eventTime, - PowerManager.GO_TO_SLEEP_REASON_USER, + PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); break; case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME: mPowerManager.goToSleep(eventTime, - PowerManager.GO_TO_SLEEP_REASON_USER, + PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); launchHomeFromHotKey(); break; @@ -2064,8 +2064,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - public Animation createForceHideEnterAnimation(boolean onWallpaper) { - if (onWallpaper) { + public Animation createForceHideEnterAnimation(boolean onWallpaper, + boolean goingToNotificationShade) { + if (goingToNotificationShade) { + return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in); + } else if (onWallpaper) { Animation a = AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_wallpaper); AnimationSet set = (AnimationSet) a; @@ -2073,7 +2076,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { // TODO: Use XML interpolators when we have log interpolators available in XML. set.getAnimations().get(0).setInterpolator(mLogDecelerateInterpolator); set.getAnimations().get(1).setInterpolator(mLogDecelerateInterpolator); - set.getAnimations().get(2).setInterpolator(mLogDecelerateInterpolator); return set; } else { Animation a = AnimationUtils.loadAnimation(mContext, @@ -2088,8 +2090,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override - public Animation createForceHideWallpaperExitAnimation() { - return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_wallpaper_exit); + public Animation createForceHideWallpaperExitAnimation(boolean goingToNotificationShade) { + if (goingToNotificationShade) { + return null; + } else { + return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_wallpaper_exit); + } } private static void awakenDreams() { @@ -4290,7 +4296,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if ((mEndcallBehavior & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) { - mPowerManager.goToSleep(event.getEventTime()); + mPowerManager.goToSleep(event.getEventTime(), + PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); isWakeKey = false; } } @@ -4347,7 +4354,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (!mPowerManager.isInteractive()) { useHapticFeedback = false; // suppress feedback if already non-interactive } - mPowerManager.goToSleep(event.getEventTime()); + mPowerManager.goToSleep(event.getEventTime(), + PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); isWakeKey = false; break; } @@ -4766,13 +4774,19 @@ public class PhoneWindowManager implements WindowManagerPolicy { mHandler.post(new Runnable() { @Override public void run() { - if (mKeyguardDelegate.isDismissable()) { - // Can we just finish the keyguard straight away? - mKeyguardDelegate.keyguardDone(false, true); - } else { - // ask the keyguard to prompt the user to authenticate if necessary - mKeyguardDelegate.dismiss(); - } + // ask the keyguard to prompt the user to authenticate if necessary + mKeyguardDelegate.dismiss(); + } + }); + } + } + + public void notifyActivityDrawnForKeyguardLw() { + if (mKeyguardDelegate != null) { + mHandler.post(new Runnable() { + @Override + public void run() { + mKeyguardDelegate.onActivityDrawn(); } }); } @@ -5246,7 +5260,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private void applyLidSwitchState() { if (mLidState == LID_CLOSED && mLidControlsSleep) { mPowerManager.goToSleep(SystemClock.uptimeMillis(), - PowerManager.GO_TO_SLEEP_REASON_USER, + PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java index 63a585072663..aac02add704e 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java @@ -334,4 +334,9 @@ public class KeyguardServiceDelegate { mKeyguardState.bootCompleted = true; } + public void onActivityDrawn() { + if (mKeyguardService != null) { + mKeyguardService.onActivityDrawn(); + } + } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java index 5096bd3eae99..2778b153f953 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java @@ -198,6 +198,14 @@ public class KeyguardServiceWrapper implements IKeyguardService { } } + public void onActivityDrawn() { + try { + mService.onActivityDrawn(); + } catch (RemoteException e) { + Slog.w(TAG , "Remote Exception", e); + } + } + public void showAssistant() { // Not used by PhoneWindowManager } diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java index ac76ddfb8bde..7db85f26bded 100644 --- a/rs/java/android/renderscript/Allocation.java +++ b/rs/java/android/renderscript/Allocation.java @@ -1341,9 +1341,13 @@ public class Allocation extends BaseObj { * @param dimX The new size of the allocation. * * @deprecated RenderScript objects should be immutable once created. The - * replacement is to create a new allocation and copy the contents. + * replacement is to create a new allocation and copy the contents. This + * function will throw an exception if API 21 or higher is used. */ public synchronized void resize(int dimX) { + if (mRS.getApplicationContext().getApplicationInfo().targetSdkVersion >= 21) { + throw new RSRuntimeException("Resize is not allowed in API 21+."); + } if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { throw new RSInvalidStateException("Resize only support for 1D allocations at this time."); } diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 21e56702b6ad..e9419ad02489 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -19,7 +19,6 @@ package com.android.server; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManagerNative; -import android.app.AlarmClockInfo; import android.app.AlarmManager; import android.app.IAlarmManager; import android.app.PendingIntent; @@ -129,14 +128,17 @@ class AlarmManagerService extends SystemService { long mStartCurrentDelayTime; long mNextNonWakeupDeliveryTime; - private final SparseArray<AlarmClockInfo> mNextAlarmClockForUser = new SparseArray<>(); - private final SparseArray<AlarmClockInfo> mTmpSparseAlarmClockArray = new SparseArray<>(); + private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = + new SparseArray<>(); + private final SparseArray<AlarmManager.AlarmClockInfo> mTmpSparseAlarmClockArray = + new SparseArray<>(); private final SparseBooleanArray mPendingSendNextAlarmClockChangedForUser = new SparseBooleanArray(); private boolean mNextAlarmClockMayChange; // May only use on mHandler's thread, locking not required. - private final SparseArray<AlarmClockInfo> mHandlerSparseAlarmClockArray = new SparseArray<>(); + private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray = + new SparseArray<>(); class WakeupEvent { public long when; @@ -619,7 +621,7 @@ class AlarmManagerService extends SystemService { void setImpl(int type, long triggerAtTime, long windowLength, long interval, PendingIntent operation, boolean isStandalone, WorkSource workSource, - AlarmClockInfo alarmClock) { + AlarmManager.AlarmClockInfo alarmClock) { if (operation == null) { Slog.w(TAG, "set/setRepeating ignored because there is no intent"); return; @@ -672,7 +674,8 @@ class AlarmManagerService extends SystemService { private void setImplLocked(int type, long when, long whenElapsed, long windowLength, long maxWhen, long interval, PendingIntent operation, boolean isStandalone, - boolean doValidate, WorkSource workSource, AlarmClockInfo alarmClock, int userId) { + boolean doValidate, WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock, + int userId) { Alarm a = new Alarm(type, when, whenElapsed, windowLength, maxWhen, interval, operation, workSource, alarmClock, userId); removeLocked(operation); @@ -714,7 +717,8 @@ class AlarmManagerService extends SystemService { private final IBinder mService = new IAlarmManager.Stub() { @Override public void set(int type, long triggerAtTime, long windowLength, long interval, - PendingIntent operation, WorkSource workSource, AlarmClockInfo alarmClock) { + PendingIntent operation, WorkSource workSource, + AlarmManager.AlarmClockInfo alarmClock) { if (workSource != null) { getContext().enforceCallingPermission( android.Manifest.permission.UPDATE_DEVICE_STATS, @@ -762,7 +766,7 @@ class AlarmManagerService extends SystemService { } @Override - public AlarmClockInfo getNextAlarmClock(int userId) { + public AlarmManager.AlarmClockInfo getNextAlarmClock(int userId) { userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false /* allowAll */, false /* requireFull */, "getNextAlarmClock", null); @@ -1009,7 +1013,7 @@ class AlarmManagerService extends SystemService { return null; } - private AlarmClockInfo getNextAlarmClockImpl(int userId) { + private AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) { synchronized (mLock) { return mNextAlarmClockForUser.get(userId); } @@ -1024,7 +1028,7 @@ class AlarmManagerService extends SystemService { } mNextAlarmClockMayChange = false; - SparseArray<AlarmClockInfo> nextForUser = mTmpSparseAlarmClockArray; + SparseArray<AlarmManager.AlarmClockInfo> nextForUser = mTmpSparseAlarmClockArray; nextForUser.clear(); final int N = mAlarmBatches.size(); @@ -1054,9 +1058,9 @@ class AlarmManagerService extends SystemService { // Update mNextAlarmForUser with new values. final int NN = nextForUser.size(); for (int i = 0; i < NN; i++) { - AlarmClockInfo newAlarm = nextForUser.valueAt(i); + AlarmManager.AlarmClockInfo newAlarm = nextForUser.valueAt(i); int userId = nextForUser.keyAt(i); - AlarmClockInfo currentAlarm = mNextAlarmClockForUser.get(userId); + AlarmManager.AlarmClockInfo currentAlarm = mNextAlarmClockForUser.get(userId); if (!newAlarm.equals(currentAlarm)) { updateNextAlarmInfoForUserLocked(userId, newAlarm); } @@ -1072,7 +1076,8 @@ class AlarmManagerService extends SystemService { } } - private void updateNextAlarmInfoForUserLocked(int userId, AlarmClockInfo alarmClock) { + private void updateNextAlarmInfoForUserLocked(int userId, + AlarmManager.AlarmClockInfo alarmClock) { if (alarmClock != null) { if (DEBUG_ALARM_CLOCK) { Log.v(TAG, "Next AlarmClockInfoForUser(" + userId + "): " + @@ -1100,7 +1105,7 @@ class AlarmManagerService extends SystemService { * @see AlarmHandler#SEND_NEXT_ALARM_CLOCK_CHANGED */ private void sendNextAlarmClockChanged() { - SparseArray<AlarmClockInfo> pendingUsers = mHandlerSparseAlarmClockArray; + SparseArray<AlarmManager.AlarmClockInfo> pendingUsers = mHandlerSparseAlarmClockArray; pendingUsers.clear(); synchronized (mLock) { @@ -1115,7 +1120,7 @@ class AlarmManagerService extends SystemService { final int N = pendingUsers.size(); for (int i = 0; i < N; i++) { int userId = pendingUsers.keyAt(i); - AlarmClockInfo alarmClock = pendingUsers.valueAt(i); + AlarmManager.AlarmClockInfo alarmClock = pendingUsers.valueAt(i); Settings.System.putStringForUser(getContext().getContentResolver(), Settings.System.NEXT_ALARM_FORMATTED, formatNextAlarm(getContext(), alarmClock), @@ -1129,7 +1134,7 @@ class AlarmManagerService extends SystemService { /** * Formats an alarm like platform/packages/apps/DeskClock used to. */ - private static String formatNextAlarm(final Context context, AlarmClockInfo info) { + private static String formatNextAlarm(final Context context, AlarmManager.AlarmClockInfo info) { String skeleton = DateFormat.is24HourFormat(context) ? "EHm" : "Ehma"; String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton); return (info == null) ? "" : @@ -1414,12 +1419,12 @@ class AlarmManagerService extends SystemService { public long whenElapsed; // 'when' in the elapsed time base public long maxWhen; // also in the elapsed time base public long repeatInterval; - public final AlarmClockInfo alarmClock; + public final AlarmManager.AlarmClockInfo alarmClock; public final int userId; public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen, - long _interval, PendingIntent _op, WorkSource _ws, AlarmClockInfo _info, - int _userId) { + long _interval, PendingIntent _op, WorkSource _ws, + AlarmManager.AlarmClockInfo _info, int _userId) { type = _type; wakeup = _type == AlarmManager.ELAPSED_REALTIME_WAKEUP || _type == AlarmManager.RTC_WAKEUP; diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index b229c4f39b98..dd5a7ea5f6c4 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -372,6 +372,11 @@ public class ConnectivityService extends IConnectivityManager.Stub { */ private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24; + /** + * Used internally to indicate the system is ready. + */ + private static final int EVENT_SYSTEM_READY = 25; + /** Handler used for internal events. */ final private InternalHandler mHandler; @@ -1437,6 +1442,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { final IntentFilter filter = new IntentFilter(Intent.ACTION_USER_PRESENT); mContext.registerReceiver(mUserPresentReceiver, filter); } + + mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY)); } private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() { @@ -2270,6 +2277,12 @@ public class ConnectivityService extends IConnectivityManager.Stub { handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1); break; } + case EVENT_SYSTEM_READY: { + for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { + nai.networkMonitor.systemReady = true; + } + break; + } } } } @@ -4108,6 +4121,9 @@ public class ConnectivityService extends IConnectivityManager.Stub { new NetworkInfo(networkInfo), new LinkProperties(linkProperties), new NetworkCapabilities(networkCapabilities), currentScore, mContext, mTrackerHandler, networkMisc); + synchronized (this) { + nai.networkMonitor.systemReady = mSystemReady; + } if (VDBG) log("registerNetworkAgent " + nai); mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai)); } diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index 4c6b772ee8ab..6ab52c611a3f 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -479,7 +479,7 @@ final class UiModeManagerService extends SystemService { // keep screen on when charging and in car mode boolean keepScreenOn = mCharging && ((mCarModeEnabled && mCarModeKeepsScreenOn && - (mCarModeEnableFlags & UiModeManager.ENABLE_CAR_MODE_NO_WAKE_LOCK) == 0) || + (mCarModeEnableFlags & UiModeManager.ENABLE_CAR_MODE_ALLOW_SLEEP) == 0) || (mCurUiMode == Configuration.UI_MODE_TYPE_DESK && mDeskModeKeepsScreenOn)); if (keepScreenOn != mWakeLock.isHeld()) { if (keepScreenOn) { diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index d6e51f366ebc..0bdb964a1409 100755 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import android.os.DeadObjectException; import android.os.Handler; import android.os.Looper; import android.os.SystemProperties; @@ -1424,6 +1425,9 @@ public final class ActiveServices { app.repProcState); r.postNotification(); created = true; + } catch (DeadObjectException e) { + Slog.w(TAG, "Application dead when creating service " + r); + mAm.appDiedLocked(app); } finally { if (!created) { app.services.remove(r); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 6054401d2d36..ad2704ae5bcc 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -4201,6 +4201,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } + final void appDiedLocked(ProcessRecord app) { + appDiedLocked(app, app.pid, app.thread); + } + final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { @@ -5639,17 +5643,13 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public void dismissKeyguardOnNextActivity() { - enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); + public void keyguardWaitingForActivityDrawn() { + enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); final long token = Binder.clearCallingIdentity(); try { synchronized (this) { if (DEBUG_LOCKSCREEN) logLockScreen(""); - if (mLockScreenShown) { - mLockScreenShown = false; - comeOutOfSleepIfNeededLocked(); - } - mStackSupervisor.setDismissKeyguard(true); + mWindowManager.keyguardWaitingForActivityDrawn(); } } finally { Binder.restoreCallingIdentity(token); @@ -5794,13 +5794,13 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public final void mediaResourcesReleased(IBinder token) { + public final void backgroundResourcesReleased(IBinder token) { final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { ActivityStack stack = ActivityRecord.getStackLocked(token); if (stack != null) { - stack.mediaResourcesReleased(token); + stack.backgroundResourcesReleased(token); } } } finally { @@ -8478,7 +8478,7 @@ public final class ActivityManagerService extends ActivityManagerNative "Existing provider " + cpr.name.flattenToShortString() + " is crashing; detaching " + r); boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); - appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); + appDiedLocked(cpr.proc); if (!lastRef) { // This wasn't the last ref our process had on // the provider... we have now been killed, bail. @@ -8928,7 +8928,7 @@ public final class ActivityManagerService extends ActivityManagerNative + ") early provider death"); final long ident = Binder.clearCallingIdentity(); try { - appDiedLocked(proc, proc.pid, proc.thread); + appDiedLocked(proc); } finally { Binder.restoreCallingIdentity(ident); } @@ -9263,8 +9263,7 @@ public final class ActivityManagerService extends ActivityManagerNative void logLockScreen(String msg) { if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + - mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + - mStackSupervisor.mDismissKeyguardOnNextActivity); + mWentToSleep + " mSleeping=" + mSleeping); } private void comeOutOfSleepIfNeededLocked() { @@ -9663,7 +9662,7 @@ public final class ActivityManagerService extends ActivityManagerNative } if (r.changeWindowTranslucency(true)) { mWindowManager.setAppFullscreen(token, true); - r.task.stack.releaseMediaResources(); + r.task.stack.releaseBackgroundResources(); mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); return true; } @@ -9704,13 +9703,13 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public boolean setMediaPlaying(IBinder token, boolean playing) { + public boolean requestVisibleBehind(IBinder token, boolean visible) { final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { final ActivityRecord r = ActivityRecord.isInStackLocked(token); if (r != null) { - return mStackSupervisor.setMediaPlayingLocked(r, playing); + return mStackSupervisor.requestVisibleBehindLocked(r, visible); } } return false; @@ -9720,15 +9719,15 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public boolean isBackgroundMediaPlaying(IBinder token) { + public boolean isBackgroundVisibleBehind(IBinder token) { final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { final ActivityStack stack = ActivityRecord.getStackLocked(token); - final boolean playing = stack == null ? false : stack.isMediaPlaying(); - if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, - "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing); - return playing; + final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); + if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, + "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); + return visible; } } finally { Binder.restoreCallingIdentity(origId); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 465374246a04..e309a037a0c5 100755 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -46,7 +46,6 @@ import com.android.internal.os.BatteryStatsImpl; import com.android.server.Watchdog; import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.am.ActivityStackSupervisor.ActivityContainer; -import com.android.server.am.ActivityStackSupervisor.ActivityDisplay; import com.android.server.wm.AppTransition; import com.android.server.wm.TaskGroup; import com.android.server.wm.WindowManagerService; @@ -249,7 +248,7 @@ final class ActivityStack { static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4; static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5; static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6; - static final int STOP_MEDIA_PLAYING_TIMEOUT_MSG = + static final int RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7; static class ScheduleDestroyArgs { @@ -325,10 +324,10 @@ final class ActivityStack { notifyActivityDrawnLocked(null); } } break; - case STOP_MEDIA_PLAYING_TIMEOUT_MSG: { + case RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG: { synchronized (mService) { - final ActivityRecord r = getMediaPlayer(); - Slog.e(TAG, "Timeout waiting for stopMediaPlaying player=" + r); + final ActivityRecord r = getVisibleBehindActivity(); + Slog.e(TAG, "Timeout waiting for cancelVisibleBehind player=" + r); if (r != null) { mService.killAppAtUsersRequest(r.app, null); } @@ -935,8 +934,8 @@ final class ActivityStack { mHandler.removeMessages(STOP_TIMEOUT_MSG, r); r.stopped = true; r.state = ActivityState.STOPPED; - if (mActivityContainer.mActivityDisplay.mMediaPlayingActivity == r) { - mStackSupervisor.setMediaPlayingLocked(r, false); + if (mActivityContainer.mActivityDisplay.mVisibleBehindActivity == r) { + mStackSupervisor.requestVisibleBehindLocked(r, false); } if (r.finishing) { r.clearOptionsLocked(); @@ -975,8 +974,8 @@ final class ActivityStack { // the current instance before starting the new one. if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev); destroyActivityLocked(prev, true, "pause-config"); - } else if (!isMediaPlaying()) { - // If we were playing then resumeTopActivities will release resources before + } else if (!hasVisibleBehindActivity()) { + // If we were visible then resumeTopActivities will release resources before // stopping. mStackSupervisor.mStoppingActivities.add(prev); if (mStackSupervisor.mStoppingActivities.size() > 3 || @@ -1059,7 +1058,7 @@ final class ActivityStack { if (next.nowVisible) { // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now. - mStackSupervisor.dismissKeyguard(); + mStackSupervisor.notifyActivityDrawnForKeyguard(); } // schedule an idle timeout in case the app doesn't do it for us. @@ -1333,8 +1332,8 @@ final class ActivityStack { case PAUSED: // This case created for transitioning activities from // translucent to opaque {@link Activity#convertToOpaque}. - if (getMediaPlayer() == r) { - releaseMediaResources(); + if (getVisibleBehindActivity() == r) { + releaseBackgroundResources(); } else { if (!mStackSupervisor.mStoppingActivities.contains(r)) { mStackSupervisor.mStoppingActivities.add(r); @@ -2937,8 +2936,8 @@ final class ActivityStack { // Get rid of any pending idle timeouts. removeTimeoutsForActivityLocked(r); - if (getMediaPlayer() == r) { - mStackSupervisor.setMediaPlayingLocked(r, false); + if (getVisibleBehindActivity() == r) { + mStackSupervisor.requestVisibleBehindLocked(r, false); } } @@ -3160,47 +3159,48 @@ final class ActivityStack { } } - void releaseMediaResources() { - if (isMediaPlaying() && !mHandler.hasMessages(STOP_MEDIA_PLAYING_TIMEOUT_MSG)) { - final ActivityRecord r = getMediaPlayer(); - if (DEBUG_STATES) Slog.d(TAG, "releaseMediaResources activtyDisplay=" + - mActivityContainer.mActivityDisplay + " mediaPlayer=" + r + " app=" + r.app + + void releaseBackgroundResources() { + if (hasVisibleBehindActivity() && + !mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) { + final ActivityRecord r = getVisibleBehindActivity(); + if (DEBUG_STATES) Slog.d(TAG, "releaseBackgroundResources activtyDisplay=" + + mActivityContainer.mActivityDisplay + " visibleBehind=" + r + " app=" + r.app + " thread=" + r.app.thread); if (r != null && r.app != null && r.app.thread != null) { try { - r.app.thread.scheduleStopMediaPlaying(r.appToken); + r.app.thread.scheduleCancelVisibleBehind(r.appToken); } catch (RemoteException e) { } - mHandler.sendEmptyMessageDelayed(STOP_MEDIA_PLAYING_TIMEOUT_MSG, 500); + mHandler.sendEmptyMessageDelayed(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG, 500); } else { - Slog.e(TAG, "releaseMediaResources: activity " + r + " no longer running"); - mediaResourcesReleased(r.appToken); + Slog.e(TAG, "releaseBackgroundResources: activity " + r + " no longer running"); + backgroundResourcesReleased(r.appToken); } } } - final void mediaResourcesReleased(IBinder token) { - mHandler.removeMessages(STOP_MEDIA_PLAYING_TIMEOUT_MSG); - final ActivityRecord r = getMediaPlayer(); + final void backgroundResourcesReleased(IBinder token) { + mHandler.removeMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG); + final ActivityRecord r = getVisibleBehindActivity(); if (r != null) { mStackSupervisor.mStoppingActivities.add(r); - setMediaPlayer(null); + setVisibleBehindActivity(null); } mStackSupervisor.resumeTopActivitiesLocked(); } - boolean isMediaPlaying() { - return isAttached() && mActivityContainer.mActivityDisplay.isMediaPlaying(); + boolean hasVisibleBehindActivity() { + return isAttached() && mActivityContainer.mActivityDisplay.hasVisibleBehindActivity(); } - void setMediaPlayer(ActivityRecord r) { + void setVisibleBehindActivity(ActivityRecord r) { if (isAttached()) { - mActivityContainer.mActivityDisplay.setMediaPlaying(r); + mActivityContainer.mActivityDisplay.setVisibleBehindActivity(r); } } - ActivityRecord getMediaPlayer() { - return isAttached() ? mActivityContainer.mActivityDisplay.mMediaPlayingActivity : null; + ActivityRecord getVisibleBehindActivity() { + return isAttached() ? mActivityContainer.mActivityDisplay.mVisibleBehindActivity : null; } private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list, diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 3d23cb73990e..110713983bfc 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -115,7 +115,7 @@ public final class ActivityStackSupervisor implements DisplayListener { static final boolean DEBUG_APP = DEBUG || false; static final boolean DEBUG_CONTAINERS = DEBUG || false; static final boolean DEBUG_IDLE = DEBUG || false; - static final boolean DEBUG_MEDIA_VISIBILITY = DEBUG || false; + static final boolean DEBUG_VISIBLE_BEHIND = DEBUG || false; static final boolean DEBUG_SAVED_STATE = DEBUG || false; static final boolean DEBUG_SCREENSHOTS = DEBUG || false; static final boolean DEBUG_STATES = DEBUG || false; @@ -167,9 +167,6 @@ public final class ActivityStackSupervisor implements DisplayListener { WindowManagerService mWindowManager; DisplayManager mDisplayManager; - /** Dismiss the keyguard after the next activity is displayed? */ - boolean mDismissKeyguardOnNextActivity = false; - /** Identifier counter for all ActivityStacks */ private int mLastStackId = HOME_STACK_ID; @@ -363,12 +360,9 @@ public final class ActivityStackSupervisor implements DisplayListener { } } - void dismissKeyguard() { + void notifyActivityDrawnForKeyguard() { if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(""); - if (mDismissKeyguardOnNextActivity) { - mDismissKeyguardOnNextActivity = false; - mWindowManager.dismissKeyguard(); - } + mWindowManager.notifyActivityDrawnForKeyguard(); } ActivityStack getFocusedStack() { @@ -439,9 +433,8 @@ public final class ActivityStackSupervisor implements DisplayListener { return mService.startHomeActivityLocked(mCurrentUser); } - void setDismissKeyguard(boolean dismiss) { - if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(" dismiss=" + dismiss); - mDismissKeyguardOnNextActivity = dismiss; + void keyguardWaitingForActivityDrawn() { + mWindowManager.keyguardWaitingForActivityDrawn(); } TaskRecord anyTaskForIdLocked(int id) { @@ -660,7 +653,7 @@ public final class ActivityStackSupervisor implements DisplayListener { w.thisTime = w.totalTime; } mService.notifyAll(); - dismissKeyguard(); + notifyActivityDrawnForKeyguard(); } void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, @@ -1165,7 +1158,7 @@ public final class ActivityStackSupervisor implements DisplayListener { Slog.e(TAG, "Second failure launching " + r.intent.getComponent().flattenToShortString() + ", giving up", e); - mService.appDiedLocked(app, app.pid, app.thread); + mService.appDiedLocked(app); stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "2nd-crash", false); return false; @@ -1371,7 +1364,6 @@ public final class ActivityStackSupervisor implements DisplayListener { resultRecord, resultWho, requestCode, Activity.RESULT_CANCELED, null); } - setDismissKeyguard(false); ActivityOptions.abort(options); return err; } @@ -1386,7 +1378,6 @@ public final class ActivityStackSupervisor implements DisplayListener { resultRecord, resultWho, requestCode, Activity.RESULT_CANCELED, null); } - setDismissKeyguard(false); String msg; if (!aInfo.exported) { msg = "Permission Denial: starting " + intent.toString() @@ -1425,7 +1416,6 @@ public final class ActivityStackSupervisor implements DisplayListener { } // We pretend to the caller that it was really started, but // they will just get a cancel result. - setDismissKeyguard(false); ActivityOptions.abort(options); return ActivityManager.START_SUCCESS; } @@ -1444,7 +1434,6 @@ public final class ActivityStackSupervisor implements DisplayListener { PendingActivityLaunch pal = new PendingActivityLaunch(r, sourceRecord, startFlags, stack); mPendingActivityLaunches.add(pal); - setDismissKeyguard(false); ActivityOptions.abort(options); return ActivityManager.START_SWITCHES_CANCELED; } @@ -1466,12 +1455,12 @@ public final class ActivityStackSupervisor implements DisplayListener { err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options); - if (allPausedActivitiesComplete()) { + if (err < 0) { // If someone asked to have the keyguard dismissed on the next // activity start, but we are not actually doing an activity // switch... just dismiss the keyguard now, because we // probably want to see whatever is behind it. - dismissKeyguard(); + notifyActivityDrawnForKeyguard(); } return err; } @@ -1554,6 +1543,7 @@ public final class ActivityStackSupervisor implements DisplayListener { final Intent intent = r.intent; final int callingUid = r.launchedFromUid; + final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP; final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE; final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK; @@ -1809,8 +1799,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // If the top activity in the task is the root // activity, deliver this new intent to it if it // desires. - if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 - || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) + if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop) && intentActivity.realActivity.equals(r.realActivity)) { ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, intentActivity.task); @@ -1874,7 +1863,7 @@ public final class ActivityStackSupervisor implements DisplayListener { if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { if (top.app != null && top.app.thread != null) { if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 - || launchSingleInstance || launchSingleTask) { + || launchSingleTop || launchSingleTask) { ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task); // For paranoia, make sure we have correctly @@ -2651,21 +2640,21 @@ public final class ActivityStackSupervisor implements DisplayListener { } } - boolean setMediaPlayingLocked(ActivityRecord r, boolean playing) { + boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) { final ActivityStack stack = r.task.stack; if (stack == null) { - if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlaying: r=" + r + " playing=" + - playing + " stack is null"); + if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: r=" + r + " visible=" + + visible + " stack is null"); return false; } - final boolean isPlaying = stack.isMediaPlaying(); - if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlayer: r=" + r + " playing=" + - playing + " isPlaying=" + isPlaying); + final boolean isVisible = stack.hasVisibleBehindActivity(); + if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind r=" + r + " visible=" + + visible + " isVisible=" + isVisible); final ActivityRecord top = topRunningActivityLocked(); - if (top == null || top == r || (playing == isPlaying)) { - if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlaying: quick return"); - stack.setMediaPlayer(playing ? r : null); + if (top == null || top == r || (visible == isVisible)) { + if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: quick return"); + stack.setVisibleBehindActivity(visible ? r : null); return true; } @@ -2673,14 +2662,14 @@ public final class ActivityStackSupervisor implements DisplayListener { if (top.fullscreen || top.state != ActivityState.RESUMED || top.app == null || top.app.thread == null) { // Can't carry out this request. - if (DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, "setMediaPlaying: returning top.fullscreen=" + - top.fullscreen+ " top.state=" + top.state + " top.app=" + top.app + + if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning top.fullscreen=" + + top.fullscreen+ " top.state=" + top.state + " top.app=" + top.app + " top.app.thread=" + top.app.thread); return false; } - stack.setMediaPlayer(playing ? r : null); - if (!playing) { + stack.setVisibleBehindActivity(visible ? r : null); + if (!visible) { // Make the activity immediately above r opaque. final ActivityRecord next = stack.findNextTranslucentActivity(r); if (next != null) { @@ -2688,7 +2677,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } } try { - top.app.thread.scheduleBackgroundMediaPlayingChanged(top.appToken, playing); + top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible); } catch (RemoteException e) { } return true; @@ -2852,8 +2841,6 @@ public final class ActivityStackSupervisor implements DisplayListener { } public void dump(PrintWriter pw, String prefix) { - pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity="); - pw.println(mDismissKeyguardOnNextActivity); pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack); pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack); pw.print(prefix); pw.println("mSleepTimeout=" + mSleepTimeout); @@ -3715,7 +3702,7 @@ public final class ActivityStackSupervisor implements DisplayListener { * stacks, bottommost behind. Accessed directly by ActivityManager package classes */ final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>(); - ActivityRecord mMediaPlayingActivity; + ActivityRecord mVisibleBehindActivity; ActivityDisplay() { } @@ -3748,12 +3735,12 @@ public final class ActivityStackSupervisor implements DisplayListener { bounds.y = mDisplayInfo.appHeight; } - void setMediaPlaying(ActivityRecord r) { - mMediaPlayingActivity = r; + void setVisibleBehindActivity(ActivityRecord r) { + mVisibleBehindActivity = r; } - boolean isMediaPlaying() { - return mMediaPlayingActivity != null; + boolean hasVisibleBehindActivity() { + return mVisibleBehindActivity != null; } @Override diff --git a/services/core/java/com/android/server/am/LockTaskNotify.java b/services/core/java/com/android/server/am/LockTaskNotify.java index 6f9b23d181fd..cf65243f3f8a 100644 --- a/services/core/java/com/android/server/am/LockTaskNotify.java +++ b/services/core/java/com/android/server/am/LockTaskNotify.java @@ -19,6 +19,7 @@ package com.android.server.am; import android.content.Context; import android.os.Handler; import android.os.Message; +import android.view.accessibility.AccessibilityManager; import android.widget.Toast; import com.android.internal.R; @@ -32,9 +33,12 @@ public class LockTaskNotify { private final Context mContext; private final H mHandler; + private AccessibilityManager mAccessibilityManager; public LockTaskNotify(Context context) { mContext = context; + mAccessibilityManager = (AccessibilityManager) + mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); mHandler = new H(); } @@ -45,6 +49,9 @@ public class LockTaskNotify { public void handleShowToast(boolean isLocked) { String text = mContext.getString(isLocked ? R.string.lock_to_app_toast_locked : R.string.lock_to_app_toast); + if (!isLocked && mAccessibilityManager.isEnabled()) { + text = mContext.getString(R.string.lock_to_app_toast_accessible); + } Toast.makeText(mContext, text, Toast.LENGTH_LONG).show(); } diff --git a/services/core/java/com/android/server/am/LockToAppRequestDialog.java b/services/core/java/com/android/server/am/LockToAppRequestDialog.java index 0847b5246078..12dcf7eee57c 100644 --- a/services/core/java/com/android/server/am/LockToAppRequestDialog.java +++ b/services/core/java/com/android/server/am/LockToAppRequestDialog.java @@ -13,6 +13,7 @@ import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.util.Slog; import android.view.WindowManager; +import android.view.accessibility.AccessibilityManager; import android.widget.CheckBox; import com.android.internal.R; @@ -33,8 +34,12 @@ public class LockToAppRequestDialog implements OnClickListener { private ILockSettings mLockSettingsService; + private AccessibilityManager mAccessibilityService; + public LockToAppRequestDialog(Context context, ActivityManagerService activityManagerService) { mContext = context; + mAccessibilityService = (AccessibilityManager) + mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); mService = activityManagerService; } @@ -78,7 +83,9 @@ public class LockToAppRequestDialog implements OnClickListener { final int unlockStringId = getLockString(task.userId); final Resources r = Resources.getSystem(); - final String description= r.getString(R.string.lock_to_app_description); + final String description= r.getString(mAccessibilityService.isEnabled() + ? R.string.lock_to_app_description_accessible + : R.string.lock_to_app_description); AlertDialog.Builder builder = new AlertDialog.Builder(mContext) .setTitle(r.getString(R.string.lock_to_app_title)) .setMessage(description) diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index ae5eda35cb80..5057994b5bb9 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -217,6 +217,8 @@ public class NetworkMonitor extends StateMachine { private String mServer; private boolean mIsCaptivePortalCheckEnabled = false; + public boolean systemReady = false; + private State mDefaultState = new DefaultState(); private State mOfflineState = new OfflineState(); private State mValidatedState = new ValidatedState(); @@ -709,6 +711,8 @@ public class NetworkMonitor extends StateMachine { return; } + if (systemReady == false) return; + Intent latencyBroadcast = new Intent(ACTION_NETWORK_CONDITIONS_MEASURED); switch (mNetworkAgentInfo.networkInfo.getType()) { case ConnectivityManager.TYPE_WIFI: diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index 72ac29ab4566..e39f0b1323cd 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -265,7 +265,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter { mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE | DisplayDeviceInfo.FLAG_NEVER_BLANK; } - if ((mInfo.flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { + if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { mInfo.flags &= ~DisplayDeviceInfo.FLAG_NEVER_BLANK; } else { mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY; diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index 591cf257d897..24072539d60d 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -258,6 +258,12 @@ final class Constants { static final int MHL_RAP_ACTION_CONTENT_ON = 0x10; static final int MHL_RAP_ACTION_CONTENT_OFF = 0x11; + // MHL RAPK messages. + static final int MHL_RAPK_NO_ERROR = 0x00; + static final int MHL_RAPK_UNRECOGNIZED_ACTION = 0x01; + static final int MHL_RAPK_UNSUPPORTED_ACTION = 0x02; + static final int MHL_RAPK_RESPONDER_BUSY = 0x03; + static final int MHL_INVALID_ADOPTER_ID = -1; static final int MHL_INVALID_DEVICE_ID = -1; diff --git a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java index ed37ead245b7..d155e849d46e 100644 --- a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java +++ b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java @@ -23,7 +23,6 @@ import android.hardware.hdmi.IHdmiControlCallback; import android.os.RemoteException; import android.util.Slog; -import com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource; import com.android.server.hdmi.HdmiControlService.SendMessageCallback; /** @@ -42,9 +41,6 @@ final class DeviceSelectAction extends HdmiCecFeatureAction { // Time in milliseconds we wait for the device power status to turn to 'On'. private static final int TIMEOUT_POWER_ON_MS = 5 * 1000; - // Time in milliseconds we wait for <Active Source>. - private static final int TIMEOUT_ACTIVE_SOURCE_MS = 20 * 1000; - // The number of times we try to wake up the target device before we give up // and just send <Set Stream Path>. private static final int LOOP_COUNTER_MAX = 20; @@ -62,11 +58,6 @@ final class DeviceSelectAction extends HdmiCecFeatureAction { // maximum 100 seconds (20 * 5) before we give up and just send <Set Stream Path>. private static final int STATE_WAIT_FOR_DEVICE_POWER_ON = 3; - // State in which we wait for the <Active Source> in response to the command - // <Set Stream Path> we have sent. We wait as much as TIMEOUT_ACTIVE_SOURCE_MS - // before we give up and mark the action as failure. - private static final int STATE_WAIT_FOR_ACTIVE_SOURCE = 4; - private final HdmiDeviceInfo mTarget; private final IHdmiControlCallback mCallback; private final HdmiCecMessage mGivePowerStatus; @@ -129,16 +120,6 @@ final class DeviceSelectAction extends HdmiCecFeatureAction { return handleReportPowerStatus(params[0]); } return false; - case STATE_WAIT_FOR_ACTIVE_SOURCE: - if (opcode == Constants.MESSAGE_ACTIVE_SOURCE) { - int physicalAddress = HdmiUtils.twoBytesToInt(params); - ActiveSourceHandler - .create((HdmiCecLocalDeviceTv) localDevice(), mCallback) - .process(ActiveSource.of(cmd.getSource(), physicalAddress)); - finish(); - return true; - } - return false; default: break; } @@ -189,8 +170,8 @@ final class DeviceSelectAction extends HdmiCecFeatureAction { private void sendSetStreamPath() { sendCommand(HdmiCecMessageBuilder.buildSetStreamPath( getSourceAddress(), mTarget.getPhysicalAddress())); - mState = STATE_WAIT_FOR_ACTIVE_SOURCE; - addTimer(mState, TIMEOUT_ACTIVE_SOURCE_MS); + invokeCallback(HdmiControlManager.RESULT_SUCCESS); + finish(); } @Override @@ -213,10 +194,6 @@ final class DeviceSelectAction extends HdmiCecFeatureAction { mPowerStatusCounter++; queryDevicePowerStatus(); break; - case STATE_WAIT_FOR_ACTIVE_SOURCE: - invokeCallback(HdmiControlManager.RESULT_TIMEOUT); - finish(); - break; } } diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 0e57afdcef04..2818ea751d70 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -198,6 +198,10 @@ public final class HdmiControlService extends SystemService { @GuardedBy("mLock") private boolean mProhibitMode; + // Set to true while the input change by MHL is allowed. + @GuardedBy("mLock") + private boolean mMhlInputChangeEnabled; + // List of listeners registered by callers that want to get notified of // system audio mode changes. private final ArrayList<IHdmiSystemAudioModeChangeListener> @@ -269,6 +273,7 @@ public final class HdmiControlService extends SystemService { mPowerStatus = HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON; mProhibitMode = false; mHdmiControlEnabled = readBooleanSetting(Global.HDMI_CONTROL_ENABLED, true); + mMhlInputChangeEnabled = readBooleanSetting(Global.MHL_INPUT_SWITCHING_ENABLED, true); mCecController = HdmiCecController.create(this); if (mCecController != null) { @@ -353,10 +358,12 @@ public final class HdmiControlService extends SystemService { // No need to propagate to HAL. break; case Global.MHL_INPUT_SWITCHING_ENABLED: - setOption(OPTION_MHL_INPUT_SWITCHING, toInt(enabled)); + setMhlInputChangeEnabled(enabled); break; case Global.MHL_POWER_CHARGE_ENABLED: - setOption(OPTION_MHL_POWER_CHARGE, toInt(enabled)); + if (mMhlController != null) { + mMhlController.setOption(OPTION_MHL_POWER_CHARGE, toInt(enabled)); + } break; } } @@ -1578,7 +1585,7 @@ public final class HdmiControlService extends SystemService { assertRunOnServiceThread(); mStandbyMessageReceived = true; PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE); - pm.goToSleep(SystemClock.uptimeMillis()); + pm.goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_HDMI, 0); // PowerManger will send the broadcast Intent.ACTION_SCREEN_OFF and after this gets // the intent, the sequence will continue at onStandby(). } @@ -1741,4 +1748,20 @@ public final class HdmiControlService extends SystemService { assertRunOnServiceThread(); mActivePortId = portId; } + + void setMhlInputChangeEnabled(boolean enabled) { + if (mMhlController != null) { + mMhlController.setOption(OPTION_MHL_INPUT_SWITCHING, toInt(enabled)); + } + + synchronized (mLock) { + mMhlInputChangeEnabled = enabled; + } + } + + boolean isMhlInputChangeEnabled() { + synchronized (mLock) { + return mMhlInputChangeEnabled; + } + } } diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java index 201d9b4e92c0..753ae39e3d44 100644 --- a/services/core/java/com/android/server/location/GpsLocationProvider.java +++ b/services/core/java/com/android/server/location/GpsLocationProvider.java @@ -1372,6 +1372,7 @@ public class GpsLocationProvider implements LocationProviderInterface { switch (status) { case GPS_REQUEST_AGPS_DATA_CONN: if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN"); + Log.v(TAG, "Received SUPL IP addr[]: " + ipaddr); // Set mAGpsDataConnectionState before calling startUsingNetworkFeature // to avoid a race condition with handleUpdateNetworkState() mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; @@ -1380,6 +1381,7 @@ public class GpsLocationProvider implements LocationProviderInterface { if (ipaddr != null) { try { mAGpsDataConnectionIpAddr = InetAddress.getByAddress(ipaddr); + Log.v(TAG, "IP address converted to: " + mAGpsDataConnectionIpAddr); } catch (UnknownHostException e) { Log.e(TAG, "Bad IP Address: " + ipaddr, e); mAGpsDataConnectionIpAddr = null; @@ -1426,6 +1428,8 @@ public class GpsLocationProvider implements LocationProviderInterface { case GPS_AGPS_DATA_CONN_FAILED: if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); break; + default: + Log.d(TAG, "Received Unknown AGPS status: " + status); } } diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index e549ead6a034..f820a3c6f92e 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ParceledListSlice; import android.media.AudioManager; +import android.media.AudioManagerInternal; import android.media.MediaMetadata; import android.media.Rating; import android.media.VolumeProvider; @@ -52,6 +53,8 @@ import android.util.Log; import android.util.Slog; import android.view.KeyEvent; +import com.android.server.LocalServices; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.UUID; @@ -111,6 +114,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { // Volume handling fields private AudioAttributes mAudioAttrs; private AudioManager mAudioManager; + private AudioManagerInternal mAudioManagerInternal; private int mVolumeType = MediaSession.PLAYBACK_TYPE_LOCAL; private int mVolumeControlType = VolumeProvider.VOLUME_CONTROL_ABSOLUTE; private int mMaxVolume = 0; @@ -134,6 +138,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { mService = service; mHandler = new MessageHandler(handler.getLooper()); mAudioManager = (AudioManager) service.getContext().getSystemService(Context.AUDIO_SERVICE); + mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class); mAudioAttrs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(); } @@ -227,7 +232,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { * * @param direction The direction to adjust volume in. */ - public void adjustVolume(int direction, int flags) { + public void adjustVolume(int direction, int flags, String packageName, int uid) { if (isPlaybackActive(false)) { flags &= ~AudioManager.FLAG_PLAY_SOUND; } @@ -238,7 +243,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } if (mVolumeType == MediaSession.PLAYBACK_TYPE_LOCAL) { int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs); - mAudioManager.adjustStreamVolume(stream, direction, flags); + mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags, packageName, + uid); } else { if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) { // Nothing to do, the volume cannot be changed @@ -262,10 +268,10 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } } - public void setVolumeTo(int value, int flags) { + public void setVolumeTo(int value, int flags, String packageName, int uid) { if (mVolumeType == MediaSession.PLAYBACK_TYPE_LOCAL) { int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs); - mAudioManager.setStreamVolume(stream, value, flags); + mAudioManagerInternal.setStreamVolumeForUid(stream, value, flags, packageName, uid); } else { if (mVolumeControlType != VolumeProvider.VOLUME_CONTROL_ABSOLUTE) { // Nothing to do. The volume can't be set directly. @@ -397,6 +403,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return; } mDestroyed = true; + mHandler.post(MessageHandler.MSG_DESTROYED); } } @@ -575,6 +582,29 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } } + private void pushSessionDestroyed() { + synchronized (mLock) { + // This is the only method that may be (and can only be) called + // after the session is destroyed. + if (!mDestroyed) { + return; + } + for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) { + ISessionControllerCallback cb = mControllerCallbacks.get(i); + try { + cb.onSessionDestroyed(); + } catch (DeadObjectException e) { + Log.w(TAG, "Removing dead callback in pushEvent.", e); + mControllerCallbacks.remove(i); + } catch (RemoteException e) { + Log.w(TAG, "unexpected exception in pushEvent.", e); + } + } + // After notifying clear all listeners + mControllerCallbacks.clear(); + } + } + private PlaybackState getStateWithUpdatedPosition() { PlaybackState state = mPlaybackState; long duration = -1; @@ -919,6 +949,16 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public void registerCallbackListener(ISessionControllerCallback cb) { synchronized (mLock) { + // If this session is already destroyed tell the caller and + // don't add them. + if (mDestroyed) { + try { + cb.onSessionDestroyed(); + } catch (Exception e) { + // ignored + } + return; + } if (getControllerCbIndexForCb(cb) < 0) { mControllerCallbacks.add(cb); if (DEBUG) { @@ -984,20 +1024,22 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } @Override - public void adjustVolume(int direction, int flags) { + public void adjustVolume(int direction, int flags, String packageName) { + int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { - MediaSessionRecord.this.adjustVolume(direction, flags); + MediaSessionRecord.this.adjustVolume(direction, flags, packageName, uid); } finally { Binder.restoreCallingIdentity(token); } } @Override - public void setVolumeTo(int value, int flags) { + public void setVolumeTo(int value, int flags, String packageName) { + int uid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); try { - MediaSessionRecord.this.setVolumeTo(value, flags); + MediaSessionRecord.this.setVolumeTo(value, flags, packageName, uid); } finally { Binder.restoreCallingIdentity(token); } @@ -1123,6 +1165,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { private static final int MSG_SEND_EVENT = 6; private static final int MSG_UPDATE_SESSION_STATE = 7; private static final int MSG_UPDATE_VOLUME = 8; + private static final int MSG_DESTROYED = 9; public MessageHandler(Looper looper) { super(looper); @@ -1154,6 +1197,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { case MSG_UPDATE_VOLUME: pushVolumeUpdate(); break; + case MSG_DESTROYED: + pushSessionDestroyed(); } } diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 0514f48fc6d0..1221aa4af10f 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -812,7 +812,8 @@ public class MediaSessionService extends SystemService implements Monitor { Log.e(TAG, "Error adjusting default volume.", e); } } else { - session.adjustVolume(direction, flags); + session.adjustVolume(direction, flags, getContext().getPackageName(), + UserHandle.myUserId()); if (session.getPlaybackType() == MediaSession.PLAYBACK_TYPE_REMOTE && mRvc != null) { try { diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 3eb2b7e508a7..d6afe68fb213 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1761,26 +1761,27 @@ public class NotificationManagerService extends SystemService { if (hasValidSound) { boolean looping = (notification.flags & Notification.FLAG_INSISTENT) != 0; - int audioStreamType; - if (notification.audioStreamType >= 0) { - audioStreamType = notification.audioStreamType; + AudioAttributes audioAttributes; + if (notification.audioAttributes != null) { + audioAttributes = notification.audioAttributes; } else { - audioStreamType = DEFAULT_STREAM_TYPE; + audioAttributes = Notification.AUDIO_ATTRIBUTES_DEFAULT; } mSoundNotification = record; // do not play notifications if stream volume is 0 (typically because // ringer mode is silent) or if there is a user of exclusive audio focus - if ((mAudioManager.getStreamVolume(audioStreamType) != 0) - && !mAudioManager.isAudioFocusExclusive()) { + if ((mAudioManager.getStreamVolume( + AudioAttributes.toLegacyStreamType(audioAttributes)) != 0) + && !mAudioManager.isAudioFocusExclusive()) { final long identity = Binder.clearCallingIdentity(); try { final IRingtonePlayer player = mAudioManager.getRingtonePlayer(); if (player != null) { if (DBG) Slog.v(TAG, "Playing sound " + soundUri - + " on stream " + audioStreamType); + + " with attributes " + audioAttributes); player.playAsync(soundUri, record.sbn.getUser(), looping, - audioStreamType); + audioAttributes); buzzBeepBlinked = true; } } catch (RemoteException e) { @@ -2424,8 +2425,9 @@ public class NotificationManagerService extends SystemService { // pulse repeatedly mNotificationLight.setFlashing(ledARGB, Light.LIGHT_FLASH_TIMED, ledOnMS, ledOffMS); - mStatusBar.notificationLightPulse(ledARGB, ledOnMS, ledOffMS); } + // let SystemUI make an independent decision + mStatusBar.notificationLightPulse(ledARGB, ledOnMS, ledOffMS); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 6be6b6055bca..89bd1d4a589c 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -253,6 +253,10 @@ public class PackageManagerService extends IPackageManager.Stub { // package apks to install directory. private static final String INSTALL_PACKAGE_SUFFIX = "-"; + // Special value for {@code PackageParser.Package#cpuAbiOverride} to indicate + // that the cpuAbiOverride must be clear. + private static final String CLEAR_ABI_OVERRIDE = "-"; + static final int SCAN_MONITOR = 1<<0; static final int SCAN_NO_DEX = 1<<1; static final int SCAN_FORCE_DEX = 1<<2; @@ -3195,7 +3199,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (fromSource != null) { packageNames = fromSource.get(targetUserId); } - if (packageNames.contains(intent.getPackage())) { + if (packageNames != null && packageNames.contains(intent.getPackage())) { return true; } // We need the package name, so we try to resolve with the loosest flags possible @@ -4093,8 +4097,7 @@ public class PackageManagerService extends IPackageManager.Stub { continue; } try { - scanPackageLI(file, flags | PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, - null, null); + scanPackageLI(file, flags | PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null); } catch (PackageManagerException e) { Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); @@ -4175,7 +4178,7 @@ public class PackageManagerService extends IPackageManager.Stub { * Returns null in case of errors and the error code is stored in mLastScanError */ private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanMode, - long currentTime, UserHandle user, String abiOverride) throws PackageManagerException { + long currentTime, UserHandle user) throws PackageManagerException { if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); parseFlags |= mDefParseFlags; PackageParser pp = new PackageParser(); @@ -4371,7 +4374,7 @@ public class PackageManagerService extends IPackageManager.Stub { // Note that we invoke the following method only if we are about to unpack an application PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode - | SCAN_UPDATE_SIGNATURE, currentTime, user, abiOverride); + | SCAN_UPDATE_SIGNATURE, currentTime, user); /* * If the system app should be overridden by a previously installed @@ -4998,8 +5001,26 @@ public class PackageManagerService extends IPackageManager.Stub { return res; } + /** + * Derive the value of the {@code cpuAbiOverride} based on the provided + * value and an optional stored value from the package settings. + */ + private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { + String cpuAbiOverride = null; + + if (CLEAR_ABI_OVERRIDE.equals(abiOverride)) { + cpuAbiOverride = null; + } else if (abiOverride != null) { + cpuAbiOverride = abiOverride; + } else if (settings != null) { + cpuAbiOverride = settings.cpuAbiOverrideString; + } + + return cpuAbiOverride; + } + private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, - int scanMode, long currentTime, UserHandle user, String abiOverride) + int scanMode, long currentTime, UserHandle user) throws PackageManagerException { final File scanFile = new File(pkg.codePath); if (pkg.applicationInfo.getCodePath() == null || @@ -5155,7 +5176,7 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.w(TAG, "Package " + pkg.packageName + " was transferred to another, but its .apk remains"); } - + // Just create the setting, don't add it yet. For already existing packages // the PkgSetting exists already and doesn't have to be created. pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, @@ -5435,14 +5456,8 @@ public class PackageManagerService extends IPackageManager.Stub { final String path = scanFile.getPath(); final String codePath = pkg.applicationInfo.getCodePath(); + final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { - // For the case where we had previously uninstalled an update, get rid - // of any native binaries we might have unpackaged. Note that this assumes - // that system app updates were not installed via ASEC. - // - // TODO(multiArch): Is this cleanup really necessary ? - NativeLibraryHelper.removeNativeBinariesFromDirLI( - new File(codePath, LIB_DIR_NAME), false /* delete dirs */); setBundledAppAbisAndRoots(pkg, pkgSetting); // If we haven't found any native libraries for the app, check if it has @@ -5497,7 +5512,7 @@ public class PackageManagerService extends IPackageManager.Stub { // Warn if we've set an abiOverride for multi-lib packages.. // By definition, we need to copy both 32 and 64 bit libraries for // such packages. - if (abiOverride != null) { + if (pkg.cpuAbiOverride != null && !CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { Slog.w(TAG, "Ignoring abiOverride for multi arch application."); } @@ -5540,15 +5555,15 @@ public class PackageManagerService extends IPackageManager.Stub { } } } else { - String[] abiList = (abiOverride != null) ? - new String[] { abiOverride } : Build.SUPPORTED_ABIS; + String[] abiList = (cpuAbiOverride != null) ? + new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; // Enable gross and lame hacks for apps that are built with old // SDK tools. We must scan their APKs for renderscript bitcode and // not launch them if it's present. Don't bother checking on devices // that don't have 64 bit support. boolean needsRenderScriptOverride = false; - if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && abiOverride == null && + if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && NativeLibraryHelper.hasRenderscriptBitcode(handle)) { abiList = Build.SUPPORTED_32_BIT_ABIS; needsRenderScriptOverride = true; @@ -5569,8 +5584,8 @@ public class PackageManagerService extends IPackageManager.Stub { if (copyRet >= 0) { pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; - } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && abiOverride != null) { - pkg.applicationInfo.primaryCpuAbi = abiOverride; + } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { + pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; } else if (needsRenderScriptOverride) { pkg.applicationInfo.primaryCpuAbi = abiList[0]; } @@ -5615,6 +5630,10 @@ public class PackageManagerService extends IPackageManager.Stub { pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; + pkgSetting.cpuAbiOverrideString = cpuAbiOverride; + // Copy the derived override back to the parsed package, so that we can + // update the package settings accordingly. + pkg.cpuAbiOverride = cpuAbiOverride; Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" @@ -6241,7 +6260,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private static String calculateApkRoot(final String codePathString) { + private static String calculateBundledApkRoot(final String codePathString) { final File codePath = new File(codePathString); final File codeRoot; if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { @@ -6281,14 +6300,9 @@ public class PackageManagerService extends IPackageManager.Stub { final ApplicationInfo info = pkg.applicationInfo; final String codePath = pkg.codePath; final File codeFile = new File(codePath); - // If "/system/lib64/apkname" exists, assume that is the per-package - // native library directory to use; otherwise use "/system/lib/apkname". - final String apkRoot = calculateApkRoot(info.sourceDir); - final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info); final boolean asecApp = isForwardLocked(info) || isExternal(info); - info.nativeLibraryRootDir = null; info.nativeLibraryRootRequiresIsa = false; info.nativeLibraryDir = null; @@ -6297,6 +6311,9 @@ public class PackageManagerService extends IPackageManager.Stub { if (isApkFile(codeFile)) { // Monolithic install if (bundledApp) { + // If "/system/lib64/apkname" exists, assume that is the per-package + // native library directory to use; otherwise use "/system/lib/apkname". + final String apkRoot = calculateBundledApkRoot(info.sourceDir); final boolean is64Bit = VMRuntime.is64BitInstructionSet( getPrimaryInstructionSet(info)); @@ -6352,7 +6369,7 @@ public class PackageManagerService extends IPackageManager.Stub { // If "/system/lib64/apkname" exists, assume that is the per-package // native library directory to use; otherwise use "/system/lib/apkname". - final String apkRoot = calculateApkRoot(pkg.applicationInfo.sourceDir); + final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); setBundledAppAbi(pkg, apkRoot, apkName); // pkgSetting might be null during rescan following uninstall of updates // to a bundled app, so accommodate that possibility. The settings in @@ -9278,7 +9295,7 @@ public class PackageManagerService extends IPackageManager.Stub { // Warn if we've set an abiOverride for multi-lib packages.. // By definition, we need to copy both 32 and 64 bit libraries for // such packages. - if (abiOverride != null) { + if (abiOverride != null && !CLEAR_ABI_OVERRIDE.equals(abiOverride)) { Slog.w(TAG, "Ignoring abiOverride for multi arch application."); } @@ -9295,10 +9312,11 @@ public class PackageManagerService extends IPackageManager.Stub { maybeThrowExceptionForMultiArchCopy("Failure copying 64 bit native libraries", copyRet); } } else { - String[] abiList = (abiOverride != null) ? - new String[] { abiOverride } : Build.SUPPORTED_ABIS; + final String cpuAbiOverride = deriveAbiOverride(this.abiOverride, null /* package setting */); + String[] abiList = (cpuAbiOverride != null) ? + new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; - if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && abiOverride == null && + if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && NativeLibraryHelper.hasRenderscriptBitcode(handle)) { abiList = Build.SUPPORTED_32_BIT_ABIS; } @@ -9566,7 +9584,7 @@ public class PackageManagerService extends IPackageManager.Stub { final String newCachePath = imcs.copyPackageToContainer( originFile.getAbsolutePath(), cid, getEncryptKey(), isExternal(), - isFwdLocked(), abiOverride); + isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); if (newCachePath != null) { setCachePath(newCachePath); @@ -9917,7 +9935,7 @@ public class PackageManagerService extends IPackageManager.Stub { */ private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, - String installerPackageName, PackageInstalledInfo res, String abiOverride) { + String installerPackageName, PackageInstalledInfo res) { // Remember this for later, in case we need to rollback this install String pkgName = pkg.packageName; @@ -9944,7 +9962,7 @@ public class PackageManagerService extends IPackageManager.Stub { try { PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode, - System.currentTimeMillis(), user, abiOverride); + System.currentTimeMillis(), user); updateSettingsLI(newPackage, installerPackageName, null, null, res); // delete the partially installed application. the data directory will have to be @@ -9980,7 +9998,7 @@ public class PackageManagerService extends IPackageManager.Stub { private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, - String installerPackageName, PackageInstalledInfo res, String abiOverride) { + String installerPackageName, PackageInstalledInfo res) { PackageParser.Package oldPackage; String pkgName = pkg.packageName; int[] allUsers; @@ -10019,19 +10037,17 @@ public class PackageManagerService extends IPackageManager.Stub { boolean sysPkg = (isSystemApp(oldPackage)); if (sysPkg) { replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, - user, allUsers, perUserInstalled, installerPackageName, res, - abiOverride); + user, allUsers, perUserInstalled, installerPackageName, res); } else { replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, - user, allUsers, perUserInstalled, installerPackageName, res, - abiOverride); + user, allUsers, perUserInstalled, installerPackageName, res); } } private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, int[] allUsers, boolean[] perUserInstalled, - String installerPackageName, PackageInstalledInfo res, String abiOverride) { + String installerPackageName, PackageInstalledInfo res) { String pkgName = deletedPackage.packageName; boolean deletedPkg = true; boolean updatedSettings = false; @@ -10056,7 +10072,7 @@ public class PackageManagerService extends IPackageManager.Stub { deleteCodeCacheDirsLI(pkgName); try { final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, - scanMode | SCAN_UPDATE_TIME, System.currentTimeMillis(), user, abiOverride); + scanMode | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res); updatedSettings = true; } catch (PackageManagerException e) { @@ -10089,8 +10105,7 @@ public class PackageManagerService extends IPackageManager.Stub { int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; try { - scanPackageLI(restoreFile, oldParseFlags, oldScanMode, origUpdateTime, null, - null); + scanPackageLI(restoreFile, oldParseFlags, oldScanMode, origUpdateTime, null); } catch (PackageManagerException e) { Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " + e.getMessage()); @@ -10112,7 +10127,7 @@ public class PackageManagerService extends IPackageManager.Stub { private void replaceSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, int[] allUsers, boolean[] perUserInstalled, - String installerPackageName, PackageInstalledInfo res, String abiOverride) { + String installerPackageName, PackageInstalledInfo res) { if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg + ", old=" + deletedPackage); boolean updatedSettings = false; @@ -10172,7 +10187,7 @@ public class PackageManagerService extends IPackageManager.Stub { PackageParser.Package newPackage = null; try { - newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user, abiOverride); + newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user); if (newPackage.mExtras != null) { final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras; newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; @@ -10204,8 +10219,7 @@ public class PackageManagerService extends IPackageManager.Stub { } // Add back the old system package try { - scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user, - null); + scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user); } catch (PackageManagerException e) { Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); } @@ -10336,6 +10350,9 @@ public class PackageManagerService extends IPackageManager.Stub { return; } + // Mark that we have an install time CPU ABI override. + pkg.cpuAbiOverride = args.abiOverride; + String pkgName = res.name = pkg.packageName; if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) { @@ -10454,10 +10471,10 @@ public class PackageManagerService extends IPackageManager.Stub { if (replace) { replacePackageLI(pkg, parseFlags, scanMode, args.user, - installerPackageName, res, args.abiOverride); + installerPackageName, res); } else { installNewPackageLI(pkg, parseFlags, scanMode | SCAN_DELETE_DATA_ON_FAILURES, args.user, - installerPackageName, res, args.abiOverride); + installerPackageName, res); } synchronized (mPackages) { final PackageSetting ps = mSettings.mPackages.get(pkgName); @@ -10893,8 +10910,7 @@ public class PackageManagerService extends IPackageManager.Stub { final PackageParser.Package newPkg; try { - newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, - null, null); + newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, null); } catch (PackageManagerException e) { Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage()); return false; @@ -12852,7 +12868,7 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mInstallLock) { PackageParser.Package pkg = null; try { - pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null, null); + pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null); } catch (PackageManagerException e) { Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); } diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java index a6571cf7b1ee..696aa34b9511 100644 --- a/services/core/java/com/android/server/pm/PackageSetting.java +++ b/services/core/java/com/android/server/pm/PackageSetting.java @@ -31,9 +31,11 @@ final class PackageSetting extends PackageSettingBase { PackageSetting(String name, String realName, File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, - String secondaryCpuAbiString, int pVersionCode, int pkgFlags) { + String secondaryCpuAbiString, String cpuAbiOverrideString, + int pVersionCode, int pkgFlags) { super(name, realName, codePath, resourcePath, legacyNativeLibraryPathString, - primaryCpuAbiString, secondaryCpuAbiString, pVersionCode, pkgFlags); + primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, + pVersionCode, pkgFlags); } /** diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index e29332cd249d..bf13fd97f5c6 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -64,8 +64,25 @@ class PackageSettingBase extends GrantedPermissions { @Deprecated String legacyNativeLibraryPathString; + /** + * The primary CPU abi for this package. This value is regenerated at every + * boot scan. + */ String primaryCpuAbiString; + + /** + * The secondary CPU abi for this package. This value is regenerated at every + * boot scan. + */ String secondaryCpuAbiString; + + /** + * The install time CPU override, if any. This value is written at install time + * and doesn't change during the life of an install. If non-null, + * {@code primaryCpuAbiString} will contain the same value. + */ + String cpuAbiOverrideString; + long timeStamp; long firstInstallTime; long lastUpdateTime; @@ -94,12 +111,13 @@ class PackageSettingBase extends GrantedPermissions { String installerPackageName; PackageSettingBase(String name, String realName, File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, - String secondaryCpuAbiString, int pVersionCode, int pkgFlags) { + String secondaryCpuAbiString, String cpuAbiOverrideString, + int pVersionCode, int pkgFlags) { super(pkgFlags); this.name = name; this.realName = realName; init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString, - secondaryCpuAbiString, pVersionCode); + secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode); } /** @@ -118,6 +136,7 @@ class PackageSettingBase extends GrantedPermissions { legacyNativeLibraryPathString = base.legacyNativeLibraryPathString; primaryCpuAbiString = base.primaryCpuAbiString; secondaryCpuAbiString = base.secondaryCpuAbiString; + cpuAbiOverrideString = base.cpuAbiOverrideString; timeStamp = base.timeStamp; firstInstallTime = base.firstInstallTime; lastUpdateTime = base.lastUpdateTime; @@ -145,7 +164,8 @@ class PackageSettingBase extends GrantedPermissions { } void init(File codePath, File resourcePath, String legacyNativeLibraryPathString, - String primaryCpuAbiString, String secondaryCpuAbiString, int pVersionCode) { + String primaryCpuAbiString, String secondaryCpuAbiString, + String cpuAbiOverrideString, int pVersionCode) { this.codePath = codePath; this.codePathString = codePath.toString(); this.resourcePath = resourcePath; @@ -153,6 +173,7 @@ class PackageSettingBase extends GrantedPermissions { this.legacyNativeLibraryPathString = legacyNativeLibraryPathString; this.primaryCpuAbiString = primaryCpuAbiString; this.secondaryCpuAbiString = secondaryCpuAbiString; + this.cpuAbiOverrideString = cpuAbiOverrideString; this.versionCode = pVersionCode; } @@ -185,6 +206,7 @@ class PackageSettingBase extends GrantedPermissions { primaryCpuAbiString = base.primaryCpuAbiString; secondaryCpuAbiString = base.secondaryCpuAbiString; + cpuAbiOverrideString = base.cpuAbiOverrideString; timeStamp = base.timeStamp; firstInstallTime = base.firstInstallTime; lastUpdateTime = base.lastUpdateTime; diff --git a/services/core/java/com/android/server/pm/PendingPackage.java b/services/core/java/com/android/server/pm/PendingPackage.java index 85be6513cb2e..5d30e769aad1 100644 --- a/services/core/java/com/android/server/pm/PendingPackage.java +++ b/services/core/java/com/android/server/pm/PendingPackage.java @@ -22,10 +22,12 @@ final class PendingPackage extends PackageSettingBase { final int sharedId; PendingPackage(String name, String realName, File codePath, File resourcePath, - String nativeLibrary32PathString, String nativeLibrary64PathString, - String requiredCpuAbiString, int sharedId, int pVersionCode, int pkgFlags) { - super(name, realName, codePath, resourcePath, nativeLibrary32PathString, nativeLibrary64PathString, - requiredCpuAbiString, pVersionCode, pkgFlags); + String legacyNativeLibraryPathString, String primaryCpuAbiString, + String secondaryCpuAbiString, String cpuAbiOverrideString, int sharedId, + int pVersionCode, int pkgFlags) { + super(name, realName, codePath, resourcePath, legacyNativeLibraryPathString, + primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, + pVersionCode, pkgFlags); this.sharedId = sharedId; } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index cd2aa2247f62..c346f7163d3d 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -325,8 +325,8 @@ final class Settings { PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage, String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, - String legacyNativeLibraryPathString, String primaryCpuAbi, String secondaryCpuAbi, int pkgFlags, - UserHandle user, boolean add) { + String legacyNativeLibraryPathString, String primaryCpuAbi, String secondaryCpuAbi, + int pkgFlags, UserHandle user, boolean add) { final String name = pkg.packageName; PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbi, secondaryCpuAbi, @@ -417,7 +417,8 @@ final class Settings { } PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath, p.legacyNativeLibraryPathString, p.primaryCpuAbiString, - p.secondaryCpuAbiString, p.appId, p.versionCode, p.pkgFlags); + p.secondaryCpuAbiString, p.secondaryCpuAbiString, + p.appId, p.versionCode, p.pkgFlags); mDisabledSysPackages.remove(name); return ret; } @@ -432,7 +433,7 @@ final class Settings { PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, - int uid, int vc, int pkgFlags) { + String cpuAbiOverrideString, int uid, int vc, int pkgFlags) { PackageSetting p = mPackages.get(name); if (p != null) { if (p.appId == uid) { @@ -443,7 +444,8 @@ final class Settings { return null; } p = new PackageSetting(name, realName, codePath, resourcePath, - legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, vc, pkgFlags); + legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, + cpuAbiOverrideString, vc, pkgFlags); p.appId = uid; if (addUserIdLPw(uid, p, name)) { mPackages.put(name, p); @@ -512,11 +514,13 @@ final class Settings { private PackageSetting getPackageLPw(String name, PackageSetting origPackage, String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, - int vc, int pkgFlags, UserHandle installUser, boolean add, boolean allowInstall) { + int vc, int pkgFlags, UserHandle installUser, boolean add, + boolean allowInstall) { PackageSetting p = mPackages.get(name); if (p != null) { p.primaryCpuAbiString = primaryCpuAbiString; p.secondaryCpuAbiString = secondaryCpuAbiString; + if (!p.codePath.equals(codePath)) { // Check to see if its a disabled system app if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { @@ -560,7 +564,8 @@ final class Settings { if (origPackage != null) { // We are consuming the data from an existing package. p = new PackageSetting(origPackage.name, name, codePath, resourcePath, - legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, vc, pkgFlags); + legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, + null /* cpuAbiOverrideString */, vc, pkgFlags); if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package " + name + " is adopting original package " + origPackage.name); // Note that we will retain the new package's signature so @@ -577,7 +582,8 @@ final class Settings { p.setTimeStamp(codePath.lastModified()); } else { p = new PackageSetting(name, realName, codePath, resourcePath, - legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, vc, pkgFlags); + legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, + null /* cpuAbiOverrideString */, vc, pkgFlags); p.setTimeStamp(codePath.lastModified()); p.sharedUser = sharedUser; // If this is not a system app, it starts out stopped. @@ -720,6 +726,7 @@ final class Settings { // Update the required Cpu Abi p.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; p.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; + p.cpuAbiOverrideString = pkg.cpuAbiOverride; // Update version code if needed if (pkg.mVersionCode != p.versionCode) { p.versionCode = pkg.mVersionCode; @@ -1888,6 +1895,9 @@ final class Settings { if (pkg.secondaryCpuAbiString != null) { serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString); } + if (pkg.cpuAbiOverrideString != null) { + serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString); + } if (pkg.sharedUser == null) { serializer.attribute(null, "userId", Integer.toString(pkg.appId)); @@ -1938,6 +1948,9 @@ final class Settings { if (pkg.secondaryCpuAbiString != null) { serializer.attribute(null, "secondaryCpuAbi", pkg.secondaryCpuAbiString); } + if (pkg.cpuAbiOverrideString != null) { + serializer.attribute(null, "cpuAbiOverride", pkg.cpuAbiOverrideString); + } serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags)); serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp)); @@ -2248,8 +2261,8 @@ final class Settings { PackageSetting p = getPackageLPw(pp.name, null, pp.realName, (SharedUserSetting) idObj, pp.codePath, pp.resourcePath, pp.legacyNativeLibraryPathString, pp.primaryCpuAbiString, - pp.secondaryCpuAbiString, pp.versionCode, pp.pkgFlags, - null, true /* add */, false /* allowInstall */); + pp.secondaryCpuAbiString, pp.versionCode, pp.pkgFlags, null, + true /* add */, false /* allowInstall */); if (p == null) { PackageManagerService.reportSettingsProblem(Log.WARN, "Unable to create application package for " + pp.name); @@ -2673,6 +2686,7 @@ final class Settings { String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi"); String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi"); + String cpuAbiOverrideStr = parser.getAttributeValue(null, "cpuAbiOverride"); if (primaryCpuAbiStr == null && legacyCpuAbiStr != null) { primaryCpuAbiStr = legacyCpuAbiStr; @@ -2698,7 +2712,7 @@ final class Settings { } PackageSetting ps = new PackageSetting(name, realName, codePathFile, new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr, - secondaryCpuAbiStr, versionCode, pkgFlags); + secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags); String timeStampStr = parser.getAttributeValue(null, "ft"); if (timeStampStr != null) { try { @@ -2768,6 +2782,7 @@ final class Settings { String legacyNativeLibraryPathStr = null; String primaryCpuAbiString = null; String secondaryCpuAbiString = null; + String cpuAbiOverrideString = null; String systemStr = null; String installerPackageName = null; String uidError = null; @@ -2792,6 +2807,7 @@ final class Settings { legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath"); primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi"); secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi"); + cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride"); if (primaryCpuAbiString == null && legacyCpuAbiString != null) { primaryCpuAbiString = legacyCpuAbiString; @@ -2874,7 +2890,7 @@ final class Settings { } else if (userId > 0) { packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString, - secondaryCpuAbiString, userId, versionCode, pkgFlags); + secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags); if (PackageManagerService.DEBUG_SETTINGS) Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId=" + userId + " pkg=" + packageSetting); @@ -2892,7 +2908,8 @@ final class Settings { if (userId > 0) { packageSetting = new PendingPackage(name.intern(), realName, new File( codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr, - primaryCpuAbiString, legacyCpuAbiString, userId, versionCode, pkgFlags); + primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, + userId, versionCode, pkgFlags); packageSetting.setTimeStamp(timeStamp); packageSetting.firstInstallTime = firstInstallTime; packageSetting.lastUpdateTime = lastUpdateTime; diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 33ecc4dc3db8..ad879933e817 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -125,6 +125,10 @@ public class UserManagerService extends IUserManager.Stub { // Number of attempts before jumping to the next BACKOFF_TIMES slot private static final int BACKOFF_INC_INTERVAL = 5; + // Maximum number of managed profiles permitted is 1. This cannot be increased + // without first making sure that the rest of the framework is prepared for it. + private static final int MAX_MANAGED_PROFILES = 1; + // Amount of time to force the user to wait before entering the PIN again, after failing // BACKOFF_INC_INTERVAL times. private static final int[] BACKOFF_TIMES = { 0, 30*1000, 60*1000, 5*60*1000, 30*60*1000 }; @@ -510,7 +514,8 @@ public class UserManagerService extends IUserManager.Stub { // Skip over users being removed for (int i = 0; i < totalUserCount; i++) { UserInfo user = mUsers.valueAt(i); - if (!mRemovingUserIds.get(user.id)) { + if (!mRemovingUserIds.get(user.id) + && !user.isGuest()) { aliveUserCount++; } } @@ -1093,6 +1098,7 @@ public class UserManagerService extends IUserManager.Stub { Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled."); return null; } + final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0; final long ident = Binder.clearCallingIdentity(); UserInfo userInfo = null; try { @@ -1103,7 +1109,21 @@ public class UserManagerService extends IUserManager.Stub { parent = getUserInfoLocked(parentId); if (parent == null) return null; } - if (isUserLimitReachedLocked()) return null; + // If we're not adding a guest user and the limit has been reached, + // cannot add a user. + if (!isGuest && isUserLimitReachedLocked()) { + return null; + } + // If we're adding a guest and there already exists one, bail. + if (isGuest && numberOfUsersOfTypeLocked(UserInfo.FLAG_GUEST, true) > 0) { + return null; + } + // Limit number of managed profiles that can be created + if ((flags & UserInfo.FLAG_MANAGED_PROFILE) != 0 + && numberOfUsersOfTypeLocked(UserInfo.FLAG_MANAGED_PROFILE, true) + >= MAX_MANAGED_PROFILES) { + return null; + } int userId = getNextAvailableIdLocked(); userInfo = new UserInfo(userId, name, null, flags); File userPath = new File(mBaseUserPath, Integer.toString(userId)); @@ -1142,6 +1162,19 @@ public class UserManagerService extends IUserManager.Stub { return userInfo; } + private int numberOfUsersOfTypeLocked(int flags, boolean excludeDying) { + int count = 0; + for (int i = mUsers.size() - 1; i >= 0; i--) { + UserInfo user = mUsers.valueAt(i); + if (!excludeDying || !mRemovingUserIds.get(user.id)) { + if ((user.flags & flags) != 0) { + count++; + } + } + } + return count; + } + /** * Removes a user and all data directories created for that user. This method should be called * after the user's processes have been terminated. diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 14cbd66178a5..39c6e0e2e982 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -771,7 +771,7 @@ public final class PowerManagerService extends com.android.server.SystemService notifyAcquire = true; } - applyWakeLockFlagsOnAcquireLocked(wakeLock); + applyWakeLockFlagsOnAcquireLocked(wakeLock, uid); mDirty |= DIRTY_WAKE_LOCKS; updatePowerStateLocked(); if (notifyAcquire) { @@ -796,10 +796,10 @@ public final class PowerManagerService extends com.android.server.SystemService return false; } - private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock) { + private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, int uid) { if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0 && isScreenLock(wakeLock)) { - wakeUpNoUpdateLocked(SystemClock.uptimeMillis()); + wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), uid); } } @@ -994,17 +994,17 @@ public final class PowerManagerService extends com.android.server.SystemService return false; } - private void wakeUpInternal(long eventTime) { + private void wakeUpInternal(long eventTime, int uid) { synchronized (mLock) { - if (wakeUpNoUpdateLocked(eventTime)) { + if (wakeUpNoUpdateLocked(eventTime, uid)) { updatePowerStateLocked(); } } } - private boolean wakeUpNoUpdateLocked(long eventTime) { + private boolean wakeUpNoUpdateLocked(long eventTime, int uid) { if (DEBUG_SPEW) { - Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime); + Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + uid); } if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE @@ -1014,13 +1014,13 @@ public final class PowerManagerService extends com.android.server.SystemService switch (mWakefulness) { case WAKEFULNESS_ASLEEP: - Slog.i(TAG, "Waking up from sleep..."); + Slog.i(TAG, "Waking up from sleep (uid " + uid +")..."); break; case WAKEFULNESS_DREAMING: - Slog.i(TAG, "Waking up from dream..."); + Slog.i(TAG, "Waking up from dream (uid " + uid +")..."); break; case WAKEFULNESS_DOZING: - Slog.i(TAG, "Waking up from dozing..."); + Slog.i(TAG, "Waking up from dozing (uid " + uid +")..."); break; } @@ -1030,13 +1030,13 @@ public final class PowerManagerService extends com.android.server.SystemService setInteractiveStateLocked(true, 0); userActivityNoUpdateLocked( - eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); + eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid); return true; } - private void goToSleepInternal(long eventTime, int reason, int flags) { + private void goToSleepInternal(long eventTime, int reason, int flags, int uid) { synchronized (mLock) { - if (goToSleepNoUpdateLocked(eventTime, reason, flags)) { + if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) { updatePowerStateLocked(); } } @@ -1045,10 +1045,10 @@ public final class PowerManagerService extends com.android.server.SystemService // This method is called goToSleep for historical reasons but we actually start // dozing before really going to sleep. @SuppressWarnings("deprecation") - private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags) { + private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) { if (DEBUG_SPEW) { Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime - + ", reason=" + reason + ", flags=" + flags); + + ", reason=" + reason + ", flags=" + flags + ", uid=" + uid); } if (eventTime < mLastWakeTime @@ -1060,14 +1060,24 @@ public final class PowerManagerService extends com.android.server.SystemService switch (reason) { case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN: - Slog.i(TAG, "Going to sleep due to device administration policy..."); + Slog.i(TAG, "Going to sleep due to device administration policy " + + "(uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT: - Slog.i(TAG, "Going to sleep due to screen timeout..."); + Slog.i(TAG, "Going to sleep due to screen timeout (uid " + uid +")..."); + break; + case PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH: + Slog.i(TAG, "Going to sleep due to lid switch (uid " + uid +")..."); + break; + case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON: + Slog.i(TAG, "Going to sleep due to power button (uid " + uid +")..."); + break; + case PowerManager.GO_TO_SLEEP_REASON_HDMI: + Slog.i(TAG, "Going to sleep due to HDMI standby (uid " + uid +")..."); break; default: - Slog.i(TAG, "Going to sleep by user request..."); - reason = PowerManager.GO_TO_SLEEP_REASON_USER; + Slog.i(TAG, "Going to sleep by application request (uid " + uid +")..."); + reason = PowerManager.GO_TO_SLEEP_REASON_APPLICATION; break; } @@ -1094,22 +1104,22 @@ public final class PowerManagerService extends com.android.server.SystemService // Skip dozing if requested. if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) { - reallyGoToSleepNoUpdateLocked(eventTime); + reallyGoToSleepNoUpdateLocked(eventTime, uid); } return true; } - private void napInternal(long eventTime) { + private void napInternal(long eventTime, int uid) { synchronized (mLock) { - if (napNoUpdateLocked(eventTime)) { + if (napNoUpdateLocked(eventTime, uid)) { updatePowerStateLocked(); } } } - private boolean napNoUpdateLocked(long eventTime) { + private boolean napNoUpdateLocked(long eventTime, int uid) { if (DEBUG_SPEW) { - Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime); + Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime + ", uid=" + uid); } if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE @@ -1117,7 +1127,7 @@ public final class PowerManagerService extends com.android.server.SystemService return false; } - Slog.i(TAG, "Nap time..."); + Slog.i(TAG, "Nap time (uid " + uid +")..."); mDirty |= DIRTY_WAKEFULNESS; mWakefulness = WAKEFULNESS_DREAMING; @@ -1127,9 +1137,10 @@ public final class PowerManagerService extends com.android.server.SystemService } // Done dozing, drop everything and go to sleep. - private boolean reallyGoToSleepNoUpdateLocked(long eventTime) { + private boolean reallyGoToSleepNoUpdateLocked(long eventTime, int uid) { if (DEBUG_SPEW) { - Slog.d(TAG, "reallyGoToSleepNoUpdateLocked: eventTime=" + eventTime); + Slog.d(TAG, "reallyGoToSleepNoUpdateLocked: eventTime=" + eventTime + + ", uid=" + uid); } if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP @@ -1137,7 +1148,7 @@ public final class PowerManagerService extends com.android.server.SystemService return false; } - Slog.i(TAG, "Sleeping..."); + Slog.i(TAG, "Sleeping (uid " + uid +")..."); mDirty |= DIRTY_WAKEFULNESS; mWakefulness = WAKEFULNESS_ASLEEP; @@ -1251,7 +1262,7 @@ public final class PowerManagerService extends com.android.server.SystemService final long now = SystemClock.uptimeMillis(); if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType, dockedOnWirelessCharger)) { - wakeUpNoUpdateLocked(now); + wakeUpNoUpdateLocked(now, Process.SYSTEM_UID); } userActivityNoUpdateLocked( now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); @@ -1509,10 +1520,10 @@ public final class PowerManagerService extends com.android.server.SystemService } final long time = SystemClock.uptimeMillis(); if (shouldNapAtBedTimeLocked()) { - changed = napNoUpdateLocked(time); + changed = napNoUpdateLocked(time, Process.SYSTEM_UID); } else { changed = goToSleepNoUpdateLocked(time, - PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0); + PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID); } } } @@ -1659,10 +1670,10 @@ public final class PowerManagerService extends com.android.server.SystemService // Dream has ended or will be stopped. Update the power state. if (isItBedTimeYetLocked()) { goToSleepNoUpdateLocked(SystemClock.uptimeMillis(), - PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0); + PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID); updatePowerStateLocked(); } else { - wakeUpNoUpdateLocked(SystemClock.uptimeMillis()); + wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID); updatePowerStateLocked(); } } else if (wakefulness == WAKEFULNESS_DOZING) { @@ -1671,7 +1682,7 @@ public final class PowerManagerService extends com.android.server.SystemService } // Doze has ended or will be stopped. Update the power state. - reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis()); + reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID); updatePowerStateLocked(); } } @@ -2852,9 +2863,10 @@ public final class PowerManagerService extends com.android.server.SystemService mContext.enforceCallingOrSelfPermission( android.Manifest.permission.DEVICE_POWER, null); + final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { - wakeUpInternal(eventTime); + wakeUpInternal(eventTime, uid); } finally { Binder.restoreCallingIdentity(ident); } @@ -2869,9 +2881,10 @@ public final class PowerManagerService extends com.android.server.SystemService mContext.enforceCallingOrSelfPermission( android.Manifest.permission.DEVICE_POWER, null); + final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { - goToSleepInternal(eventTime, reason, flags); + goToSleepInternal(eventTime, reason, flags, uid); } finally { Binder.restoreCallingIdentity(ident); } @@ -2886,9 +2899,10 @@ public final class PowerManagerService extends com.android.server.SystemService mContext.enforceCallingOrSelfPermission( android.Manifest.permission.DEVICE_POWER, null); + final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { - napInternal(eventTime); + napInternal(eventTime, uid); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/core/java/com/android/server/trust/TrustArchive.java b/services/core/java/com/android/server/trust/TrustArchive.java index d4ed86d4183d..725371666acf 100644 --- a/services/core/java/com/android/server/trust/TrustArchive.java +++ b/services/core/java/com/android/server/trust/TrustArchive.java @@ -129,8 +129,8 @@ public class TrustArchive { } switch (ev.type) { case TYPE_GRANT_TRUST: - writer.printf(", message=\"%s\", duration=%s", - ev.message, formatDuration(ev.duration)); + writer.printf(", message=\"%s\", duration=%s, initiatedByUser=%d", + ev.message, formatDuration(ev.duration), ev.userInitiated ? 1 : 0); break; case TYPE_MANAGING_TRUST: writer.printf(", managingTrust=" + ev.managingTrust); diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index badead665326..490536e6e8c3 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -93,7 +93,7 @@ public class TrustManagerService extends SystemService { private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>(); private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>(); - private final DevicePolicyReceiver mDevicePolicyReceiver = new DevicePolicyReceiver(); + private final Receiver mReceiver = new Receiver(); private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray(); /* package */ final TrustArchive mArchive = new TrustArchive(); private final Context mContext; @@ -115,7 +115,7 @@ public class TrustManagerService extends SystemService { public void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY && !isSafeMode()) { mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true); - mDevicePolicyReceiver.register(mContext); + mReceiver.register(mContext); refreshAgentList(); } } @@ -373,7 +373,13 @@ public class TrustManagerService extends SystemService { } } - if (successful && !mUserHasAuthenticatedSinceBoot.get(userId)) { + if (successful) { + updateUserHasAuthenticated(userId); + } + } + + private void updateUserHasAuthenticated(int userId) { + if (!mUserHasAuthenticatedSinceBoot.get(userId)) { mUserHasAuthenticatedSinceBoot.put(userId, true); updateTrust(userId, false); } @@ -597,7 +603,7 @@ public class TrustManagerService extends SystemService { } }; - private class DevicePolicyReceiver extends BroadcastReceiver { + private class Receiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -605,14 +611,18 @@ public class TrustManagerService extends SystemService { intent.getAction())) { refreshAgentList(); updateDevicePolicyFeatures(getSendingUserId()); + } else if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) { + updateUserHasAuthenticated(getSendingUserId()); } } public void register(Context context) { + IntentFilter filter = new IntentFilter(); + filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); + filter.addAction(Intent.ACTION_USER_PRESENT); context.registerReceiverAsUser(this, UserHandle.ALL, - new IntentFilter( - DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), + filter, null /* permission */, null /* scheduler */); } diff --git a/services/core/java/com/android/server/tv/PersistentDataStore.java b/services/core/java/com/android/server/tv/PersistentDataStore.java index 852e64038eab..05a2bde9cca9 100644 --- a/services/core/java/com/android/server/tv/PersistentDataStore.java +++ b/services/core/java/com/android/server/tv/PersistentDataStore.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.media.tv.TvContentRating; import android.media.tv.TvInputManager; +import android.os.Environment; import android.os.Handler; import android.os.UserHandle; import android.text.TextUtils; @@ -81,8 +82,13 @@ final class PersistentDataStore { public PersistentDataStore(Context context, int userId) { mContext = context; - mAtomicFile = new AtomicFile(new File("/data/system/tv/" + userId - + "/tv-input-manager-state.xml")); + File userDir = Environment.getUserSystemDirectory(userId); + if (!userDir.exists()) { + if (!userDir.mkdirs()) { + throw new IllegalStateException("User dir cannot be created: " + userDir); + } + } + mAtomicFile = new AtomicFile(new File(userDir, "tv-input-manager-state.xml")); } public boolean isParentalControlsEnabled() { @@ -91,6 +97,7 @@ final class PersistentDataStore { } public void setParentalControlsEnabled(boolean enabled) { + loadIfNeeded(); if (mParentalControlsEnabled != enabled) { mParentalControlsEnabled = enabled; mParentalControlsEnabledChanged = true; @@ -114,6 +121,7 @@ final class PersistentDataStore { } public void addBlockedRating(TvContentRating rating) { + loadIfNeeded(); if (rating != null && !mBlockedRatings.contains(rating)) { mBlockedRatings.add(rating); mBlockedRatingsChanged = true; @@ -122,6 +130,7 @@ final class PersistentDataStore { } public void removeBlockedRating(TvContentRating rating) { + loadIfNeeded(); if (rating != null && mBlockedRatings.contains(rating)) { mBlockedRatings.remove(rating); mBlockedRatingsChanged = true; diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java index c916507a7b43..78ea6c9da508 100644 --- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java +++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java @@ -55,6 +55,7 @@ import android.util.SparseBooleanArray; import android.view.KeyEvent; import android.view.Surface; +import com.android.internal.os.SomeArgs; import com.android.server.SystemService; import java.util.ArrayList; @@ -877,7 +878,7 @@ class TvInputHardwareManager implements TvInputHal.Callback { public void onHardwareDeviceRemoved(TvInputHardwareInfo info); public void onHdmiDeviceAdded(HdmiDeviceInfo device); public void onHdmiDeviceRemoved(HdmiDeviceInfo device); - public void onHdmiDeviceUpdated(HdmiDeviceInfo device); + public void onHdmiDeviceUpdated(String inputId, HdmiDeviceInfo device); } private class ListenerHandler extends Handler { @@ -918,8 +919,11 @@ class TvInputHardwareManager implements TvInputHal.Callback { break; } case HDMI_DEVICE_UPDATED: { - HdmiDeviceInfo info = (HdmiDeviceInfo) msg.obj; - mListener.onHdmiDeviceUpdated(info); + SomeArgs args = (SomeArgs) msg.obj; + String inputId = (String) args.arg1; + HdmiDeviceInfo info = (HdmiDeviceInfo) args.arg2; + args.recycle(); + mListener.onHdmiDeviceUpdated(inputId, info); } default: { Slog.w(TAG, "Unhandled message: " + msg); @@ -956,6 +960,7 @@ class TvInputHardwareManager implements TvInputHal.Callback { public void onStatusChanged(HdmiDeviceInfo deviceInfo, int status) { synchronized (mLock) { int messageType = 0; + Object obj = null; switch (status) { case HdmiControlManager.DEVICE_EVENT_ADD_DEVICE: { if (!mHdmiDeviceList.contains(deviceInfo)) { @@ -965,6 +970,7 @@ class TvInputHardwareManager implements TvInputHal.Callback { return; } messageType = ListenerHandler.HDMI_DEVICE_ADDED; + obj = deviceInfo; break; } case HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE: { @@ -973,6 +979,7 @@ class TvInputHardwareManager implements TvInputHal.Callback { return; } messageType = ListenerHandler.HDMI_DEVICE_REMOVED; + obj = deviceInfo; break; } case HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE: { @@ -982,11 +989,16 @@ class TvInputHardwareManager implements TvInputHal.Callback { } mHdmiDeviceList.add(deviceInfo); messageType = ListenerHandler.HDMI_DEVICE_UPDATED; + String inputId = mHdmiInputIdMap.get(deviceInfo.getLogicalAddress()); + SomeArgs args = SomeArgs.obtain(); + args.arg1 = inputId; + args.arg2 = deviceInfo; + obj = args; break; } } - Message msg = mHandler.obtainMessage(messageType, 0, 0, deviceInfo); + Message msg = mHandler.obtainMessage(messageType, 0, 0, obj); if (findHardwareInfoForHdmiPortLocked(deviceInfo.getPortId()) != null) { msg.sendToTarget(); } else { diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index dc5bc84d0749..3b5e79d9dea6 100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -17,6 +17,7 @@ package com.android.server.tv; import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED; +import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED_STANDBY; import static android.media.tv.TvInputManager.INPUT_STATE_DISCONNECTED; import android.app.ActivityManager; @@ -36,6 +37,7 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.graphics.Rect; +import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiDeviceInfo; import android.media.tv.ITvInputClient; import android.media.tv.ITvInputHardware; @@ -212,8 +214,6 @@ public final class TvInputManagerService extends SystemService { private void buildTvInputListLocked(int userId) { UserState userState = getUserStateLocked(userId); - - Map<String, TvInputState> inputMap = new HashMap<String, TvInputState>(); userState.packageSet.clear(); if (DEBUG) Slog.d(TAG, "buildTvInputList"); @@ -229,41 +229,42 @@ public final class TvInputManagerService extends SystemService { + android.Manifest.permission.BIND_TV_INPUT); continue; } - try { - inputList.clear(); - ComponentName component = new ComponentName(si.packageName, si.name); - if (hasHardwarePermission(pm, component)) { - ServiceState serviceState = userState.serviceStateMap.get(component); - if (serviceState == null) { - // We see this hardware TV input service for the first time; we need to - // prepare the ServiceState object so that we can connect to the service and - // let it add TvInputInfo objects to mInputList if there's any. - serviceState = new ServiceState(component, userId); - userState.serviceStateMap.put(component, serviceState); - } else { - inputList.addAll(serviceState.mInputList); - } + + ComponentName component = new ComponentName(si.packageName, si.name); + if (hasHardwarePermission(pm, component)) { + ServiceState serviceState = userState.serviceStateMap.get(component); + if (serviceState == null) { + // We see this hardware TV input service for the first time; we need to + // prepare the ServiceState object so that we can connect to the service and + // let it add TvInputInfo objects to mInputList if there's any. + serviceState = new ServiceState(component, userId); + userState.serviceStateMap.put(component, serviceState); } else { - inputList.add(TvInputInfo.createTvInputInfo(mContext, ri)); + inputList.addAll(serviceState.mInputList); } - - for (TvInputInfo info : inputList) { - if (DEBUG) Slog.d(TAG, "add " + info.getId()); - TvInputState state = userState.inputMap.get(info.getId()); - if (state == null) { - state = new TvInputState(); - } - state.mInfo = info; - inputMap.put(info.getId(), state); + } else { + try { + inputList.add(TvInputInfo.createTvInputInfo(mContext, ri)); + } catch (XmlPullParserException | IOException e) { + Slog.e(TAG, "Failed to load TV input " + si.name, e); + continue; } + } - // Reconnect the service if existing input is updated. - updateServiceConnectionLocked(component, userId); + // Reconnect the service if existing input is updated. + updateServiceConnectionLocked(component, userId); + userState.packageSet.add(si.packageName); + } - userState.packageSet.add(si.packageName); - } catch (IOException | XmlPullParserException e) { - Slog.e(TAG, "Can't load TV input " + si.name, e); + Map<String, TvInputState> inputMap = new HashMap<String, TvInputState>(); + for (TvInputInfo info : inputList) { + if (DEBUG) Slog.d(TAG, "add " + info.getId()); + TvInputState state = userState.inputMap.get(info.getId()); + if (state == null) { + state = new TvInputState(); } + state.mInfo = info; + inputMap.put(info.getId(), state); } for (String inputId : inputMap.keySet()) { @@ -338,7 +339,6 @@ public final class TvInputManagerService extends SystemService { Slog.e(TAG, "error in unregisterCallback", e); } } - serviceState.mClientTokens.clear(); mContext.unbindService(serviceState.mConnection); } userState.serviceStateMap.clear(); @@ -401,9 +401,7 @@ public final class TvInputManagerService extends SystemService { } private static boolean shouldMaintainConnection(ServiceState serviceState) { - return !serviceState.mClientTokens.isEmpty() - || !serviceState.mSessionTokens.isEmpty() - || serviceState.mIsHardware; + return !serviceState.mSessionTokens.isEmpty() || serviceState.mIsHardware; // TODO: Find a way to maintain connection only when necessary. } @@ -996,12 +994,13 @@ public final class TvInputManagerService extends SystemService { } private void ensureParentalControlsPermission() { - if (mContext.checkCallingPermission( - android.Manifest.permission.MODIFY_PARENTAL_CONTROLS) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException( - "The caller does not have parental controls permission"); - } + // STOPSHIP: Uncomment when b/16984416 is resolved. + //if (mContext.checkCallingPermission( + // android.Manifest.permission.MODIFY_PARENTAL_CONTROLS) + // != PackageManager.PERMISSION_GRANTED) { + // throw new SecurityException( + // "The caller does not have parental controls permission"); + //} } @Override @@ -1610,13 +1609,6 @@ public final class TvInputManagerService extends SystemService { pw.increaseIndent(); - pw.println("mClientTokens:"); - pw.increaseIndent(); - for (IBinder token : service.mClientTokens) { - pw.println("" + token); - } - pw.decreaseIndent(); - pw.println("mSessionTokens:"); pw.increaseIndent(); for (IBinder token : service.mSessionTokens) { @@ -1753,7 +1745,6 @@ public final class TvInputManagerService extends SystemService { } private final class ServiceState { - private final List<IBinder> mClientTokens = new ArrayList<IBinder>(); private final List<IBinder> mSessionTokens = new ArrayList<IBinder>(); private final ServiceConnection mConnection; private final ComponentName mComponent; @@ -1808,7 +1799,7 @@ public final class TvInputManagerService extends SystemService { // If there are any other sessions based on this session, they should be released. UserState userState = getUserStateLocked(mUserId); for (SessionState sessionState : userState.sessionStateMap.values()) { - if (mSession != null && mSession == sessionState.mHardwareSessionToken) { + if (mSessionToken == sessionState.mHardwareSessionToken) { try { sessionState.mSession.release(); } catch (RemoteException e) { @@ -2176,8 +2167,27 @@ public final class TvInputManagerService extends SystemService { } @Override - public void onHdmiDeviceUpdated(HdmiDeviceInfo deviceInfo) { - // TODO: implement here. + public void onHdmiDeviceUpdated(String inputId, HdmiDeviceInfo deviceInfo) { + synchronized (mLock) { + Integer state = null; + switch (deviceInfo.getDevicePowerStatus()) { + case HdmiControlManager.POWER_STATUS_ON: + state = INPUT_STATE_CONNECTED; + break; + case HdmiControlManager.POWER_STATUS_STANDBY: + case HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON: + case HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY: + state = INPUT_STATE_CONNECTED_STANDBY; + break; + case HdmiControlManager.POWER_STATUS_UNKNOWN: + default: + state = null; + break; + } + if (state != null) { + setStateLocked(inputId, state.intValue(), mCurrentUserId); + } + } } } } diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 0e1340c27e5d..f6ec86db5478 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -159,7 +159,7 @@ public class AppTransition implements Dump { private final int mConfigShortAnimTime; private final Interpolator mDecelerateInterpolator; private final Interpolator mThumbnailFadeoutInterpolator; - private final Interpolator mThumbnailCubicInterpolator; + private final Interpolator mThumbnailFastOutSlowInInterpolator; private int mCurrentUserId = 0; @@ -170,7 +170,7 @@ public class AppTransition implements Dump { com.android.internal.R.integer.config_shortAnimTime); mDecelerateInterpolator = AnimationUtils.loadInterpolator(context, com.android.internal.R.interpolator.decelerate_cubic); - mThumbnailCubicInterpolator = AnimationUtils.loadInterpolator(context, + mThumbnailFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, com.android.internal.R.interpolator.fast_out_slow_in); mThumbnailFadeoutInterpolator = new Interpolator() { @Override @@ -635,7 +635,7 @@ public class AppTransition implements Dump { } return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, - THUMBNAIL_APP_TRANSITION_DURATION, mThumbnailCubicInterpolator); + THUMBNAIL_APP_TRANSITION_DURATION, mThumbnailFastOutSlowInInterpolator); } /** diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 32e8afe0b33c..4edd5cfda29f 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -88,6 +88,8 @@ public class WindowAnimator { boolean mInitialized = false; boolean mKeyguardGoingAway; + boolean mKeyguardGoingAwayToNotificationShade; + boolean mKeyguardGoingAwayDisableWindowAnimations; // forceHiding states. static final int KEYGUARD_NOT_SHOWN = 0; @@ -389,7 +391,11 @@ public class WindowAnimator { if (unForceHiding != null) { boolean startKeyguardExit = true; for (int i=unForceHiding.size()-1; i>=0; i--) { - Animation a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding); + Animation a = null; + if (!mKeyguardGoingAwayDisableWindowAnimations) { + a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding, + mKeyguardGoingAwayToNotificationShade); + } if (a != null) { final WindowStateAnimator winAnimator = unForceHiding.get(i); winAnimator.setAnimation(a); @@ -405,9 +411,14 @@ public class WindowAnimator { } // Wallpaper is going away in un-force-hide motion, animate it as well. - if (!wallpaperInUnForceHiding && wallpaper != null) { - WindowStateAnimator animator = wallpaper.mWinAnimator; - animator.setAnimation(mPolicy.createForceHideWallpaperExitAnimation()); + if (!wallpaperInUnForceHiding && wallpaper != null + && !mKeyguardGoingAwayDisableWindowAnimations) { + Animation a = mPolicy.createForceHideWallpaperExitAnimation( + mKeyguardGoingAwayToNotificationShade); + if (a != null) { + WindowStateAnimator animator = wallpaper.mWinAnimator; + animator.setAnimation(a); + } } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index e7ebae738c15..711cf9c615b6 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -462,6 +462,9 @@ public class WindowManagerService extends IWindowManager.Stub int mRotation = 0; int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; boolean mAltOrientation = false; + + private boolean mKeyguardWaitingForActivityDrawn; + class RotationWatcher { IRotationWatcher watcher; IBinder.DeathRecipient deathRecipient; @@ -2311,6 +2314,10 @@ public class WindowManagerService extends IWindowManager.Stub + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } + } else if (token.appWindowToken != null) { + Slog.i(TAG, "Non-null appWindowToken for system window of type=" + type); + // app token should be null for any other window types. + token.appWindowToken = null; } win = new WindowState(this, session, client, token, @@ -5236,17 +5243,35 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void keyguardGoingAway() { + public void keyguardGoingAway(boolean disableWindowAnimations, + boolean keyguardGoingToNotificationShade) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires DISABLE_KEYGUARD permission"); } synchronized (mWindowMap) { mAnimator.mKeyguardGoingAway = true; + mAnimator.mKeyguardGoingAwayToNotificationShade = keyguardGoingToNotificationShade; + mAnimator.mKeyguardGoingAwayDisableWindowAnimations = disableWindowAnimations; requestTraversalLocked(); } } + public void keyguardWaitingForActivityDrawn() { + synchronized (mWindowMap) { + mKeyguardWaitingForActivityDrawn = true; + } + } + + public void notifyActivityDrawnForKeyguard() { + synchronized (mWindowMap) { + if (mKeyguardWaitingForActivityDrawn) { + mPolicy.notifyActivityDrawnForKeyguardLw(); + mKeyguardWaitingForActivityDrawn = false; + } + } + } + void showGlobalActions() { mPolicy.showGlobalActions(); } diff --git a/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp b/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp index 2519ff85a49f..37a3eaa1d045 100644 --- a/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp +++ b/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp @@ -66,7 +66,12 @@ static inline void ThrowOnError( } ALOGE("Error %d in '%s'", resultCode, methodName); - env->FatalError(methodName); + // TODO: this layer needs to be refactored to return error codes to Java + // raising a FatalError is harsh, and because FLP Hardware Provider is loaded inside the system + // service, it can cause the device to reboot, or remain in a reboot loop + // a simple exception is still dumped to logcat, but it is handled more gracefully + jclass exceptionClass = env->FindClass("java/lang/RuntimeException"); + env->ThrowNew(exceptionClass, methodName); } static bool IsValidCallbackThread() { diff --git a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp index 46327d7db897..c39890806788 100644 --- a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp @@ -28,6 +28,7 @@ #include "android_runtime/AndroidRuntime.h" #include "android_runtime/Log.h" +#include <arpa/inet.h> #include <string.h> #include <pthread.h> #include <linux/in.h> @@ -189,8 +190,10 @@ static jbyteArray convert_to_ipv4(uint32_t ip, bool net_order) jbyte ipv4[4]; if (net_order) { + ALOGV("Converting IPv4 address(net_order) %x", ip); memcpy(ipv4, &ip, sizeof(ipv4)); } else { + ALOGV("Converting IPv4 address(host_order) %x", ip); //endianess transparent conversion from int to char[] ipv4[0] = (jbyte) (ip & 0xFF); ipv4[1] = (jbyte)((ip>>8) & 0xFF); @@ -210,6 +213,7 @@ static void agps_status_callback(AGpsStatus* agps_status) size_t status_size = agps_status->size; if (status_size == sizeof(AGpsStatus_v3)) { + ALOGV("AGpsStatus is V3: %d", status_size); switch (agps_status->addr.ss_family) { case AF_INET: @@ -220,6 +224,12 @@ static void agps_status_callback(AGpsStatus* agps_status) if (byteArray != NULL) { isSupported = true; } + IF_ALOGD() { + // log the IP for reference in case there is a bogus value pushed by HAL + char str[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &(in->sin_addr), str, INET_ADDRSTRLEN); + ALOGD("AGPS IP is v4: %s", str); + } } break; case AF_INET6: @@ -232,6 +242,12 @@ static void agps_status_callback(AGpsStatus* agps_status) } else { ALOGE("Unable to allocate byte array for IPv6 address."); } + IF_ALOGD() { + // log the IP for reference in case there is a bogus value pushed by HAL + char str[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &(in6->sin6_addr), str, INET6_ADDRSTRLEN); + ALOGD("AGPS IP is v6: %s", str); + } } break; default: @@ -239,14 +255,17 @@ static void agps_status_callback(AGpsStatus* agps_status) break; } } else if (status_size >= sizeof(AGpsStatus_v2)) { + ALOGV("AGpsStatus is V2+: %d", status_size); // for back-compatibility reasons we check in v2 that the data structure size is greater or // equal to the declared size in gps.h uint32_t ipaddr = agps_status->ipaddr; + ALOGV("AGPS IP is v4: %x", ipaddr); byteArray = convert_to_ipv4(ipaddr, false /* net_order */); if (ipaddr == INADDR_NONE || byteArray != NULL) { isSupported = true; } } else if (status_size >= sizeof(AGpsStatus_v1)) { + ALOGV("AGpsStatus is V1+: %d", status_size); // because we have to check for >= with regards to v2, we also need to relax the check here // and only make sure that the size is at least what we expect isSupported = true; @@ -255,6 +274,8 @@ static void agps_status_callback(AGpsStatus* agps_status) } if (isSupported) { + jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0; + ALOGV("Passing AGPS IP addr: size %d", byteArrayLength); env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, agps_status->type, agps_status->status, byteArray); diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java index 8aae69554ad7..c3d4ed9f1ab5 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java @@ -47,7 +47,6 @@ import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.isA; -import android.app.AlarmClockInfo; import android.app.AlarmManager; import android.app.IAlarmManager; import android.app.PendingIntent; @@ -880,7 +879,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase { expectLastCall().anyTimes(); mAlarmManager.set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), anyLong(), - isA(PendingIntent.class), isA(WorkSource.class), isA(AlarmClockInfo.class)); + isA(PendingIntent.class), isA(WorkSource.class), + isA(AlarmManager.AlarmClockInfo.class)); expectLastCall().atLeastOnce(); mNetManager.setGlobalAlert(anyLong()); diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java index 2e309be6af0c..6e1373204c47 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -47,6 +47,18 @@ public class UserManagerTest extends AndroidTestCase { } } }, filter); + + removeExistingUsers(); + } + + private void removeExistingUsers() { + List<UserInfo> list = mUserManager.getUsers(); + boolean found = false; + for (UserInfo user : list) { + if (user.id != UserHandle.USER_OWNER) { + removeUser(user.id); + } + } } public void testHasPrimary() throws Exception { @@ -95,6 +107,29 @@ public class UserManagerTest extends AndroidTestCase { assertFalse(findUser(userInfo.id)); } + public void testAddGuest() throws Exception { + UserInfo userInfo1 = mUserManager.createUser("Guest 1", UserInfo.FLAG_GUEST); + UserInfo userInfo2 = mUserManager.createUser("Guest 2", UserInfo.FLAG_GUEST); + assertNotNull(userInfo1); + assertNull(userInfo2); + + // Cleanup + removeUser(userInfo1.id); + } + + // Make sure only one managed profile can be created + public void testAddManagedProfile() throws Exception { + UserInfo userInfo1 = mUserManager.createProfileForUser("Managed 1", + UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_OWNER); + UserInfo userInfo2 = mUserManager.createProfileForUser("Managed 2", + UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_OWNER); + assertNotNull(userInfo1); + assertNull(userInfo2); + + // Cleanup + removeUser(userInfo1.id); + } + private boolean findUser(int id) { List<UserInfo> list = mUserManager.getUsers(); diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java index bcbae607d9f3..5860fc7c81cc 100644 --- a/services/usb/java/com/android/server/usb/UsbHostManager.java +++ b/services/usb/java/com/android/server/usb/UsbHostManager.java @@ -314,14 +314,22 @@ public class UsbHostManager { mConnectedUsbCard = cardsParser.getNumCardRecords() - 1; mConnectedUsbDeviceNum = 0; - if (!waitForAlsaFile(mConnectedUsbCard, mConnectedUsbDeviceNum, false)) { - return; - } - mConnectedHasPlayback = devicesParser.hasPlaybackDevices(mConnectedUsbCard); mConnectedHasCapture = devicesParser.hasCaptureDevices(mConnectedUsbCard); mConnectedHasMIDI = devicesParser.hasMIDIDevices(mConnectedUsbCard); + // Playback device file needed/present? + if (mConnectedHasPlayback && + !waitForAlsaFile(mConnectedUsbCard, mConnectedUsbDeviceNum, false)) { + return; + } + + // Capture device file needed/present? + if (mConnectedHasCapture && + !waitForAlsaFile(mConnectedUsbCard, mConnectedUsbDeviceNum, true)) { + return; + } + if (DEBUG_AUDIO) { Slog.d(TAG, "usb: hasPlayback:" + mConnectedHasPlayback + " hasCapture:" + mConnectedHasCapture); diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java index f0ecafede1a9..cc0d8df2adda 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/DatabaseHelper.java @@ -130,8 +130,8 @@ public class DatabaseHelper extends SQLiteOpenHelper { synchronized(this) { SQLiteDatabase db = getWritableDatabase(); - String soundModelClause = SoundModelContract.KEY_MODEL_UUID + "=" - + modelUuid.toString(); + String soundModelClause = SoundModelContract.KEY_MODEL_UUID + "='" + + modelUuid.toString() + "'"; try { return db.delete(SoundModelContract.TABLE, soundModelClause, null) != 0; diff --git a/telecomm/java/android/telecomm/CallAudioState.aidl b/telecomm/java/android/telecomm/AudioState.aidl index ae645677e3ed..03772b6614a4 100644 --- a/telecomm/java/android/telecomm/CallAudioState.aidl +++ b/telecomm/java/android/telecomm/AudioState.aidl @@ -16,4 +16,7 @@ package android.telecomm; -parcelable CallAudioState; +/** + * {@hide} + */ +parcelable AudioState; diff --git a/telecomm/java/android/telecomm/CallAudioState.java b/telecomm/java/android/telecomm/AudioState.java index d9a0090116d9..dc28b1678974 100644 --- a/telecomm/java/android/telecomm/CallAudioState.java +++ b/telecomm/java/android/telecomm/AudioState.java @@ -24,7 +24,7 @@ import java.util.Locale; /** * Encapsulates all audio states during a call. */ -public final class CallAudioState implements Parcelable { +public final class AudioState implements Parcelable { /** Direct the audio stream through the device's earpiece. */ public static int ROUTE_EARPIECE = 0x00000001; @@ -57,14 +57,14 @@ public final class CallAudioState implements Parcelable { public final int supportedRouteMask; /** @hide */ - public CallAudioState(boolean isMuted, int route, int supportedRouteMask) { + public AudioState(boolean isMuted, int route, int supportedRouteMask) { this.isMuted = isMuted; this.route = route; this.supportedRouteMask = supportedRouteMask; } /** @hide */ - public CallAudioState(CallAudioState state) { + public AudioState(AudioState state) { isMuted = state.isMuted; route = state.route; supportedRouteMask = state.supportedRouteMask; @@ -75,10 +75,10 @@ public final class CallAudioState implements Parcelable { if (obj == null) { return false; } - if (!(obj instanceof CallAudioState)) { + if (!(obj instanceof AudioState)) { return false; } - CallAudioState state = (CallAudioState) obj; + AudioState state = (AudioState) obj; return isMuted == state.isMuted && route == state.route && supportedRouteMask == state.supportedRouteMask; } @@ -86,7 +86,7 @@ public final class CallAudioState implements Parcelable { @Override public String toString() { return String.format(Locale.US, - "[CallAudioState isMuted: %b, route; %s, supportedRouteMask: %s]", + "[AudioState isMuted: %b, route; %s, supportedRouteMask: %s]", isMuted, audioRouteToString(route), audioRouteToString(supportedRouteMask)); } @@ -121,22 +121,22 @@ public final class CallAudioState implements Parcelable { } /** - * Responsible for creating CallAudioState objects for deserialized Parcels. + * Responsible for creating AudioState objects for deserialized Parcels. */ - public static final Parcelable.Creator<CallAudioState> CREATOR = - new Parcelable.Creator<CallAudioState> () { + public static final Parcelable.Creator<AudioState> CREATOR = + new Parcelable.Creator<AudioState> () { @Override - public CallAudioState createFromParcel(Parcel source) { + public AudioState createFromParcel(Parcel source) { boolean isMuted = source.readByte() == 0 ? false : true; int route = source.readInt(); int supportedRouteMask = source.readInt(); - return new CallAudioState(isMuted, route, supportedRouteMask); + return new AudioState(isMuted, route, supportedRouteMask); } @Override - public CallAudioState[] newArray(int size) { - return new CallAudioState[size]; + public AudioState[] newArray(int size) { + return new AudioState[size]; } }; @@ -149,7 +149,7 @@ public final class CallAudioState implements Parcelable { } /** - * Writes CallAudioState object into a serializeable Parcel. + * Writes AudioState object into a serializeable Parcel. */ @Override public void writeToParcel(Parcel destination, int flags) { diff --git a/telecomm/java/android/telecomm/Call.java b/telecomm/java/android/telecomm/Call.java index 0a54c71f573c..f988ac8a759b 100644 --- a/telecomm/java/android/telecomm/Call.java +++ b/telecomm/java/android/telecomm/Call.java @@ -18,6 +18,7 @@ package android.telecomm; import android.app.PendingIntent; import android.net.Uri; +import android.os.Bundle; import android.telephony.DisconnectCause; import java.lang.String; @@ -29,6 +30,8 @@ import java.util.Objects; /** * Represents an ongoing phone call that the in-call app should present to the user. + * + * {@hide} */ public final class Call { /** @@ -84,11 +87,12 @@ public final class Call { private final PhoneAccountHandle mAccountHandle; private final int mCallCapabilities; private final int mDisconnectCauseCode; - private final String mDisconnectCauseMsg; + private final String mDisconnectCauseMessage; private final long mConnectTimeMillis; private final GatewayInfo mGatewayInfo; private final int mVideoState; private final StatusHints mStatusHints; + private final Bundle mExtras; /** * @return The handle (e.g., phone number) to which the {@code Call} is currently @@ -100,7 +104,7 @@ public final class Call { /** * @return The presentation requirements for the handle. See - * {@link android.telecomm.CallPropertyPresentation} for valid values. + * {@link PropertyPresentation} for valid values. */ public int getHandlePresentation() { return mHandlePresentation; @@ -115,7 +119,7 @@ public final class Call { /** * @return The presentation requirements for the caller display name. See - * {@link android.telecomm.CallPropertyPresentation} for valid values. + * {@link PropertyPresentation} for valid values. */ public int getCallerDisplayNamePresentation() { return mCallerDisplayNamePresentation; @@ -131,7 +135,7 @@ public final class Call { /** * @return A bitmask of the capabilities of the {@code Call}, as defined in - * {@link CallCapabilities}. + * {@link PhoneCapabilities}. */ public int getCallCapabilities() { return mCallCapabilities; @@ -149,8 +153,8 @@ public final class Call { * @return For a {@link #STATE_DISCONNECTED} {@code Call}, an optional reason for * disconnection expressed as a free text message. */ - public String getDisconnectCauseMsg() { - return mDisconnectCauseMsg; + public String getDisconnectCauseMessage() { + return mDisconnectCauseMessage; } /** @@ -184,6 +188,13 @@ public final class Call { return mStatusHints; } + /** + * @return A bundle extras to pass with the call + */ + public Bundle getExtras() { + return mExtras; + } + @Override public boolean equals(Object o) { if (o instanceof Details) { @@ -197,11 +208,12 @@ public final class Call { Objects.equals(mAccountHandle, d.mAccountHandle) && Objects.equals(mCallCapabilities, d.mCallCapabilities) && Objects.equals(mDisconnectCauseCode, d.mDisconnectCauseCode) && - Objects.equals(mDisconnectCauseMsg, d.mDisconnectCauseMsg) && + Objects.equals(mDisconnectCauseMessage, d.mDisconnectCauseMessage) && Objects.equals(mConnectTimeMillis, d.mConnectTimeMillis) && Objects.equals(mGatewayInfo, d.mGatewayInfo) && Objects.equals(mVideoState, d.mVideoState) && - Objects.equals(mStatusHints, d.mStatusHints); + Objects.equals(mStatusHints, d.mStatusHints) && + Objects.equals(mExtras, d.mExtras); } return false; } @@ -216,11 +228,12 @@ public final class Call { Objects.hashCode(mAccountHandle) + Objects.hashCode(mCallCapabilities) + Objects.hashCode(mDisconnectCauseCode) + - Objects.hashCode(mDisconnectCauseMsg) + + Objects.hashCode(mDisconnectCauseMessage) + Objects.hashCode(mConnectTimeMillis) + Objects.hashCode(mGatewayInfo) + Objects.hashCode(mVideoState) + - Objects.hashCode(mStatusHints); + Objects.hashCode(mStatusHints) + + Objects.hashCode(mExtras); } /** {@hide} */ @@ -232,11 +245,12 @@ public final class Call { PhoneAccountHandle accountHandle, int capabilities, int disconnectCauseCode, - String disconnectCauseMsg, + String disconnectCauseMessage, long connectTimeMillis, GatewayInfo gatewayInfo, int videoState, - StatusHints statusHints) { + StatusHints statusHints, + Bundle extras) { mHandle = handle; mHandlePresentation = handlePresentation; mCallerDisplayName = callerDisplayName; @@ -244,11 +258,12 @@ public final class Call { mAccountHandle = accountHandle; mCallCapabilities = capabilities; mDisconnectCauseCode = disconnectCauseCode; - mDisconnectCauseMsg = disconnectCauseMsg; + mDisconnectCauseMessage = disconnectCauseMessage; mConnectTimeMillis = connectTimeMillis; mGatewayInfo = gatewayInfo; mVideoState = videoState; mStatusHints = statusHints; + mExtras = extras; } } @@ -256,8 +271,6 @@ public final class Call { /** * Invoked when the state of this {@code Call} has changed. See {@link #getState()}. * - * TODO: Provide previous state also? - * * @param call The {@code Call} invoking this method. * @param state The new state of the {@code Call}. */ @@ -459,8 +472,6 @@ public final class Call { /** * Notifies this {@code Call} that the phone account user interface element was touched. - * - * TODO: Figure out if and how we can generalize this */ public void phoneAccountClicked() { mInCallAdapter.phoneAccountClicked(mTelecommCallId); @@ -495,14 +506,6 @@ public final class Call { } /** - * Instructs this {@code Call} to swap itself with an existing background call, if one - * such call exists. - */ - public void swapWithBackgroundCall() { - mInCallAdapter.swapWithBackgroundCall(mTelecommCallId); - } - - /** * Obtains the parent of this {@code Call} in a conference, if any. * * @return The parent {@code Call}, or {@code null} if this {@code Call} is not a @@ -617,7 +620,8 @@ public final class Call { parcelableCall.getConnectTimeMillis(), parcelableCall.getGatewayInfo(), parcelableCall.getVideoState(), - parcelableCall.getStatusHints()); + parcelableCall.getStatusHints(), + parcelableCall.getExtras()); boolean detailsChanged = !Objects.equals(mDetails, details); if (detailsChanged) { mDetails = details; @@ -774,25 +778,25 @@ public final class Call { } } - private int stateFromParcelableCallState(CallState parcelableCallState) { + private int stateFromParcelableCallState(int parcelableCallState) { switch (parcelableCallState) { - case NEW: + case CallState.NEW: return STATE_NEW; - case CONNECTING: + case CallState.CONNECTING: return STATE_CONNECTING; - case PRE_DIAL_WAIT: + case CallState.PRE_DIAL_WAIT: return STATE_PRE_DIAL_WAIT; - case DIALING: + case CallState.DIALING: return STATE_DIALING; - case RINGING: + case CallState.RINGING: return STATE_RINGING; - case ACTIVE: + case CallState.ACTIVE: return STATE_ACTIVE; - case ON_HOLD: + case CallState.ON_HOLD: return STATE_HOLDING; - case DISCONNECTED: + case CallState.DISCONNECTED: return STATE_DISCONNECTED; - case ABORTED: + case CallState.ABORTED: return STATE_DISCONNECTED; default: Log.wtf(this, "Unrecognized CallState %s", parcelableCallState); diff --git a/telecomm/java/android/telecomm/CallState.java b/telecomm/java/android/telecomm/CallState.java index 0ca4840caef5..73edbe235742 100644 --- a/telecomm/java/android/telecomm/CallState.java +++ b/telecomm/java/android/telecomm/CallState.java @@ -21,22 +21,27 @@ package android.telecomm; * have the notion of normal transitions, due to the volatile nature of telephony systems, code * that uses these states should be resilient to unexpected state changes outside of what is * considered traditional. + * + * {@hide} */ -public enum CallState { +public final class CallState { + + private CallState() {} + /** * Indicates that a call is new and not connected. This is used as the default state internally * within Telecomm and should not be used between Telecomm and call services. Call services are * not expected to ever interact with NEW calls, but {@link InCallService}s will see calls in * this state. */ - NEW, + public static final int NEW = 0; /** * The initial state of an outgoing {@code Call}. * Common transitions are to {@link #DIALING} state for a successful call or * {@link #DISCONNECTED} if it failed. */ - CONNECTING, + public static final int CONNECTING = 1; /** * Indicates that the call is about to go into the outgoing and dialing state but is waiting for @@ -44,7 +49,7 @@ public enum CallState { * this is the state where the InCallUI is waiting for the user to select a * {@link PhoneAccount} to call from. */ - PRE_DIAL_WAIT, + public static final int PRE_DIAL_WAIT = 2; /** * Indicates that a call is outgoing and in the dialing state. A call transitions to this state @@ -52,7 +57,7 @@ public enum CallState { * state usually transition to {@link #ACTIVE} if the call was answered or {@link #DISCONNECTED} * if the call was disconnected somehow (e.g., failure or cancellation of the call by the user). */ - DIALING, + public static final int DIALING = 3; /** * Indicates that a call is incoming and the user still has the option of answering, rejecting, @@ -60,14 +65,14 @@ public enum CallState { * ringtone. Normal transitions are to {@link #ACTIVE} if answered or {@link #DISCONNECTED} * otherwise. */ - RINGING, + public static final int RINGING = 4; /** * Indicates that a call is currently connected to another party and a communication channel is * open between them. The normal transition to this state is by the user answering a * {@link #DIALING} call or a {@link #RINGING} call being answered by the other party. */ - ACTIVE, + public static final int ACTIVE = 5; /** * Indicates that the call is currently on hold. In this state, the call is not terminated @@ -75,7 +80,7 @@ public enum CallState { * to this state is by the user putting an {@link #ACTIVE} call on hold by explicitly performing * an action, such as clicking the hold button. */ - ON_HOLD, + public static final int ON_HOLD = 6; /** * Indicates that a call is currently disconnected. All states can transition to this state @@ -84,12 +89,36 @@ public enum CallState { * the disconnection or communication was lost to the call service currently responsible for * this call (e.g., call service crashes). */ - DISCONNECTED, + public static final int DISCONNECTED = 7; /** * Indicates that the call was attempted (mostly in the context of outgoing, at least at the * time of writing) but cancelled before it was successfully connected. - * @hide */ - ABORTED; + public static final int ABORTED = 8; + + public static String toString(int callState) { + switch (callState) { + case NEW: + return "NEW"; + case CONNECTING: + return "CONNECTING"; + case PRE_DIAL_WAIT: + return "PRE_DIAL_WAIT"; + case DIALING: + return "DIALING"; + case RINGING: + return "RINGING"; + case ACTIVE: + return "ACTIVE"; + case ON_HOLD: + return "ON_HOLD"; + case DISCONNECTED: + return "DISCONNECTED"; + case ABORTED: + return "ABORTED"; + default: + return "UNKNOWN"; + } + } } diff --git a/telecomm/java/android/telecomm/VideoCallProfile.aidl b/telecomm/java/android/telecomm/CameraCapabilities.aidl index adbf94d65fe7..08e6f434e37b 100644 --- a/telecomm/java/android/telecomm/VideoCallProfile.aidl +++ b/telecomm/java/android/telecomm/CameraCapabilities.aidl @@ -14,7 +14,9 @@ * limitations under the License */ - package android.telecomm; -parcelable VideoCallProfile; +/** + * {@hide} + */ +parcelable CameraCapabilities; diff --git a/telecomm/java/android/telecomm/CallCameraCapabilities.java b/telecomm/java/android/telecomm/CameraCapabilities.java index 74904e3ad6ad..7c7dde17a095 100644 --- a/telecomm/java/android/telecomm/CallCameraCapabilities.java +++ b/telecomm/java/android/telecomm/CameraCapabilities.java @@ -21,9 +21,8 @@ import android.os.Parcelable; /** * Represents the camera capabilities important to a Video Telephony provider. - * TODO: Add camera capabilities as required. */ -public final class CallCameraCapabilities implements Parcelable { +public final class CameraCapabilities implements Parcelable { /** * Whether the camera supports zoom. @@ -53,7 +52,7 @@ public final class CallCameraCapabilities implements Parcelable { * @param width The width of the camera video (in pixels). * @param height The height of the camera video (in pixels). */ - public CallCameraCapabilities(boolean zoomSupported, float maxZoom, int width, int height) { + public CameraCapabilities(boolean zoomSupported, float maxZoom, int width, int height) { mZoomSupported = zoomSupported; mMaxZoom = maxZoom; mWidth = width; @@ -63,8 +62,8 @@ public final class CallCameraCapabilities implements Parcelable { /** * Responsible for creating CallCameraCapabilities objects from deserialized Parcels. **/ - public static final Parcelable.Creator<CallCameraCapabilities> CREATOR = - new Parcelable.Creator<CallCameraCapabilities> () { + public static final Parcelable.Creator<CameraCapabilities> CREATOR = + new Parcelable.Creator<CameraCapabilities> () { /** * Creates a CallCameraCapabilities instances from a parcel. * @@ -72,18 +71,18 @@ public final class CallCameraCapabilities implements Parcelable { * @return The CallCameraCapabilities. */ @Override - public CallCameraCapabilities createFromParcel(Parcel source) { + public CameraCapabilities createFromParcel(Parcel source) { boolean supportsZoom = source.readByte() != 0; float maxZoom = source.readFloat(); int width = source.readInt(); int height = source.readInt(); - return new CallCameraCapabilities(supportsZoom, maxZoom, width, height); + return new CameraCapabilities(supportsZoom, maxZoom, width, height); } @Override - public CallCameraCapabilities[] newArray(int size) { - return new CallCameraCapabilities[size]; + public CameraCapabilities[] newArray(int size) { + return new CameraCapabilities[size]; } }; diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java index b3236466fa29..3ecb4cb70b8b 100644 --- a/telecomm/java/android/telecomm/Connection.java +++ b/telecomm/java/android/telecomm/Connection.java @@ -16,11 +16,20 @@ package android.telecomm; +import com.android.internal.telecomm.IVideoCallback; +import com.android.internal.telecomm.IVideoProvider; + import android.app.PendingIntent; import android.net.Uri; -import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.RemoteException; +import android.telephony.DisconnectCause; +import android.view.Surface; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; @@ -30,6 +39,29 @@ import java.util.concurrent.CopyOnWriteArraySet; */ public abstract class Connection { + public static final int STATE_INITIALIZING = 0; + + public static final int STATE_NEW = 1; + + public static final int STATE_RINGING = 2; + + public static final int STATE_DIALING = 3; + + public static final int STATE_ACTIVE = 4; + + public static final int STATE_HOLDING = 5; + + public static final int STATE_DISCONNECTED = 6; + + public static final int STATE_FAILED = 7; + + public static final int STATE_CANCELED = 8; + + // Flag controlling whether PII is emitted into the logs + private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG); + + private static Connection sNullConnection; + /** @hide */ public abstract static class Listener { public void onStateChanged(Connection c, int state) {} @@ -37,15 +69,14 @@ public abstract class Connection { public void onCallerDisplayNameChanged( Connection c, String callerDisplayName, int presentation) {} public void onVideoStateChanged(Connection c, int videoState) {} - public void onSignalChanged(Connection c, Bundle details) {} public void onDisconnected(Connection c, int cause, String message) {} public void onPostDialWait(Connection c, String remaining) {} public void onRequestingRingback(Connection c, boolean ringback) {} public void onDestroyed(Connection c) {} public void onCallCapabilitiesChanged(Connection c, int callCapabilities) {} public void onParentConnectionChanged(Connection c, Connection parent) {} - public void onVideoCallProviderChanged( - Connection c, ConnectionService.VideoCallProvider videoCallProvider) {} + public void onVideoProviderChanged( + Connection c, VideoProvider videoProvider) {} public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {} public void onStatusHintsChanged(Connection c, StatusHints statusHints) {} public void onStartActivityFromInCall(Connection c, PendingIntent intent) {} @@ -53,19 +84,359 @@ public abstract class Connection { Connection c, List<Connection> conferenceableConnections) {} } - public final class State { - private State() {} + public static abstract class VideoProvider { + + /** + * Video is not being received (no protocol pause was issued). + */ + public static final int SESSION_EVENT_RX_PAUSE = 1; + + /** + * Video reception has resumed after a SESSION_EVENT_RX_PAUSE. + */ + public static final int SESSION_EVENT_RX_RESUME = 2; + + /** + * Video transmission has begun. This occurs after a negotiated start of video transmission + * when the underlying protocol has actually begun transmitting video to the remote party. + */ + public static final int SESSION_EVENT_TX_START = 3; + + /** + * Video transmission has stopped. This occurs after a negotiated stop of video transmission + * when the underlying protocol has actually stopped transmitting video to the remote party. + */ + public static final int SESSION_EVENT_TX_STOP = 4; + + /** + * A camera failure has occurred for the selected camera. The In-Call UI can use this as a + * cue to inform the user the camera is not available. + */ + public static final int SESSION_EVENT_CAMERA_FAILURE = 5; + + /** + * Issued after {@code SESSION_EVENT_CAMERA_FAILURE} when the camera is once again ready for + * operation. The In-Call UI can use this as a cue to inform the user that the camera has + * become available again. + */ + public static final int SESSION_EVENT_CAMERA_READY = 6; + + /** + * Session modify request was successful. + */ + public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1; + + /** + * Session modify request failed. + */ + public static final int SESSION_MODIFY_REQUEST_FAIL = 2; + + /** + * Session modify request ignored due to invalid parameters. + */ + public static final int SESSION_MODIFY_REQUEST_INVALID = 3; + + private static final int MSG_SET_VIDEO_LISTENER = 1; + private static final int MSG_SET_CAMERA = 2; + private static final int MSG_SET_PREVIEW_SURFACE = 3; + private static final int MSG_SET_DISPLAY_SURFACE = 4; + private static final int MSG_SET_DEVICE_ORIENTATION = 5; + private static final int MSG_SET_ZOOM = 6; + private static final int MSG_SEND_SESSION_MODIFY_REQUEST = 7; + private static final int MSG_SEND_SESSION_MODIFY_RESPONSE = 8; + private static final int MSG_REQUEST_CAMERA_CAPABILITIES = 9; + private static final int MSG_REQUEST_CALL_DATA_USAGE = 10; + private static final int MSG_SET_PAUSE_IMAGE = 11; + + private final VideoProvider.VideoProviderHandler + mMessageHandler = new VideoProvider.VideoProviderHandler(); + private final VideoProvider.VideoProviderBinder mBinder; + private IVideoCallback mVideoListener; + + /** + * Default handler used to consolidate binder method calls onto a single thread. + */ + private final class VideoProviderHandler extends Handler { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_SET_VIDEO_LISTENER: + mVideoListener = IVideoCallback.Stub.asInterface((IBinder) msg.obj); + break; + case MSG_SET_CAMERA: + onSetCamera((String) msg.obj); + break; + case MSG_SET_PREVIEW_SURFACE: + onSetPreviewSurface((Surface) msg.obj); + break; + case MSG_SET_DISPLAY_SURFACE: + onSetDisplaySurface((Surface) msg.obj); + break; + case MSG_SET_DEVICE_ORIENTATION: + onSetDeviceOrientation(msg.arg1); + break; + case MSG_SET_ZOOM: + onSetZoom((Float) msg.obj); + break; + case MSG_SEND_SESSION_MODIFY_REQUEST: + onSendSessionModifyRequest((VideoProfile) msg.obj); + break; + case MSG_SEND_SESSION_MODIFY_RESPONSE: + onSendSessionModifyResponse((VideoProfile) msg.obj); + break; + case MSG_REQUEST_CAMERA_CAPABILITIES: + onRequestCameraCapabilities(); + break; + case MSG_REQUEST_CALL_DATA_USAGE: + onRequestCallDataUsage(); + break; + case MSG_SET_PAUSE_IMAGE: + onSetPauseImage((String) msg.obj); + break; + default: + break; + } + } + } + + /** + * IVideoProvider stub implementation. + */ + private final class VideoProviderBinder extends IVideoProvider.Stub { + public void setVideoListener(IBinder videoListenerBinder) { + mMessageHandler.obtainMessage( + MSG_SET_VIDEO_LISTENER, videoListenerBinder).sendToTarget(); + } + + public void setCamera(String cameraId) { + mMessageHandler.obtainMessage(MSG_SET_CAMERA, cameraId).sendToTarget(); + } + + public void setPreviewSurface(Surface surface) { + mMessageHandler.obtainMessage(MSG_SET_PREVIEW_SURFACE, surface).sendToTarget(); + } + + public void setDisplaySurface(Surface surface) { + mMessageHandler.obtainMessage(MSG_SET_DISPLAY_SURFACE, surface).sendToTarget(); + } + + public void setDeviceOrientation(int rotation) { + mMessageHandler.obtainMessage(MSG_SET_DEVICE_ORIENTATION, rotation).sendToTarget(); + } + + public void setZoom(float value) { + mMessageHandler.obtainMessage(MSG_SET_ZOOM, value).sendToTarget(); + } + + public void sendSessionModifyRequest(VideoProfile requestProfile) { + mMessageHandler.obtainMessage( + MSG_SEND_SESSION_MODIFY_REQUEST, requestProfile).sendToTarget(); + } + + public void sendSessionModifyResponse(VideoProfile responseProfile) { + mMessageHandler.obtainMessage( + MSG_SEND_SESSION_MODIFY_RESPONSE, responseProfile).sendToTarget(); + } + + public void requestCameraCapabilities() { + mMessageHandler.obtainMessage(MSG_REQUEST_CAMERA_CAPABILITIES).sendToTarget(); + } + + public void requestCallDataUsage() { + mMessageHandler.obtainMessage(MSG_REQUEST_CALL_DATA_USAGE).sendToTarget(); + } + + public void setPauseImage(String uri) { + mMessageHandler.obtainMessage(MSG_SET_PAUSE_IMAGE, uri).sendToTarget(); + } + } + + public VideoProvider() { + mBinder = new VideoProvider.VideoProviderBinder(); + } + + /** + * Returns binder object which can be used across IPC methods. + * @hide + */ + public final IVideoProvider getInterface() { + return mBinder; + } + + /** + * Sets the camera to be used for video recording in a video call. + * + * @param cameraId The id of the camera. + */ + public abstract void onSetCamera(String cameraId); + + /** + * Sets the surface to be used for displaying a preview of what the user's camera is + * currently capturing. When video transmission is enabled, this is the video signal which + * is sent to the remote device. + * + * @param surface The surface. + */ + public abstract void onSetPreviewSurface(Surface surface); + + /** + * Sets the surface to be used for displaying the video received from the remote device. + * + * @param surface The surface. + */ + public abstract void onSetDisplaySurface(Surface surface); + + /** + * Sets the device orientation, in degrees. Assumes that a standard portrait orientation of + * the device is 0 degrees. + * + * @param rotation The device orientation, in degrees. + */ + public abstract void onSetDeviceOrientation(int rotation); + + /** + * Sets camera zoom ratio. + * + * @param value The camera zoom ratio. + */ + public abstract void onSetZoom(float value); + + /** + * Issues a request to modify the properties of the current session. The request is + * sent to the remote device where it it handled by the In-Call UI. + * Some examples of session modification requests: upgrade call from audio to video, + * downgrade call from video to audio, pause video. + * + * @param requestProfile The requested call video properties. + */ + public abstract void onSendSessionModifyRequest(VideoProfile requestProfile); + + /**te + * Provides a response to a request to change the current call session video + * properties. + * This is in response to a request the InCall UI has received via the InCall UI. + * + * @param responseProfile The response call video properties. + */ + public abstract void onSendSessionModifyResponse(VideoProfile responseProfile); + + /** + * Issues a request to the video provider to retrieve the camera capabilities. + * Camera capabilities are reported back to the caller via the In-Call UI. + */ + public abstract void onRequestCameraCapabilities(); + + /** + * Issues a request to the video telephony framework to retrieve the cumulative data usage + * for the current call. Data usage is reported back to the caller via the + * InCall UI. + */ + public abstract void onRequestCallDataUsage(); + + /** + * Provides the video telephony framework with the URI of an image to be displayed to remote + * devices when the video signal is paused. + * + * @param uri URI of image to display. + */ + public abstract void onSetPauseImage(String uri); + + /** + * Invokes callback method defined in In-Call UI. + * + * @param videoProfile The requested video call profile. + */ + public void receiveSessionModifyRequest(VideoProfile videoProfile) { + if (mVideoListener != null) { + try { + mVideoListener.receiveSessionModifyRequest(videoProfile); + } catch (RemoteException ignored) { + } + } + } + + /** + * Invokes callback method defined in In-Call UI. + * + * @param status Status of the session modify request. Valid values are + * {@link VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS}, + * {@link VideoProvider#SESSION_MODIFY_REQUEST_FAIL}, + * {@link VideoProvider#SESSION_MODIFY_REQUEST_INVALID} + * @param requestedProfile The original request which was sent to the remote device. + * @param responseProfile The actual profile changes made by the remote device. + */ + public void receiveSessionModifyResponse(int status, + VideoProfile requestedProfile, VideoProfile responseProfile) { + if (mVideoListener != null) { + try { + mVideoListener.receiveSessionModifyResponse( + status, requestedProfile, responseProfile); + } catch (RemoteException ignored) { + } + } + } - public static final int INITIALIZING = 0; - public static final int NEW = 1; - public static final int RINGING = 2; - public static final int DIALING = 3; - public static final int ACTIVE = 4; - public static final int HOLDING = 5; - public static final int DISCONNECTED = 6; - public static final int FAILED = 7; - public static final int CANCELED = 8; + /** + * Invokes callback method defined in In-Call UI. + * + * Valid values are: {@link VideoProvider#SESSION_EVENT_RX_PAUSE}, + * {@link VideoProvider#SESSION_EVENT_RX_RESUME}, + * {@link VideoProvider#SESSION_EVENT_TX_START}, + * {@link VideoProvider#SESSION_EVENT_TX_STOP} + * + * @param event The event. + */ + public void handleCallSessionEvent(int event) { + if (mVideoListener != null) { + try { + mVideoListener.handleCallSessionEvent(event); + } catch (RemoteException ignored) { + } + } + } + + /** + * Invokes callback method defined in In-Call UI. + * + * @param width The updated peer video width. + * @param height The updated peer video height. + */ + public void changePeerDimensions(int width, int height) { + if (mVideoListener != null) { + try { + mVideoListener.changePeerDimensions(width, height); + } catch (RemoteException ignored) { + } + } + } + /** + * Invokes callback method defined in In-Call UI. + * + * @param dataUsage The updated data usage. + */ + public void changeCallDataUsage(int dataUsage) { + if (mVideoListener != null) { + try { + mVideoListener.changeCallDataUsage(dataUsage); + } catch (RemoteException ignored) { + } + } + } + + /** + * Invokes callback method defined in In-Call UI. + * + * @param cameraCapabilities The changed camera capabilities. + */ + public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) { + if (mVideoListener != null) { + try { + mVideoListener.changeCameraCapabilities(cameraCapabilities); + } catch (RemoteException ignored) { + } + } + } } private final Listener mConnectionDeathListener = new Listener() { @@ -79,10 +450,14 @@ public abstract class Connection { private final Set<Listener> mListeners = new CopyOnWriteArraySet<>(); private final List<Connection> mChildConnections = new ArrayList<>(); + private final List<Connection> mUnmodifiableChildConnections = + Collections.unmodifiableList(mChildConnections); private final List<Connection> mConferenceableConnections = new ArrayList<>(); + private final List<Connection> mUnmodifiableConferenceableConnections = + Collections.unmodifiableList(mConferenceableConnections); - private int mState = State.NEW; - private CallAudioState mCallAudioState; + private int mState = STATE_NEW; + private AudioState mAudioState; private Uri mHandle; private int mHandlePresentation; private String mCallerDisplayName; @@ -90,7 +465,7 @@ public abstract class Connection { private boolean mRequestingRingback = false; private int mCallCapabilities; private Connection mParentConnection; - private ConnectionService.VideoCallProvider mVideoCallProvider; + private VideoProvider mVideoProvider; private boolean mAudioModeIsVoip; private StatusHints mStatusHints; private int mVideoState; @@ -111,7 +486,7 @@ public abstract class Connection { } /** - * @return The {@link CallPropertyPresentation} which controls how the handle is shown. + * @return The {@link PropertyPresentation} which controls how the handle is shown. */ public final int getHandlePresentation() { return mHandlePresentation; @@ -125,7 +500,7 @@ public abstract class Connection { } /** - * @return The {@link CallPropertyPresentation} which controls how the caller display name is + * @return The {@link PropertyPresentation} which controls how the caller display name is * shown. */ public final int getCallerDisplayNamePresentation() { @@ -141,10 +516,10 @@ public abstract class Connection { /** * Returns the video state of the call. - * Valid values: {@link android.telecomm.VideoCallProfile.VideoState#AUDIO_ONLY}, - * {@link android.telecomm.VideoCallProfile.VideoState#BIDIRECTIONAL}, - * {@link android.telecomm.VideoCallProfile.VideoState#TX_ENABLED}, - * {@link android.telecomm.VideoCallProfile.VideoState#RX_ENABLED}. + * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY}, + * {@link VideoProfile.VideoState#BIDIRECTIONAL}, + * {@link VideoProfile.VideoState#TX_ENABLED}, + * {@link VideoProfile.VideoState#RX_ENABLED}. * * @return The video state of the call. */ @@ -157,8 +532,8 @@ public abstract class Connection { * being routed by the system. This is {@code null} if this Connection * does not directly know about its audio state. */ - public final CallAudioState getCallAudioState() { - return mCallAudioState; + public final AudioState getAudioState() { + return mAudioState; } /** @@ -236,36 +611,36 @@ public abstract class Connection { * @param state The new audio state. * @hide */ - final void setAudioState(CallAudioState state) { + final void setAudioState(AudioState state) { Log.d(this, "setAudioState %s", state); - mCallAudioState = state; + mAudioState = state; onSetAudioState(state); } /** - * @param state An integer value from {@link State}. + * @param state An integer value of a {@code STATE_*} constant. * @return A string representation of the value. */ public static String stateToString(int state) { switch (state) { - case State.INITIALIZING: - return "INITIALIZING"; - case State.NEW: - return "NEW"; - case State.RINGING: - return "RINGING"; - case State.DIALING: - return "DIALING"; - case State.ACTIVE: - return "ACTIVE"; - case State.HOLDING: - return "HOLDING"; - case State.DISCONNECTED: + case STATE_INITIALIZING: + return "STATE_INITIALIZING"; + case STATE_NEW: + return "STATE_NEW"; + case STATE_RINGING: + return "STATE_RINGING"; + case STATE_DIALING: + return "STATE_DIALING"; + case STATE_ACTIVE: + return "STATE_ACTIVE"; + case STATE_HOLDING: + return "STATE_HOLDING"; + case STATE_DISCONNECTED: return "DISCONNECTED"; - case State.FAILED: - return "FAILED"; - case State.CANCELED: - return "CANCELED"; + case STATE_FAILED: + return "STATE_FAILED"; + case STATE_CANCELED: + return "STATE_CANCELED"; default: Log.wtf(Connection.class, "Unknown state %d", state); return "UNKNOWN"; @@ -297,11 +672,11 @@ public abstract class Connection { } public final List<Connection> getChildConnections() { - return mChildConnections; + return mUnmodifiableChildConnections; } /** - * Returns the connection's {@link CallCapabilities} + * Returns the connection's {@link PhoneCapabilities} */ public final int getCallCapabilities() { return mCallCapabilities; @@ -311,7 +686,7 @@ public abstract class Connection { * Sets the value of the {@link #getHandle()} property. * * @param handle The new handle. - * @param presentation The {@link CallPropertyPresentation} which controls how the handle is + * @param presentation The {@link PropertyPresentation} which controls how the handle is * shown. */ public final void setHandle(Uri handle, int presentation) { @@ -327,7 +702,7 @@ public abstract class Connection { * Sets the caller display name (CNAP). * * @param callerDisplayName The new display name. - * @param presentation The {@link CallPropertyPresentation} which controls how the name is + * @param presentation The {@link PropertyPresentation} which controls how the name is * shown. */ public final void setCallerDisplayName(String callerDisplayName, int presentation) { @@ -345,17 +720,17 @@ public abstract class Connection { */ public final void setCanceled() { Log.d(this, "setCanceled"); - setState(State.CANCELED); + setState(STATE_CANCELED); } /** - * Move the {@link Connection} to the {@link State#FAILED} state, with the given code + * Move the {@link Connection} to the {@link #STATE_FAILED} state, with the given code * ({@see DisconnectCause}) and message. This message is not shown to the user, but is useful * for logging and debugging purposes. * <p> * After calling this, the {@link Connection} will not be used. * - * @param code The {@link android.telephony.DisconnectCause} indicating why the connection + * @param code The {@link DisconnectCause} indicating why the connection * failed. * @param message A message explaining why the {@link Connection} failed. */ @@ -363,15 +738,15 @@ public abstract class Connection { Log.d(this, "setFailed (%d: %s)", code, message); mFailureCode = code; mFailureMessage = message; - setState(State.FAILED); + setState(STATE_FAILED); } /** * Set the video state for the connection. - * Valid values: {@link android.telecomm.VideoCallProfile.VideoState#AUDIO_ONLY}, - * {@link android.telecomm.VideoCallProfile.VideoState#BIDIRECTIONAL}, - * {@link android.telecomm.VideoCallProfile.VideoState#TX_ENABLED}, - * {@link android.telecomm.VideoCallProfile.VideoState#RX_ENABLED}. + * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY}, + * {@link VideoProfile.VideoState#BIDIRECTIONAL}, + * {@link VideoProfile.VideoState#TX_ENABLED}, + * {@link VideoProfile.VideoState#RX_ENABLED}. * * @param videoState The new video state. */ @@ -389,68 +764,68 @@ public abstract class Connection { */ public final void setActive() { setRequestingRingback(false); - setState(State.ACTIVE); + setState(STATE_ACTIVE); } /** * Sets state to ringing (e.g., an inbound ringing call). */ public final void setRinging() { - setState(State.RINGING); + setState(STATE_RINGING); } /** * Sets state to initializing (this Connection is not yet ready to be used). */ public final void setInitializing() { - setState(State.INITIALIZING); + setState(STATE_INITIALIZING); } /** * Sets state to initialized (the Connection has been set up and is now ready to be used). */ public final void setInitialized() { - setState(State.NEW); + setState(STATE_NEW); } /** * Sets state to dialing (e.g., dialing an outbound call). */ public final void setDialing() { - setState(State.DIALING); + setState(STATE_DIALING); } /** * Sets state to be on hold. */ public final void setOnHold() { - setState(State.HOLDING); + setState(STATE_HOLDING); } /** * Sets the video call provider. - * @param videoCallProvider The video call provider. + * @param videoProvider The video provider. */ - public final void setVideoCallProvider(ConnectionService.VideoCallProvider videoCallProvider) { - mVideoCallProvider = videoCallProvider; + public final void setVideoProvider(VideoProvider videoProvider) { + mVideoProvider = videoProvider; for (Listener l : mListeners) { - l.onVideoCallProviderChanged(this, videoCallProvider); + l.onVideoProviderChanged(this, videoProvider); } } - public final ConnectionService.VideoCallProvider getVideoCallProvider() { - return mVideoCallProvider; + public final VideoProvider getVideoProvider() { + return mVideoProvider; } /** * Sets state to disconnected. * * @param cause The reason for the disconnection, any of - * {@link android.telephony.DisconnectCause}. + * {@link DisconnectCause}. * @param message Optional call-service-provided message about the disconnect. */ public final void setDisconnected(int cause, String message) { - setState(State.DISCONNECTED); + setState(STATE_DISCONNECTED); Log.d(this, "Disconnected with cause %d message %s", cause, message); for (Listener l : mListeners) { l.onDisconnected(this, cause, message); @@ -482,7 +857,7 @@ public abstract class Connection { } /** - * Sets the connection's {@link CallCapabilities}. + * Sets the connection's {@link PhoneCapabilities}. * * @param callCapabilities The new call capabilities. */ @@ -510,17 +885,6 @@ public abstract class Connection { } /** - * Sets the current signal levels for the underlying data transport. - * - * @param details A {@link android.os.Bundle} containing details of the current level. - */ - public final void setSignal(Bundle details) { - for (Listener l : mListeners) { - l.onSignalChanged(this, details); - } - } - - /** * Requests that the framework use VOIP audio mode for this connection. * * @param isVoip True if the audio mode is VOIP. @@ -563,6 +927,13 @@ public abstract class Connection { } /** + * Obtains the connections with which this connection can be conferenced. + */ + public final List<Connection> getConferenceableConnections() { + return mUnmodifiableConferenceableConnections; + } + + /** * Launches an activity for this connection on top of the in-call UI. * * @param intent The intent to use to start the activity. @@ -577,17 +948,17 @@ public abstract class Connection { } /** - * Notifies this Connection that the {@link #getCallAudioState()} property has a new value. + * Notifies this Connection that the {@link #getAudioState()} property has a new value. * * @param state The new call audio state. */ - public void onSetAudioState(CallAudioState state) {} + public void onSetAudioState(AudioState state) {} /** * Notifies this Connection of an internal state change. This method is called after the * state is changed. * - * @param state The new state, a {@link Connection.State} member. + * @param state The new state, one of the {@code STATE_*} constants. */ public void onSetState(int state) {} @@ -629,7 +1000,7 @@ public abstract class Connection { public void onUnhold() {} /** - * Notifies this Connection, which is in {@link State#RINGING}, of + * Notifies this Connection, which is in {@link #STATE_RINGING}, of * a request to accept. * * @param videoState The video state in which to answer the call. @@ -637,7 +1008,7 @@ public abstract class Connection { public void onAnswer(int videoState) {} /** - * Notifies this Connection, which is in {@link State#RINGING}, of + * Notifies this Connection, which is in {@link #STATE_RINGING}, of * a request to reject. */ public void onReject() {} @@ -648,12 +1019,6 @@ public abstract class Connection { public void onPostDialContinue(boolean proceed) {} /** - * Swap this call with a background call. This is used for calls that don't support hold, - * e.g. CDMA. - */ - public void onSwapWithBackgroundCall() {} - - /** * TODO: Needs documentation. */ public void onChildrenChanged(List<Connection> children) {} @@ -673,6 +1038,38 @@ public abstract class Connection { */ public void onConferenceWith(Connection otherConnection) {} + static String toLogSafePhoneNumber(String number) { + // For unknown number, log empty string. + if (number == null) { + return ""; + } + + if (PII_DEBUG) { + // When PII_DEBUG is true we emit PII. + return number; + } + + // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare + // sanitized phone numbers. + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < number.length(); i++) { + char c = number.charAt(i); + if (c == '-' || c == '@' || c == '.') { + builder.append(c); + } else { + builder.append('x'); + } + } + return builder.toString(); + } + + static synchronized Connection getNullConnection() { + if (sNullConnection == null) { + sNullConnection = new Connection() {}; + } + return sNullConnection; + } + private void addChild(Connection connection) { Log.d(this, "adding child %s", connection); mChildConnections.add(connection); @@ -686,7 +1083,7 @@ public abstract class Connection { } private void setState(int state) { - if (mState == State.FAILED || mState == State.CANCELED) { + if (mState == STATE_FAILED || mState == STATE_CANCELED) { Log.d(this, "Connection already %s; cannot transition out of this state.", stateToString(mState)); return; @@ -711,7 +1108,7 @@ public abstract class Connection { * @param message A reason for why the connection failed (not intended to be shown to the user). * @return A {@link Connection} which indicates failure. */ - public static Connection getFailedConnection(final int code, final String message) { + public static Connection createFailedConnection(final int code, final String message) { return new Connection() {{ setFailed(code, message); }}; @@ -723,13 +1120,13 @@ public abstract class Connection { /** * Return a {@link Connection} which represents a canceled a connection attempt. The returned - * {@link Connection} will have state {@link State#CANCELED}, and cannot be moved out of that + * {@link Connection} will have state {@link #STATE_CANCELED}, and cannot be moved out of that * state. This connection should not be used for anything, and no other {@link Connection}s * should be attempted. * * @return A {@link Connection} which indicates that the underlying call should be canceled. */ - public static Connection getCanceledConnection() { + public static Connection createCanceledConnection() { return CANCELED_CONNECTION; } diff --git a/telecomm/java/android/telecomm/ConnectionRequest.aidl b/telecomm/java/android/telecomm/ConnectionRequest.aidl index 72e5c8c4a0be..6081c2247f7b 100644 --- a/telecomm/java/android/telecomm/ConnectionRequest.aidl +++ b/telecomm/java/android/telecomm/ConnectionRequest.aidl @@ -16,4 +16,7 @@ package android.telecomm; +/** + * {@hide} + */ parcelable ConnectionRequest; diff --git a/telecomm/java/android/telecomm/ConnectionRequest.java b/telecomm/java/android/telecomm/ConnectionRequest.java index 10160914ed33..5ea1d1ab660f 100644 --- a/telecomm/java/android/telecomm/ConnectionRequest.java +++ b/telecomm/java/android/telecomm/ConnectionRequest.java @@ -20,8 +20,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; -import android.os.ResultReceiver; -import android.telephony.DisconnectCause; /** * Simple data container encapsulating a request to some entity to @@ -30,10 +28,7 @@ import android.telephony.DisconnectCause; public final class ConnectionRequest implements Parcelable { // TODO: Token to limit recursive invocations - // TODO: Consider upgrading "mHandle" to ordered list of handles, indicating a set of phone - // numbers that would satisfy the client's needs, in order of preference private final PhoneAccountHandle mAccountHandle; - private final String mCallId; private final Uri mHandle; private final int mHandlePresentation; private final Bundle mExtras; @@ -41,22 +36,19 @@ public final class ConnectionRequest implements Parcelable { /** * @param accountHandle The accountHandle which should be used to place the call. - * @param callId An identifier for this call. * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect. - * @param handlePresentation The {@link CallPropertyPresentation} which controls how the handle + * @param handlePresentation The {@link PropertyPresentation} which controls how the handle * is shown. * @param extras Application-specific extra data. * @param videoState Determines the video state for the connection. */ public ConnectionRequest( PhoneAccountHandle accountHandle, - String callId, Uri handle, int handlePresentation, Bundle extras, int videoState) { mAccountHandle = accountHandle; - mCallId = callId; mHandle = handle; mHandlePresentation = handlePresentation; mExtras = extras; @@ -65,7 +57,6 @@ public final class ConnectionRequest implements Parcelable { private ConnectionRequest(Parcel in) { mAccountHandle = in.readParcelable(getClass().getClassLoader()); - mCallId = in.readString(); mHandle = in.readParcelable(getClass().getClassLoader()); mHandlePresentation = in.readInt(); mExtras = in.readParcelable(getClass().getClassLoader()); @@ -78,17 +69,12 @@ public final class ConnectionRequest implements Parcelable { public PhoneAccountHandle getAccountHandle() { return mAccountHandle; } /** - * An identifier for this call. - */ - public String getCallId() { return mCallId; } - - /** * The handle (e.g., phone number) to which the {@link Connection} is to connect. */ public Uri getHandle() { return mHandle; } /** - * The {@link CallPropertyPresentation} which controls how the handle is shown. + * The {@link PropertyPresentation} which controls how the handle is shown. */ public int getHandlePresentation() { return mHandlePresentation; } @@ -100,11 +86,11 @@ public final class ConnectionRequest implements Parcelable { public Bundle getExtras() { return mExtras; } /** - * Determines the video state for the connection. - * Valid values: {@link VideoCallProfile.VideoState#AUDIO_ONLY}, - * {@link VideoCallProfile.VideoState#BIDIRECTIONAL}, - * {@link VideoCallProfile.VideoState#TX_ENABLED}, - * {@link VideoCallProfile.VideoState#RX_ENABLED}. + * Describes the video states supported by the client requesting the connection. + * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY}, + * {@link VideoProfile.VideoState#BIDIRECTIONAL}, + * {@link VideoProfile.VideoState#TX_ENABLED}, + * {@link VideoProfile.VideoState#RX_ENABLED}. * * @return The video state for the connection. */ @@ -114,10 +100,10 @@ public final class ConnectionRequest implements Parcelable { @Override public String toString() { - return String.format("PhoneConnectionRequest %s %s", + return String.format("ConnectionRequest %s %s", mHandle == null ? Uri.EMPTY - : ConnectionService.toLogSafePhoneNumber(mHandle.toString()), + : Connection.toLogSafePhoneNumber(mHandle.toString()), mExtras == null ? "" : mExtras); } @@ -144,7 +130,6 @@ public final class ConnectionRequest implements Parcelable { @Override public void writeToParcel(Parcel destination, int flags) { destination.writeParcelable(mAccountHandle, 0); - destination.writeString(mCallId); destination.writeParcelable(mHandle, 0); destination.writeInt(mHandlePresentation); destination.writeParcelable(mExtras, 0); diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java index 80c7bbce5929..d5e4f1b2cd13 100644 --- a/telecomm/java/android/telecomm/ConnectionService.java +++ b/telecomm/java/android/telecomm/ConnectionService.java @@ -17,26 +17,20 @@ package android.telecomm; import android.annotation.SdkConstant; -import android.annotation.SdkConstant.SdkConstantType; import android.app.PendingIntent; import android.app.Service; import android.content.ComponentName; import android.content.Intent; import android.net.Uri; -import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.telephony.DisconnectCause; -import android.os.RemoteException; -import android.view.Surface; import com.android.internal.os.SomeArgs; import com.android.internal.telecomm.IConnectionService; import com.android.internal.telecomm.IConnectionServiceAdapter; -import com.android.internal.telecomm.IVideoCallCallback; -import com.android.internal.telecomm.IVideoCallProvider; import com.android.internal.telecomm.RemoteServiceCallback; import java.util.ArrayList; @@ -51,10 +45,11 @@ import java.util.Map; * Android device. */ public abstract class ConnectionService extends Service { + /** * The {@link Intent} that must be declared as handled by the service. */ - @SdkConstant(SdkConstantType.SERVICE_ACTION) + @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) public static final String SERVICE_INTERFACE = "android.telecomm.ConnectionService"; // Flag controlling whether PII is emitted into the logs @@ -73,12 +68,9 @@ public abstract class ConnectionService extends Service { private static final int MSG_STOP_DTMF_TONE = 11; private static final int MSG_CONFERENCE = 12; private static final int MSG_SPLIT_FROM_CONFERENCE = 13; - private static final int MSG_SWAP_WITH_BACKGROUND_CALL = 14; - private static final int MSG_ON_POST_DIAL_CONTINUE = 15; - private static final int MSG_ON_PHONE_ACCOUNT_CLICKED = 16; - private static final int MSG_REMOVE_CONNECTION_SERVICE_ADAPTER = 17; - - private static Connection sNullConnection; + private static final int MSG_ON_POST_DIAL_CONTINUE = 14; + private static final int MSG_ON_PHONE_ACCOUNT_CLICKED = 15; + private static final int MSG_REMOVE_CONNECTION_SERVICE_ADAPTER = 16; private final Map<String, Connection> mConnectionById = new HashMap<>(); private final Map<Connection, String> mIdByConnection = new HashMap<>(); @@ -88,37 +80,6 @@ public abstract class ConnectionService extends Service { private final List<Runnable> mPreInitializationConnectionRequests = new ArrayList<>(); private final ConnectionServiceAdapter mAdapter = new ConnectionServiceAdapter(); - /** - * A callback for providing the result of creating a connection. - */ - public interface CreateConnectionResponse<CONNECTION> { - /** - * Tells Telecomm that an attempt to create the connection succeeded. - * - * @param request The original request. - * @param connection The connection. - */ - void onSuccess(ConnectionRequest request, CONNECTION connection); - - /** - * Tells Telecomm that an attempt to create the connection failed. Telecomm will try a - * different service until a service cancels the process or completes it successfully. - * - * @param request The original request. - * @param code An integer code indicating the reason for failure. - * @param msg A message explaining the reason for failure. - */ - void onFailure(ConnectionRequest request, int code, String msg); - - /** - * Tells Telecomm to cancel creating the connection. Telecomm will stop trying to create - * the connection an no more services will be tried. - * - * @param request The original request. - */ - void onCancel(ConnectionRequest request); - } - private final IBinder mBinder = new IConnectionService.Stub() { @Override public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) { @@ -132,11 +93,13 @@ public abstract class ConnectionService extends Service { @Override public void createConnection( PhoneAccountHandle connectionManagerPhoneAccount, + String id, ConnectionRequest request, boolean isIncoming) { SomeArgs args = SomeArgs.obtain(); args.arg1 = connectionManagerPhoneAccount; - args.arg2 = request; + args.arg2 = id; + args.arg3 = request; args.argi1 = isIncoming ? 1 : 0; mHandler.obtainMessage(MSG_CREATE_CONNECTION, args).sendToTarget(); } @@ -175,7 +138,7 @@ public abstract class ConnectionService extends Service { } @Override - public void onAudioStateChanged(String callId, CallAudioState audioState) { + public void onAudioStateChanged(String callId, AudioState audioState) { SomeArgs args = SomeArgs.obtain(); args.arg1 = callId; args.arg2 = audioState; @@ -206,11 +169,6 @@ public abstract class ConnectionService extends Service { } @Override - public void swapWithBackgroundCall(String callId) { - mHandler.obtainMessage(MSG_SWAP_WITH_BACKGROUND_CALL, callId).sendToTarget(); - } - - @Override public void onPostDialContinue(String callId, boolean proceed) { SomeArgs args = SomeArgs.obtain(); args.arg1 = callId; @@ -240,22 +198,27 @@ public abstract class ConnectionService extends Service { try { final PhoneAccountHandle connectionManagerPhoneAccount = (PhoneAccountHandle) args.arg1; - final ConnectionRequest request = (ConnectionRequest) args.arg2; + final String id = (String) args.arg2; + final ConnectionRequest request = (ConnectionRequest) args.arg3; final boolean isIncoming = args.argi1 == 1; if (!mAreAccountsInitialized) { - Log.d(this, "Enqueueing pre-init request %s", request.getCallId()); + Log.d(this, "Enqueueing pre-init request %s", id); mPreInitializationConnectionRequests.add(new Runnable() { @Override public void run() { createConnection( connectionManagerPhoneAccount, + id, request, isIncoming); } }); } else { - Log.d(this, "Immediately processing request %s", request.getCallId()); - createConnection(connectionManagerPhoneAccount, request, isIncoming); + createConnection( + connectionManagerPhoneAccount, + id, + request, + isIncoming); } } finally { args.recycle(); @@ -292,7 +255,7 @@ public abstract class ConnectionService extends Service { SomeArgs args = (SomeArgs) msg.obj; try { String callId = (String) args.arg1; - CallAudioState audioState = (CallAudioState) args.arg2; + AudioState audioState = (AudioState) args.arg2; onAudioStateChanged(callId, audioState); } finally { args.recycle(); @@ -319,9 +282,6 @@ public abstract class ConnectionService extends Service { case MSG_SPLIT_FROM_CONFERENCE: splitFromConference((String) msg.obj); break; - case MSG_SWAP_WITH_BACKGROUND_CALL: - swapWithBackgroundCall((String) msg.obj); - break; case MSG_ON_POST_DIAL_CONTINUE: { SomeArgs args = (SomeArgs) msg.obj; try { @@ -348,22 +308,22 @@ public abstract class ConnectionService extends Service { String id = mIdByConnection.get(c); Log.d(this, "Adapter set state %s %s", id, Connection.stateToString(state)); switch (state) { - case Connection.State.ACTIVE: + case Connection.STATE_ACTIVE: mAdapter.setActive(id); break; - case Connection.State.DIALING: + case Connection.STATE_DIALING: mAdapter.setDialing(id); break; - case Connection.State.DISCONNECTED: + case Connection.STATE_DISCONNECTED: // Handled in onDisconnected() break; - case Connection.State.HOLDING: + case Connection.STATE_HOLDING: mAdapter.setOnHold(id); break; - case Connection.State.NEW: + case Connection.STATE_NEW: // Nothing to tell Telecomm break; - case Connection.State.RINGING: + case Connection.STATE_RINGING: mAdapter.setRinging(id); break; } @@ -397,11 +357,6 @@ public abstract class ConnectionService extends Service { } @Override - public void onSignalChanged(Connection c, Bundle details) { - // TODO: Unsupported yet - } - - @Override public void onDestroyed(Connection c) { removeConnection(c); } @@ -421,11 +376,11 @@ public abstract class ConnectionService extends Service { } @Override - public void onCallCapabilitiesChanged(Connection c, int callCapabilities) { + public void onCallCapabilitiesChanged(Connection c, int capabilities) { String id = mIdByConnection.get(c); - Log.d(this, "call capabilities: parcelableconnection: %s", - CallCapabilities.toString(callCapabilities)); - mAdapter.setCallCapabilities(id, callCapabilities); + Log.d(this, "capabilities: parcelableconnection: %s", + PhoneCapabilities.toString(capabilities)); + mAdapter.setCallCapabilities(id, capabilities); } @Override @@ -436,9 +391,9 @@ public abstract class ConnectionService extends Service { } @Override - public void onVideoCallProviderChanged(Connection c, VideoCallProvider videoCallProvider) { + public void onVideoProviderChanged(Connection c, Connection.VideoProvider videoProvider) { String id = mIdByConnection.get(c); - mAdapter.setVideoCallProvider(id, videoCallProvider); + mAdapter.setVideoProvider(id, videoProvider); } @Override @@ -487,6 +442,7 @@ public abstract class ConnectionService extends Service { */ private void createConnection( final PhoneAccountHandle callManagerAccount, + final String callId, final ConnectionRequest request, boolean isIncoming) { Log.d(this, "call %s", request); @@ -499,64 +455,79 @@ public abstract class ConnectionService extends Service { } if (createdConnection != null) { - if (createdConnection.getState() == Connection.State.INITIALIZING) { + Log.d(this, "adapter handleCreateConnectionSuccessful %s", callId); + if (createdConnection.getState() == Connection.STATE_INITIALIZING) { // Wait for the connection to become initialized. createdConnection.addConnectionListener(new Connection.Listener() { @Override public void onStateChanged(Connection c, int state) { switch (state) { - case Connection.State.FAILED: + case Connection.STATE_FAILED: Log.d(this, "Connection (%s) failed (%d: %s)", request, c.getFailureCode(), c.getFailureMessage()); Log.d(this, "adapter handleCreateConnectionFailed %s", - request.getCallId()); - mAdapter.handleCreateConnectionFailed(request, c.getFailureCode(), + callId); + mAdapter.handleCreateConnectionFailed( + callId, + request, + c.getFailureCode(), c.getFailureMessage()); break; - case Connection.State.CANCELED: + case Connection.STATE_CANCELED: Log.d(this, "adapter handleCreateConnectionCanceled %s", - request.getCallId()); - mAdapter.handleCreateConnectionCancelled(request); + callId); + mAdapter.handleCreateConnectionCancelled(callId, request); break; - case Connection.State.INITIALIZING: - Log.d(this, "State changed to INITIALIZING; ignoring"); + case Connection.STATE_INITIALIZING: + Log.d(this, "State changed to STATE_INITIALIZING; ignoring"); return; // Don't want to stop listening on this state transition. default: Log.d(this, "Connection created in state %s", Connection.stateToString(state)); - connectionCreated(request, createdConnection); + connectionCreated(callId, request, createdConnection); break; } c.removeConnectionListener(this); } }); - } else if (createdConnection.getState() == Connection.State.CANCELED) { + } else if (createdConnection.getState() == Connection.STATE_CANCELED) { // Tell telecomm not to attempt any more services. - mAdapter.handleCreateConnectionCancelled(request); - } else if (createdConnection.getState() == Connection.State.FAILED) { - mAdapter.handleCreateConnectionFailed(request, createdConnection.getFailureCode(), + mAdapter.handleCreateConnectionCancelled(callId, request); + } else if (createdConnection.getState() == Connection.STATE_FAILED) { + mAdapter.handleCreateConnectionFailed( + callId, + request, + createdConnection.getFailureCode(), createdConnection.getFailureMessage()); } else { - connectionCreated(request, createdConnection); + connectionCreated(callId, request, createdConnection); } } else { // Tell telecomm to try a different service. - Log.d(this, "adapter handleCreateConnectionFailed %s", request.getCallId()); - mAdapter.handleCreateConnectionFailed(request, DisconnectCause.ERROR_UNSPECIFIED, null); + Log.d(this, "adapter handleCreateConnectionFailed %s", callId); + mAdapter.handleCreateConnectionFailed( + callId, + request, + DisconnectCause.ERROR_UNSPECIFIED, + null); } } - private void connectionCreated(ConnectionRequest request, Connection connection) { - addConnection(request.getCallId(), connection); + private void connectionCreated( + String callId, + ConnectionRequest request, + Connection connection) { + addConnection(callId, connection); Uri handle = connection.getHandle(); String number = handle == null ? "null" : handle.getSchemeSpecificPart(); Log.v(this, "connectionCreated, parcelableconnection: %s, %d, %s", - toLogSafePhoneNumber(number), + Connection.toLogSafePhoneNumber(number), connection.getState(), - CallCapabilities.toString(connection.getCallCapabilities())); + PhoneCapabilities.toString(connection.getCallCapabilities())); - Log.d(this, "adapter handleCreateConnectionSuccessful %s", request.getCallId()); + Log.d(this, "adapter handleCreateConnectionSuccessful %s", callId); mAdapter.handleCreateConnectionSuccessful( + callId, request, new ParcelableConnection( request.getAccountHandle(), @@ -566,8 +537,8 @@ public abstract class ConnectionService extends Service { connection.getHandlePresentation(), connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation(), - connection.getVideoCallProvider() == null ? - null : connection.getVideoCallProvider().getInterface(), + connection.getVideoProvider() == null ? + null : connection.getVideoProvider().getInterface(), connection.getVideoState())); } @@ -601,7 +572,7 @@ public abstract class ConnectionService extends Service { findConnectionForAction(callId, "unhold").onUnhold(); } - private void onAudioStateChanged(String callId, CallAudioState audioState) { + private void onAudioStateChanged(String callId, AudioState audioState) { Log.d(this, "onAudioStateChanged %s %s", callId, audioState); findConnectionForAction(callId, "onAudioStateChanged").setAudioState(audioState); } @@ -620,7 +591,7 @@ public abstract class ConnectionService extends Service { Log.d(this, "conference %s, %s", conferenceCallId, callId); Connection connection = findConnectionForAction(callId, "conference"); - if (connection == getNullConnection()) { + if (connection == Connection.getNullConnection()) { Log.w(this, "Connection missing in conference request %s.", callId); return; } @@ -653,7 +624,7 @@ public abstract class ConnectionService extends Service { Log.d(this, "splitFromConference(%s)", callId); Connection connection = findConnectionForAction(callId, "splitFromConference"); - if (connection == getNullConnection()) { + if (connection == Connection.getNullConnection()) { Log.w(this, "Connection missing in conference request %s.", callId); return; } @@ -661,11 +632,6 @@ public abstract class ConnectionService extends Service { // TODO: Find existing conference call and invoke split(connection). } - private void swapWithBackgroundCall(String callId) { - Log.d(this, "swapWithBackgroundCall(%s)", callId); - findConnectionForAction(callId, "swapWithBackgroundCall").onSwapWithBackgroundCall(); - } - private void onPostDialContinue(String callId, boolean proceed) { Log.d(this, "onPostDialContinue(%s)", callId); findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed); @@ -792,7 +758,7 @@ public abstract class ConnectionService extends Service { * making the connection. * @param request Details about the outgoing call. * @return The {@code Connection} object to satisfy this call, or the result of an invocation - * of {@link Connection#getFailedConnection(int, String)} to not handle the call. + * of {@link Connection#createFailedConnection(int, String)} to not handle the call. */ public Connection onCreateOutgoingConnection( PhoneAccountHandle connectionManagerPhoneAccount, @@ -805,6 +771,9 @@ public abstract class ConnectionService extends Service { * specified connection into a conference call. The specified connection can be any connection * which had previously specified itself as conference-capable including both simple connections * and connections previously returned from this method. + * <p> + * TODO: To be refactored out with conference call re-engineering<br/> + * TODO: Also remove class {@link Response} once this method is removed * * @param connection The connection from which the user opted to start a conference call. * @param token The token to be passed into the response callback. @@ -829,31 +798,6 @@ public abstract class ConnectionService extends Service { */ public void onConnectionRemoved(Connection connection) {} - static String toLogSafePhoneNumber(String number) { - // For unknown number, log empty string. - if (number == null) { - return ""; - } - - if (PII_DEBUG) { - // When PII_DEBUG is true we emit PII. - return number; - } - - // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare - // sanitized phone numbers. - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < number.length(); i++) { - char c = number.charAt(i); - if (c == '-' || c == '@' || c == '.') { - builder.append(c); - } else { - builder.append('x'); - } - } - return builder.toString(); - } - private void onAccountsInitialized() { mAreAccountsInitialized = true; for (Runnable r : mPreInitializationConnectionRequests) { @@ -883,346 +827,7 @@ public abstract class ConnectionService extends Service { return mConnectionById.get(callId); } Log.w(this, "%s - Cannot find Connection %s", action, callId); - return getNullConnection(); - } - - private final static synchronized Connection getNullConnection() { - if (sNullConnection == null) { - sNullConnection = new Connection() {}; - } - return sNullConnection; + return Connection.getNullConnection(); } - /** - * Abstraction for a class which provides video call functionality. This class contains no base - * implementation for its methods. It is expected that subclasses will override these - * functions to provide the desired behavior if it is supported. - */ - public static abstract class VideoCallProvider { - private static final int MSG_SET_VIDEO_CALL_LISTENER = 1; - private static final int MSG_SET_CAMERA = 2; - private static final int MSG_SET_PREVIEW_SURFACE = 3; - private static final int MSG_SET_DISPLAY_SURFACE = 4; - private static final int MSG_SET_DEVICE_ORIENTATION = 5; - private static final int MSG_SET_ZOOM = 6; - private static final int MSG_SEND_SESSION_MODIFY_REQUEST = 7; - private static final int MSG_SEND_SESSION_MODIFY_RESPONSE = 8; - private static final int MSG_REQUEST_CAMERA_CAPABILITIES = 9; - private static final int MSG_REQUEST_CALL_DATA_USAGE = 10; - private static final int MSG_SET_PAUSE_IMAGE = 11; - - private final VideoCallProviderHandler mMessageHandler = new VideoCallProviderHandler(); - private final VideoCallProviderBinder mBinder; - private IVideoCallCallback mVideoCallListener; - - /** - * Default handler used to consolidate binder method calls onto a single thread. - */ - private final class VideoCallProviderHandler extends Handler { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_SET_VIDEO_CALL_LISTENER: - mVideoCallListener = IVideoCallCallback.Stub.asInterface((IBinder) msg.obj); - break; - case MSG_SET_CAMERA: - onSetCamera((String) msg.obj); - break; - case MSG_SET_PREVIEW_SURFACE: - onSetPreviewSurface((Surface) msg.obj); - break; - case MSG_SET_DISPLAY_SURFACE: - onSetDisplaySurface((Surface) msg.obj); - break; - case MSG_SET_DEVICE_ORIENTATION: - onSetDeviceOrientation(msg.arg1); - break; - case MSG_SET_ZOOM: - onSetZoom((Float) msg.obj); - break; - case MSG_SEND_SESSION_MODIFY_REQUEST: - onSendSessionModifyRequest((VideoCallProfile) msg.obj); - break; - case MSG_SEND_SESSION_MODIFY_RESPONSE: - onSendSessionModifyResponse((VideoCallProfile) msg.obj); - break; - case MSG_REQUEST_CAMERA_CAPABILITIES: - onRequestCameraCapabilities(); - break; - case MSG_REQUEST_CALL_DATA_USAGE: - onRequestCallDataUsage(); - break; - case MSG_SET_PAUSE_IMAGE: - onSetPauseImage((String) msg.obj); - break; - default: - break; - } - } - } - - /** - * IVideoCallProvider stub implementation. - */ - private final class VideoCallProviderBinder extends IVideoCallProvider.Stub { - public void setVideoCallListener(IBinder videoCallListenerBinder) { - mMessageHandler.obtainMessage( - MSG_SET_VIDEO_CALL_LISTENER, videoCallListenerBinder).sendToTarget(); - } - - public void setCamera(String cameraId) { - mMessageHandler.obtainMessage(MSG_SET_CAMERA, cameraId).sendToTarget(); - } - - public void setPreviewSurface(Surface surface) { - mMessageHandler.obtainMessage(MSG_SET_PREVIEW_SURFACE, surface).sendToTarget(); - } - - public void setDisplaySurface(Surface surface) { - mMessageHandler.obtainMessage(MSG_SET_DISPLAY_SURFACE, surface).sendToTarget(); - } - - public void setDeviceOrientation(int rotation) { - mMessageHandler.obtainMessage(MSG_SET_DEVICE_ORIENTATION, rotation).sendToTarget(); - } - - public void setZoom(float value) { - mMessageHandler.obtainMessage(MSG_SET_ZOOM, value).sendToTarget(); - } - - public void sendSessionModifyRequest(VideoCallProfile requestProfile) { - mMessageHandler.obtainMessage( - MSG_SEND_SESSION_MODIFY_REQUEST, requestProfile).sendToTarget(); - } - - public void sendSessionModifyResponse(VideoCallProfile responseProfile) { - mMessageHandler.obtainMessage( - MSG_SEND_SESSION_MODIFY_RESPONSE, responseProfile).sendToTarget(); - } - - public void requestCameraCapabilities() { - mMessageHandler.obtainMessage(MSG_REQUEST_CAMERA_CAPABILITIES).sendToTarget(); - } - - public void requestCallDataUsage() { - mMessageHandler.obtainMessage(MSG_REQUEST_CALL_DATA_USAGE).sendToTarget(); - } - - public void setPauseImage(String uri) { - mMessageHandler.obtainMessage(MSG_SET_PAUSE_IMAGE, uri).sendToTarget(); - } - } - - public VideoCallProvider() { - mBinder = new VideoCallProviderBinder(); - } - - /** - * Returns binder object which can be used across IPC methods. - * @hide - */ - public final IVideoCallProvider getInterface() { - return mBinder; - } - - /** - * Sets the camera to be used for video recording in a video call. - * - * @param cameraId The id of the camera. - */ - public void onSetCamera(String cameraId) { - // To be implemented by subclass. - } - - /** - * Sets the surface to be used for displaying a preview of what the user's camera is - * currently capturing. When video transmission is enabled, this is the video signal which - * is sent to the remote device. - * - * @param surface The surface. - */ - public void onSetPreviewSurface(Surface surface) { - // To be implemented by subclass. - } - - /** - * Sets the surface to be used for displaying the video received from the remote device. - * - * @param surface The surface. - */ - public void onSetDisplaySurface(Surface surface) { - // To be implemented by subclass. - } - - /** - * Sets the device orientation, in degrees. Assumes that a standard portrait orientation of - * the device is 0 degrees. - * - * @param rotation The device orientation, in degrees. - */ - public void onSetDeviceOrientation(int rotation) { - // To be implemented by subclass. - } - - /** - * Sets camera zoom ratio. - * - * @param value The camera zoom ratio. - */ - public void onSetZoom(float value) { - // To be implemented by subclass. - } - - /** - * Issues a request to modify the properties of the current session. The request is sent to - * the remote device where it it handled by - * {@link InCallService.VideoCall.Listener#onSessionModifyRequestReceived}. - * Some examples of session modification requests: upgrade call from audio to video, downgrade - * call from video to audio, pause video. - * - * @param requestProfile The requested call video properties. - */ - public void onSendSessionModifyRequest(VideoCallProfile requestProfile) { - // To be implemented by subclass. - } - - /** - * Provides a response to a request to change the current call session video - * properties. - * This is in response to a request the InCall UI has received via - * {@link InCallService.VideoCall.Listener#onSessionModifyRequestReceived}. - * The response is handled on the remove device by - * {@link InCallService.VideoCall.Listener#onSessionModifyResponseReceived}. - * - * @param responseProfile The response call video properties. - */ - public void onSendSessionModifyResponse(VideoCallProfile responseProfile) { - // To be implemented by subclass. - } - - /** - * Issues a request to the video provider to retrieve the camera capabilities. - * Camera capabilities are reported back to the caller via - * {@link InCallService.VideoCall.Listener#onCameraCapabilitiesChanged(CallCameraCapabilities)}. - */ - public void onRequestCameraCapabilities() { - // To be implemented by subclass. - } - - /** - * Issues a request to the video telephony framework to retrieve the cumulative data usage for - * the current call. Data usage is reported back to the caller via - * {@link InCallService.VideoCall.Listener#onCallDataUsageChanged}. - */ - public void onRequestCallDataUsage() { - // To be implemented by subclass. - } - - /** - * Provides the video telephony framework with the URI of an image to be displayed to remote - * devices when the video signal is paused. - * - * @param uri URI of image to display. - */ - public void onSetPauseImage(String uri) { - // To be implemented by subclass. - } - - /** - * Invokes callback method defined in {@link InCallService.VideoCall.Listener}. - * - * @param videoCallProfile The requested video call profile. - */ - public void receiveSessionModifyRequest(VideoCallProfile videoCallProfile) { - if (mVideoCallListener != null) { - try { - mVideoCallListener.receiveSessionModifyRequest(videoCallProfile); - } catch (RemoteException ignored) { - } - } - } - - /** - * Invokes callback method defined in {@link InCallService.VideoCall.Listener}. - * - * @param status Status of the session modify request. Valid values are - * {@link InCallService.VideoCall#SESSION_MODIFY_REQUEST_SUCCESS}, - * {@link InCallService.VideoCall#SESSION_MODIFY_REQUEST_FAIL}, - * {@link InCallService.VideoCall#SESSION_MODIFY_REQUEST_INVALID} - * @param requestedProfile The original request which was sent to the remote device. - * @param responseProfile The actual profile changes made by the remote device. - */ - public void receiveSessionModifyResponse( - int status, VideoCallProfile requestedProfile, VideoCallProfile responseProfile) { - if (mVideoCallListener != null) { - try { - mVideoCallListener.receiveSessionModifyResponse( - status, requestedProfile, responseProfile); - } catch (RemoteException ignored) { - } - } - } - - /** - * Invokes callback method defined in {@link InCallService.VideoCall.Listener}. - * - * Valid values are: {@link InCallService.VideoCall#SESSION_EVENT_RX_PAUSE}, - * {@link InCallService.VideoCall#SESSION_EVENT_RX_RESUME}, - * {@link InCallService.VideoCall#SESSION_EVENT_TX_START}, - * {@link InCallService.VideoCall#SESSION_EVENT_TX_STOP} - * - * @param event The event. - */ - public void handleCallSessionEvent(int event) { - if (mVideoCallListener != null) { - try { - mVideoCallListener.handleCallSessionEvent(event); - } catch (RemoteException ignored) { - } - } - } - - /** - * Invokes callback method defined in {@link InCallService.VideoCall.Listener}. - * - * @param width The updated peer video width. - * @param height The updated peer video height. - */ - public void changePeerDimensions(int width, int height) { - if (mVideoCallListener != null) { - try { - mVideoCallListener.changePeerDimensions(width, height); - } catch (RemoteException ignored) { - } - } - } - - /** - * Invokes callback method defined in {@link InCallService.VideoCall.Listener}. - * - * @param dataUsage The updated data usage. - */ - public void changeCallDataUsage(int dataUsage) { - if (mVideoCallListener != null) { - try { - mVideoCallListener.changeCallDataUsage(dataUsage); - } catch (RemoteException ignored) { - } - } - } - - /** - * Invokes callback method defined in {@link InCallService.VideoCall.Listener}. - * - * @param callCameraCapabilities The changed camera capabilities. - */ - public void changeCameraCapabilities(CallCameraCapabilities callCameraCapabilities) { - if (mVideoCallListener != null) { - try { - mVideoCallListener.changeCameraCapabilities(callCameraCapabilities); - } catch (RemoteException ignored) { - } - } - } - } } diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java index 9fd3a971175d..bfcb5c3218be 100644 --- a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java +++ b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java @@ -17,18 +17,13 @@ package android.telecomm; import android.app.PendingIntent; -import android.content.ComponentName; import android.net.Uri; -import android.os.IBinder; import android.os.IBinder.DeathRecipient; import android.os.RemoteException; -import com.android.internal.telecomm.IConnectionService; import com.android.internal.telecomm.IConnectionServiceAdapter; -import com.android.internal.telecomm.IVideoCallProvider; import com.android.internal.telecomm.RemoteServiceCallback; -import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -77,28 +72,36 @@ final class ConnectionServiceAdapter implements DeathRecipient { } void handleCreateConnectionSuccessful( - ConnectionRequest request, ParcelableConnection connection) { + String id, + ConnectionRequest request, + ParcelableConnection connection) { for (IConnectionServiceAdapter adapter : mAdapters) { try { - adapter.handleCreateConnectionSuccessful(request, connection); + adapter.handleCreateConnectionSuccessful(id, request, connection); } catch (RemoteException e) { } } } - void handleCreateConnectionFailed(ConnectionRequest request, int errorCode, String errorMsg) { + void handleCreateConnectionFailed( + String id, + ConnectionRequest request, + int errorCode, + String errorMsg) { for (IConnectionServiceAdapter adapter : mAdapters) { try { - adapter.handleCreateConnectionFailed(request, errorCode, errorMsg); + adapter.handleCreateConnectionFailed(id, request, errorCode, errorMsg); } catch (RemoteException e) { } } } - void handleCreateConnectionCancelled(ConnectionRequest request) { + void handleCreateConnectionCancelled( + String id, + ConnectionRequest request) { for (IConnectionServiceAdapter adapter : mAdapters) { try { - adapter.handleCreateConnectionCancelled(request); + adapter.handleCreateConnectionCancelled(id, request); } catch (RemoteException e) { } } @@ -275,15 +278,15 @@ final class ConnectionServiceAdapter implements DeathRecipient { * Sets the call video provider for a call. * * @param callId The unique ID of the call to set with the given call video provider. - * @param videoCallProvider The call video provider instance to set on the call. + * @param videoProvider The call video provider instance to set on the call. */ - void setVideoCallProvider( - String callId, ConnectionService.VideoCallProvider videoCallProvider) { + void setVideoProvider( + String callId, Connection.VideoProvider videoProvider) { for (IConnectionServiceAdapter adapter : mAdapters) { try { - adapter.setVideoCallProvider( + adapter.setVideoProvider( callId, - videoCallProvider == null ? null : videoCallProvider.getInterface()); + videoProvider == null ? null : videoProvider.getInterface()); } catch (RemoteException e) { } } @@ -334,10 +337,10 @@ final class ConnectionServiceAdapter implements DeathRecipient { /** * Sets the video state associated with a call. * - * Valid values: {@link android.telecomm.VideoCallProfile#VIDEO_STATE_AUDIO_ONLY}, - * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_BIDIRECTIONAL}, - * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_TX_ENABLED}, - * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_RX_ENABLED}. + * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY}, + * {@link VideoProfile.VideoState#BIDIRECTIONAL}, + * {@link VideoProfile.VideoState#TX_ENABLED}, + * {@link VideoProfile.VideoState#RX_ENABLED}. * * @param callId The unique ID of the call to set the video state for. * @param videoState The video state. diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java index 1685bd7b9903..263292411276 100644 --- a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java +++ b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java @@ -24,7 +24,7 @@ import android.os.RemoteException; import com.android.internal.os.SomeArgs; import com.android.internal.telecomm.IConnectionServiceAdapter; -import com.android.internal.telecomm.IVideoCallProvider; +import com.android.internal.telecomm.IVideoProvider; import com.android.internal.telecomm.RemoteServiceCallback; import java.util.List; @@ -80,8 +80,9 @@ final class ConnectionServiceAdapterServant { SomeArgs args = (SomeArgs) msg.obj; try { mDelegate.handleCreateConnectionSuccessful( - (ConnectionRequest) args.arg1, - (ParcelableConnection) args.arg2); + (String) args.arg1, + (ConnectionRequest) args.arg2, + (ParcelableConnection) args.arg3); } finally { args.recycle(); } @@ -91,16 +92,24 @@ final class ConnectionServiceAdapterServant { SomeArgs args = (SomeArgs) msg.obj; try { mDelegate.handleCreateConnectionFailed( - (ConnectionRequest) args.arg1, + (String) args.arg1, + (ConnectionRequest) args.arg2, args.argi1, - (String) args.arg2); + (String) args.arg3); } finally { args.recycle(); } break; } case MSG_HANDLE_CREATE_CONNECTION_CANCELLED: { - mDelegate.handleCreateConnectionCancelled((ConnectionRequest) msg.obj); + SomeArgs args = (SomeArgs) msg.obj; + try { + mDelegate.handleCreateConnectionCancelled( + (String) args.arg1, + (ConnectionRequest) args.arg2); + } finally { + args.recycle(); + } break; } case MSG_SET_ACTIVE: @@ -164,8 +173,8 @@ final class ConnectionServiceAdapterServant { case MSG_SET_VIDEO_CALL_PROVIDER: { SomeArgs args = (SomeArgs) msg.obj; try { - mDelegate.setVideoCallProvider((String) args.arg1, - (IVideoCallProvider) args.arg2); + mDelegate.setVideoProvider((String) args.arg1, + (IVideoProvider) args.arg2); } finally { args.recycle(); } @@ -229,26 +238,38 @@ final class ConnectionServiceAdapterServant { private final IConnectionServiceAdapter mStub = new IConnectionServiceAdapter.Stub() { @Override public void handleCreateConnectionSuccessful( - ConnectionRequest request, ParcelableConnection connection) { + String id, + ConnectionRequest request, + ParcelableConnection connection) { SomeArgs args = SomeArgs.obtain(); - args.arg1 = request; - args.arg2 = connection; + args.arg1 = id; + args.arg2 = request; + args.arg3 = connection; mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL, args).sendToTarget(); } @Override public void handleCreateConnectionFailed( - ConnectionRequest request, int errorCode, String errorMessage) { + String id, + ConnectionRequest request, + int errorCode, + String errorMessage) { SomeArgs args = SomeArgs.obtain(); - args.arg1 = request; + args.arg1 = id; + args.arg2 = request; args.argi1 = errorCode; - args.arg2 = errorMessage; + args.arg3 = errorMessage; mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_FAILED, args).sendToTarget(); } @Override - public void handleCreateConnectionCancelled(ConnectionRequest request) { - mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_CANCELLED, request).sendToTarget(); + public void handleCreateConnectionCancelled( + String id, + ConnectionRequest request) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = id; + args.arg2 = request; + mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_CANCELLED, args).sendToTarget(); } @Override @@ -330,11 +351,10 @@ final class ConnectionServiceAdapterServant { } @Override - public void setVideoCallProvider( - String connectionId, IVideoCallProvider videoCallProvider) { + public void setVideoProvider(String connectionId, IVideoProvider videoProvider) { SomeArgs args = SomeArgs.obtain(); args.arg1 = connectionId; - args.arg2 = videoCallProvider; + args.arg2 = videoProvider; mHandler.obtainMessage(MSG_SET_VIDEO_CALL_PROVIDER, args).sendToTarget(); } diff --git a/telecomm/java/android/telecomm/GatewayInfo.aidl b/telecomm/java/android/telecomm/GatewayInfo.aidl index d59e9b4376ec..bd810149bdab 100644 --- a/telecomm/java/android/telecomm/GatewayInfo.aidl +++ b/telecomm/java/android/telecomm/GatewayInfo.aidl @@ -16,4 +16,7 @@ package android.telecomm; +/** + * {@hide} + */ parcelable GatewayInfo; diff --git a/telecomm/java/android/telecomm/InCallAdapter.java b/telecomm/java/android/telecomm/InCallAdapter.java index 08eb03adae9c..80f7b5784a2d 100644 --- a/telecomm/java/android/telecomm/InCallAdapter.java +++ b/telecomm/java/android/telecomm/InCallAdapter.java @@ -28,6 +28,10 @@ import com.android.internal.telecomm.IInCallAdapter; * given call IDs to execute commands such as {@link #answerCall} for incoming calls or * {@link #disconnectCall} for active calls the user would like to end. Some commands are only * appropriate for calls in certain states; please consult each method for such limitations. + * <p> + * The adapter will stop functioning when there are no more calls. + * + * {@hide} */ public final class InCallAdapter { private final IInCallAdapter mAdapter; @@ -115,7 +119,7 @@ public final class InCallAdapter { } /** - * Sets the audio route (speaker, bluetooth, etc...). See {@link CallAudioState}. + * Sets the audio route (speaker, bluetooth, etc...). See {@link AudioState}. * * @param route The audio route to use. */ @@ -237,19 +241,6 @@ public final class InCallAdapter { } /** - * Swap this call with a background call. This is used for calls that don't support hold, - * e.g. CDMA. - * - * @param callId The unique ID of the call. - */ - public void swapWithBackgroundCall(String callId) { - try { - mAdapter.swapWithBackgroundCall(callId); - } catch (RemoteException ignored) { - } - } - - /** * Instructs Telecomm to turn the proximity sensor on. */ public void turnProximitySensorOn() { diff --git a/telecomm/java/android/telecomm/InCallService.java b/telecomm/java/android/telecomm/InCallService.java index b2758094ffd3..de05d1c4db9c 100644 --- a/telecomm/java/android/telecomm/InCallService.java +++ b/telecomm/java/android/telecomm/InCallService.java @@ -35,7 +35,8 @@ import java.lang.String; * This service is implemented by any app that wishes to provide the user-interface for managing * phone calls. Telecomm binds to this service while there exists a live (active or incoming) call, * and uses it to notify the in-call app of any live and and recently disconnected calls. - * TODO: What happens if two or more apps on a given device implement this interface? + * + * {@hide} */ public abstract class InCallService extends Service { private static final int MSG_SET_IN_CALL_ADAPTER = 1; @@ -73,7 +74,7 @@ public abstract class InCallService extends Service { break; } case MSG_ON_AUDIO_STATE_CHANGED: - mPhone.internalAudioStateChanged((CallAudioState) msg.obj); + mPhone.internalAudioStateChanged((AudioState) msg.obj); break; case MSG_BRING_TO_FOREGROUND: mPhone.internalBringToForeground(msg.arg1 == 1); @@ -124,7 +125,7 @@ public abstract class InCallService extends Service { } @Override - public void onAudioStateChanged(CallAudioState audioState) { + public void onAudioStateChanged(AudioState audioState) { mHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, audioState).sendToTarget(); } @@ -191,56 +192,6 @@ public abstract class InCallService extends Service { public static abstract class VideoCall { /** - * Video is not being received (no protocol pause was issued). - */ - public static final int SESSION_EVENT_RX_PAUSE = 1; - - /** - * Video reception has resumed after a SESSION_EVENT_RX_PAUSE. - */ - public static final int SESSION_EVENT_RX_RESUME = 2; - - /** - * Video transmission has begun. This occurs after a negotiated start of video transmission - * when the underlying protocol has actually begun transmitting video to the remote party. - */ - public static final int SESSION_EVENT_TX_START = 3; - - /** - * Video transmission has stopped. This occurs after a negotiated stop of video transmission - * when the underlying protocol has actually stopped transmitting video to the remote party. - */ - public static final int SESSION_EVENT_TX_STOP = 4; - - /** - * A camera failure has occurred for the selected camera. The In-Call UI can use this as a - * cue to inform the user the camera is not available. - */ - public static final int SESSION_EVENT_CAMERA_FAILURE = 5; - - /** - * Issued after {@code SESSION_EVENT_CAMERA_FAILURE} when the camera is once again ready for - * operation. The In-Call UI can use this as a cue to inform the user that the camera has - * become available again. - */ - public static final int SESSION_EVENT_CAMERA_READY = 6; - - /** - * Session modify request was successful. - */ - public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1; - - /** - * Session modify request failed. - */ - public static final int SESSION_MODIFY_REQUEST_FAIL = 2; - - /** - * Session modify request ignored due to invalid parameters. - */ - public static final int SESSION_MODIFY_REQUEST_INVALID = 3; - - /** * Sets a listener to invoke callback methods in the InCallUI after performing video * telephony actions. * @@ -295,7 +246,7 @@ public abstract class InCallService extends Service { * * @param requestProfile The requested call video properties. */ - public abstract void sendSessionModifyRequest(VideoCallProfile requestProfile); + public abstract void sendSessionModifyRequest(VideoProfile requestProfile); /** * Provides a response to a request to change the current call session video @@ -307,12 +258,12 @@ public abstract class InCallService extends Service { * * @param responseProfile The response call video properties. */ - public abstract void sendSessionModifyResponse(VideoCallProfile responseProfile); + public abstract void sendSessionModifyResponse(VideoProfile responseProfile); /** * Issues a request to the video provider to retrieve the camera capabilities. * Camera capabilities are reported back to the caller via - * {@link VideoCall.Listener#onCameraCapabilitiesChanged(CallCameraCapabilities)}. + * {@link VideoCall.Listener#onCameraCapabilitiesChanged(CameraCapabilities)}. */ public abstract void requestCameraCapabilities(); @@ -338,43 +289,44 @@ public abstract class InCallService extends Service { /** * Called when a session modification request is received from the remote device. * The remote request is sent via - * {@link ConnectionService.VideoCallProvider#onSendSessionModifyRequest}. The InCall UI + * {@link Connection.VideoProvider#onSendSessionModifyRequest}. The InCall UI * is responsible for potentially prompting the user whether they wish to accept the new * call profile (e.g. prompt user if they wish to accept an upgrade from an audio to a * video call) and should call - * {@link ConnectionService.VideoCallProvider#onSendSessionModifyResponse} to indicate + * {@link Connection.VideoProvider#onSendSessionModifyResponse} to indicate * the video settings the user has agreed to. * - * @param videoCallProfile The requested video call profile. + * @param videoProfile The requested video call profile. */ - public abstract void onSessionModifyRequestReceived(VideoCallProfile videoCallProfile); + public abstract void onSessionModifyRequestReceived(VideoProfile videoProfile); /** * Called when a response to a session modification request is received from the remote * device. The remote InCall UI sends the response using - * {@link ConnectionService.VideoCallProvider#onSendSessionModifyResponse}. + * {@link Connection.VideoProvider#onSendSessionModifyResponse}. * * @param status Status of the session modify request. Valid values are - * {@link VideoCall#SESSION_MODIFY_REQUEST_SUCCESS}, - * {@link VideoCall#SESSION_MODIFY_REQUEST_FAIL}, - * {@link VideoCall#SESSION_MODIFY_REQUEST_INVALID} + * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS}, + * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_FAIL}, + * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_INVALID} * @param requestedProfile The original request which was sent to the remote device. * @param responseProfile The actual profile changes made by the remote device. */ public abstract void onSessionModifyResponseReceived(int status, - VideoCallProfile requestedProfile, VideoCallProfile responseProfile); + VideoProfile requestedProfile, VideoProfile responseProfile); /** * Handles events related to the current session which the client may wish to handle. * These are separate from requested changes to the session due to the underlying * protocol or connection. * - * Valid values are: {@link VideoCall#SESSION_EVENT_RX_PAUSE}, - * {@link VideoCall#SESSION_EVENT_RX_RESUME}, - * {@link VideoCall#SESSION_EVENT_TX_START}, - * {@link VideoCall#SESSION_EVENT_TX_STOP}, - * {@link VideoCall#SESSION_EVENT_CAMERA_FAILURE}, - * {@link VideoCall#SESSION_EVENT_CAMERA_READY} + * Valid values are: + * {@link Connection.VideoProvider#SESSION_EVENT_RX_PAUSE}, + * {@link Connection.VideoProvider#SESSION_EVENT_RX_RESUME}, + * {@link Connection.VideoProvider#SESSION_EVENT_TX_START}, + * {@link Connection.VideoProvider#SESSION_EVENT_TX_STOP}, + * {@link Connection.VideoProvider#SESSION_EVENT_CAMERA_FAILURE}, + * {@link Connection.VideoProvider#SESSION_EVENT_CAMERA_READY} * * @param event The event. */ @@ -399,10 +351,10 @@ public abstract class InCallService extends Service { /** * Handles a change in camera capabilities. * - * @param callCameraCapabilities The changed camera capabilities. + * @param cameraCapabilities The changed camera capabilities. */ public abstract void onCameraCapabilitiesChanged( - CallCameraCapabilities callCameraCapabilities); + CameraCapabilities cameraCapabilities); } } } diff --git a/telecomm/java/android/telecomm/ParcelableCall.aidl b/telecomm/java/android/telecomm/ParcelableCall.aidl index 8c966382d481..18691d267562 100644 --- a/telecomm/java/android/telecomm/ParcelableCall.aidl +++ b/telecomm/java/android/telecomm/ParcelableCall.aidl @@ -16,4 +16,7 @@ package android.telecomm; +/** + * {@hide} + */ parcelable ParcelableCall; diff --git a/telecomm/java/android/telecomm/ParcelableCall.java b/telecomm/java/android/telecomm/ParcelableCall.java index 360e7689965e..8098b94c923c 100644 --- a/telecomm/java/android/telecomm/ParcelableCall.java +++ b/telecomm/java/android/telecomm/ParcelableCall.java @@ -17,24 +17,25 @@ package android.telecomm; import android.net.Uri; +import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.telephony.DisconnectCause; -import com.android.internal.telecomm.IVideoCallProvider; - import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.android.internal.telecomm.IVideoProvider; + /** * Information about a call that is used between InCallService and Telecomm. * @hide */ public final class ParcelableCall implements Parcelable { private final String mId; - private final CallState mState; + private final int mState; private final int mDisconnectCauseCode; private final String mDisconnectCauseMsg; private final List<String> mCannedSmsResponses; @@ -46,17 +47,18 @@ public final class ParcelableCall implements Parcelable { private final int mCallerDisplayNamePresentation; private final GatewayInfo mGatewayInfo; private final PhoneAccountHandle mAccountHandle; - private final IVideoCallProvider mVideoCallProvider; + private final IVideoProvider mVideoCallProvider; private InCallService.VideoCall mVideoCall; private final String mParentCallId; private final List<String> mChildCallIds; private final StatusHints mStatusHints; private final int mVideoState; private final List<String> mConferenceableCallIds; + private final Bundle mExtras; public ParcelableCall( String id, - CallState state, + int state, int disconnectCauseCode, String disconnectCauseMsg, List<String> cannedSmsResponses, @@ -68,12 +70,13 @@ public final class ParcelableCall implements Parcelable { int callerDisplayNamePresentation, GatewayInfo gatewayInfo, PhoneAccountHandle accountHandle, - IVideoCallProvider videoCallProvider, + IVideoProvider videoCallProvider, String parentCallId, List<String> childCallIds, StatusHints statusHints, int videoState, - List<String> conferenceableCallIds) { + List<String> conferenceableCallIds, + Bundle extras) { mId = id; mState = state; mDisconnectCauseCode = disconnectCauseCode; @@ -93,6 +96,7 @@ public final class ParcelableCall implements Parcelable { mStatusHints = statusHints; mVideoState = videoState; mConferenceableCallIds = Collections.unmodifiableList(conferenceableCallIds); + mExtras = extras; } /** The unique ID of the call. */ @@ -101,7 +105,7 @@ public final class ParcelableCall implements Parcelable { } /** The current state of the call. */ - public CallState getState() { + public int getState() { return mState; } @@ -143,7 +147,7 @@ public final class ParcelableCall implements Parcelable { return mHandle; } - /** The {@link CallPropertyPresentation} which controls how the handle is shown. */ + /** The {@link PropertyPresentation} which controls how the handle is shown. */ public int getHandlePresentation() { return mHandlePresentation; } @@ -153,7 +157,7 @@ public final class ParcelableCall implements Parcelable { return mCallerDisplayName; } - /** The {@link CallPropertyPresentation} which controls how the caller display name is shown. */ + /** The {@link PropertyPresentation} which controls how the caller display name is shown. */ public int getCallerDisplayNamePresentation() { return mCallerDisplayNamePresentation; } @@ -220,6 +224,15 @@ public final class ParcelableCall implements Parcelable { return mVideoState; } + /** + * Any extras to pass with the call + * + * @return a bundle of extras + */ + public Bundle getExtras() { + return mExtras; + } + /** Responsible for creating ParcelableCall objects for deserialized Parcels. */ public static final Parcelable.Creator<ParcelableCall> CREATOR = new Parcelable.Creator<ParcelableCall> () { @@ -227,7 +240,7 @@ public final class ParcelableCall implements Parcelable { public ParcelableCall createFromParcel(Parcel source) { ClassLoader classLoader = ParcelableCall.class.getClassLoader(); String id = source.readString(); - CallState state = CallState.valueOf(source.readString()); + int state = source.readInt(); int disconnectCauseCode = source.readInt(); String disconnectCauseMsg = source.readString(); List<String> cannedSmsResponses = new ArrayList<>(); @@ -240,8 +253,8 @@ public final class ParcelableCall implements Parcelable { int callerDisplayNamePresentation = source.readInt(); GatewayInfo gatewayInfo = source.readParcelable(classLoader); PhoneAccountHandle accountHandle = source.readParcelable(classLoader); - IVideoCallProvider videoCallProvider = - IVideoCallProvider.Stub.asInterface(source.readStrongBinder()); + IVideoProvider videoCallProvider = + IVideoProvider.Stub.asInterface(source.readStrongBinder()); String parentCallId = source.readString(); List<String> childCallIds = new ArrayList<>(); source.readList(childCallIds, classLoader); @@ -249,11 +262,12 @@ public final class ParcelableCall implements Parcelable { int videoState = source.readInt(); List<String> conferenceableCallIds = new ArrayList<>(); source.readList(conferenceableCallIds, classLoader); + Bundle extras = source.readParcelable(classLoader); return new ParcelableCall(id, state, disconnectCauseCode, disconnectCauseMsg, cannedSmsResponses, capabilities, connectTimeMillis, handle, handlePresentation, callerDisplayName, callerDisplayNamePresentation, gatewayInfo, accountHandle, videoCallProvider, parentCallId, childCallIds, statusHints, - videoState, conferenceableCallIds); + videoState, conferenceableCallIds, extras); } @Override @@ -272,7 +286,7 @@ public final class ParcelableCall implements Parcelable { @Override public void writeToParcel(Parcel destination, int flags) { destination.writeString(mId); - destination.writeString(mState.name()); + destination.writeInt(mState); destination.writeInt(mDisconnectCauseCode); destination.writeString(mDisconnectCauseMsg); destination.writeList(mCannedSmsResponses); @@ -291,6 +305,7 @@ public final class ParcelableCall implements Parcelable { destination.writeParcelable(mStatusHints, 0); destination.writeInt(mVideoState); destination.writeList(mConferenceableCallIds); + destination.writeParcelable(mExtras, 0); } @Override diff --git a/telecomm/java/android/telecomm/ParcelableConnection.aidl b/telecomm/java/android/telecomm/ParcelableConnection.aidl index e3c3bd247d17..143c5a6133d8 100644 --- a/telecomm/java/android/telecomm/ParcelableConnection.aidl +++ b/telecomm/java/android/telecomm/ParcelableConnection.aidl @@ -16,4 +16,7 @@ package android.telecomm; +/** + * {@hide} + */ parcelable ParcelableConnection; diff --git a/telecomm/java/android/telecomm/ParcelableConnection.java b/telecomm/java/android/telecomm/ParcelableConnection.java index 2f790044d53d..78dd64a2c529 100644 --- a/telecomm/java/android/telecomm/ParcelableConnection.java +++ b/telecomm/java/android/telecomm/ParcelableConnection.java @@ -20,7 +20,7 @@ import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; -import com.android.internal.telecomm.IVideoCallProvider; +import com.android.internal.telecomm.IVideoProvider; /** * Information about a connection that is used between Telecomm and the ConnectionService. @@ -36,7 +36,7 @@ public final class ParcelableConnection implements Parcelable { private int mHandlePresentation; private String mCallerDisplayName; private int mCallerDisplayNamePresentation; - private IVideoCallProvider mVideoCallProvider; + private IVideoProvider mVideoProvider; private int mVideoState; /** @hide */ @@ -48,7 +48,7 @@ public final class ParcelableConnection implements Parcelable { int handlePresentation, String callerDisplayName, int callerDisplayNamePresentation, - IVideoCallProvider videoCallProvider, + IVideoProvider videoProvider, int videoState) { mPhoneAccount = phoneAccount; mState = state; @@ -57,7 +57,7 @@ public final class ParcelableConnection implements Parcelable { mHandlePresentation = handlePresentation; mCallerDisplayName = callerDisplayName; mCallerDisplayNamePresentation = callerDisplayNamePresentation; - mVideoCallProvider = videoCallProvider; + mVideoProvider = videoProvider; mVideoState = videoState; } @@ -90,8 +90,8 @@ public final class ParcelableConnection implements Parcelable { return mCallerDisplayNamePresentation; } - public IVideoCallProvider getVideoCallProvider() { - return mVideoCallProvider; + public IVideoProvider getVideoProvider() { + return mVideoProvider; } public int getVideoState() { @@ -106,7 +106,7 @@ public final class ParcelableConnection implements Parcelable { .append(", state:") .append(mState) .append(", capabilities:") - .append(CallCapabilities.toString(mCapabilities)) + .append(PhoneCapabilities.toString(mCapabilities)) .toString(); } @@ -123,8 +123,8 @@ public final class ParcelableConnection implements Parcelable { int handlePresentation = source.readInt(); String callerDisplayName = source.readString(); int callerDisplayNamePresentation = source.readInt(); - IVideoCallProvider videoCallProvider = - IVideoCallProvider.Stub.asInterface(source.readStrongBinder()); + IVideoProvider videoCallProvider = + IVideoProvider.Stub.asInterface(source.readStrongBinder()); int videoState = source.readInt(); return new ParcelableConnection( @@ -162,7 +162,7 @@ public final class ParcelableConnection implements Parcelable { destination.writeString(mCallerDisplayName); destination.writeInt(mCallerDisplayNamePresentation); destination.writeStrongBinder( - mVideoCallProvider != null ? mVideoCallProvider.asBinder() : null); + mVideoProvider != null ? mVideoProvider.asBinder() : null); destination.writeInt(mVideoState); } } diff --git a/telecomm/java/android/telecomm/Phone.java b/telecomm/java/android/telecomm/Phone.java index 4ad572d9ef52..79e777a4eb4e 100644 --- a/telecomm/java/android/telecomm/Phone.java +++ b/telecomm/java/android/telecomm/Phone.java @@ -27,6 +27,8 @@ import java.util.Objects; /** * A unified virtual device providing a means of voice (and other) communication on a device. + * + * {@hide} */ public final class Phone { @@ -35,9 +37,9 @@ public final class Phone { * Called when the audio state changes. * * @param phone The {@code Phone} calling this method. - * @param audioState The new {@link CallAudioState}. + * @param audioState The new {@link AudioState}. */ - public void onAudioStateChanged(Phone phone, CallAudioState audioState) { } + public void onAudioStateChanged(Phone phone, AudioState audioState) { } /** * Called to bring the in-call screen to the foreground. The in-call experience should @@ -85,7 +87,7 @@ public final class Phone { private final InCallAdapter mInCallAdapter; - private CallAudioState mAudioState; + private AudioState mAudioState; private final List<Listener> mListeners = new ArrayList<>(); @@ -129,10 +131,10 @@ public final class Phone { } /** {@hide} */ - final void internalAudioStateChanged(CallAudioState callAudioState) { - if (!Objects.equals(mAudioState, callAudioState)) { - mAudioState = callAudioState; - fireAudioStateChanged(callAudioState); + final void internalAudioStateChanged(AudioState audioState) { + if (!Objects.equals(mAudioState, audioState)) { + mAudioState = audioState; + fireAudioStateChanged(audioState); } } @@ -229,7 +231,7 @@ public final class Phone { * * @return An object encapsulating the audio state. */ - public final CallAudioState getAudioState() { + public final AudioState getAudioState() { return mAudioState; } @@ -247,7 +249,7 @@ public final class Phone { } } - private void fireAudioStateChanged(CallAudioState audioState) { + private void fireAudioStateChanged(AudioState audioState) { Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]); for (int i = 0; i < listeners.length; i++) { listeners[i].onAudioStateChanged(this, audioState); diff --git a/telecomm/java/android/telecomm/PhoneAccount.java b/telecomm/java/android/telecomm/PhoneAccount.java index 0fea7ba17083..411f48c20520 100644 --- a/telecomm/java/android/telecomm/PhoneAccount.java +++ b/telecomm/java/android/telecomm/PhoneAccount.java @@ -27,7 +27,8 @@ import android.os.Parcelable; import java.util.MissingResourceException; /** - * Provides user interface description information for a {@code PhoneAccount}. + * Describes a distinct account, line of service or call placement method that the system + * can use to place phone calls. */ public class PhoneAccount implements Parcelable { @@ -37,9 +38,9 @@ public class PhoneAccount implements Parcelable { * will be allowed to manage phone calls including using its own proprietary phone-call * implementation (like VoIP calling) to make calls instead of the telephony stack. * <p> - * When a user opts to place a call using the SIM-based telephony stack, the connection-service - * associated with this phone-account will be attempted first if the user has explicitly - * selected it to be used as the default connection manager. + * When a user opts to place a call using the SIM-based telephony stack, the + * {@link ConnectionService} associated with this {@code PhoneAccount} will be attempted first + * if the user has explicitly selected it to be used as the default connection manager. * <p> * See {@link #getCapabilities} */ @@ -53,21 +54,25 @@ public class PhoneAccount implements Parcelable { * calls from or use the built-in telephony stack to place its calls. * <p> * See {@link #getCapabilities} - * + * <p> * {@hide} */ public static final int CAPABILITY_CALL_PROVIDER = 0x2; /** - * Flag indicating that this {@code PhoneAccount} represents built-in PSTN SIM + * Flag indicating that this {@code PhoneAccount} represents a built-in PSTN SIM * subscription. * <p> - * Only the android framework can set this capability on a phone account. + * Only the Android framework can register a {@code PhoneAccount} having this capability. + * <p> + * See {@link #getCapabilities} */ public static final int CAPABILITY_SIM_SUBSCRIPTION = 0x4; /** - * Flag indicating that this {@code PhoneAccount} is capable of video calling. + * Flag indicating that this {@code PhoneAccount} is capable of placing video calls. + * <p> + * See {@link #getCapabilities} */ public static final int CAPABILITY_VIDEO_CALLING = 0x8; @@ -79,7 +84,65 @@ public class PhoneAccount implements Parcelable { private final CharSequence mLabel; private final CharSequence mShortDescription; - public PhoneAccount( + public static class Builder { + private PhoneAccountHandle mAccountHandle; + private Uri mHandle; + private String mSubscriptionNumber; + private int mCapabilities; + private int mIconResId; + private CharSequence mLabel; + private CharSequence mShortDescription; + + private Builder() {} + + public Builder withAccountHandle(PhoneAccountHandle value) { + this.mAccountHandle = value; + return this; + } + + public Builder withHandle(Uri value) { + this.mHandle = value; + return this; + } + + public Builder withSubscriptionNumber(String value) { + this.mSubscriptionNumber = value; + return this; + } + + public Builder withCapabilities(int value) { + this.mCapabilities = value; + return this; + } + + public Builder withIconResId(int value) { + this.mIconResId = value; + return this; + } + + public Builder withLabel(CharSequence value) { + this.mLabel = value; + return this; + } + + public Builder withShortDescription(CharSequence value) { + this.mShortDescription = value; + return this; + } + + public PhoneAccount build() { + return new PhoneAccount( + mAccountHandle, + mHandle, + mSubscriptionNumber, + mCapabilities, + mIconResId, + mLabel, + mShortDescription); + } + } + + private PhoneAccount( PhoneAccountHandle account, Uri handle, String subscriptionNumber, @@ -96,8 +159,10 @@ public class PhoneAccount implements Parcelable { mShortDescription = shortDescription; } + public static Builder builder() { return new Builder(); } + /** - * The {@code PhoneAccountHandle} to which this metadata pertains. + * The unique identifier of this {@code PhoneAccount}. * * @return A {@code PhoneAccountHandle}. */ @@ -118,9 +183,15 @@ public class PhoneAccount implements Parcelable { } /** - * The subscription number associated with the underlying transport. This may differ from the - * {@link #getHandle()} number; for example, if the number used to talk to the network is not - * the same number that will be on the remote party's caller ID display. + * The raw callback number used for this {@code PhoneAccount}, as distinct from + * {@link #getHandle()}. For the majority of {@code PhoneAccount}s this should be registered + * as {@code null}. It is used by the system for SIM-based {@code PhoneAccount} registration + * where {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(String, String)} + * or {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(long, String, String)} + * has been used to alter the callback number. + * <p> + * TODO: Should this also be a URI, for consistency? Should it be called the + * "subscription handle"? * * @return The subscription number, suitable for display to the user. */ @@ -147,7 +218,7 @@ public class PhoneAccount implements Parcelable { } /** - * A short paragraph describing a {@code PhoneAccount}. + * A short paragraph describing this {@code PhoneAccount}. * * @return A description for this {@code PhoneAccount}. */ @@ -183,7 +254,7 @@ public class PhoneAccount implements Parcelable { return null; } try { - return packageContext.getResources().getDrawable(resId); + return packageContext.getDrawable(resId); } catch (NotFoundException|MissingResourceException e) { Log.e(this, e, "Cannot find icon %d in package %s", resId, mAccountHandle.getComponentName().getPackageName()); diff --git a/telecomm/java/android/telecomm/PhoneAccountHandle.java b/telecomm/java/android/telecomm/PhoneAccountHandle.java index f14766cb88d2..04cd2b0f64da 100644 --- a/telecomm/java/android/telecomm/PhoneAccountHandle.java +++ b/telecomm/java/android/telecomm/PhoneAccountHandle.java @@ -23,8 +23,7 @@ import android.os.Parcelable; import java.util.Objects; /** - * Represents a distinct account, line of service or call placement method that - * the system can use to place phone calls. + * The unique identifier for a {@link PhoneAccount}. */ public class PhoneAccountHandle implements Parcelable { private ComponentName mComponentName; @@ -48,10 +47,18 @@ public class PhoneAccountHandle implements Parcelable { } /** - * A unique identifier for this {@code PhoneAccountHandle}, generated by and meaningful to the - * {@link android.telecomm.ConnectionService} that created it. + * A string that uniquely distinguishes this particular {@code PhoneAccountHandle} from all the + * others supported by the {@link ConnectionService} that created it. + * <p> + * A {@code ConnectionService} must select identifiers that are stable for the lifetime of + * their users' relationship with their service, across many Android devices. For example, a + * good set of identifiers might be the email addresses with which with users registered for + * their accounts with a particular service. Depending on how a service chooses to operate, + * a bad set of identifiers might be an increasing series of integers + * ({@code 0}, {@code 1}, {@code 2}, ...) that are generated locally on each phone and could + * collide with values generated on other phones or after a data wipe of a given phone. * - * @return A unique identifier for this {@code PhoneAccountHandle}. + * @return A service-specific unique identifier for this {@code PhoneAccountHandle}. */ public String getId() { return mId; diff --git a/telecomm/java/android/telecomm/CallCapabilities.java b/telecomm/java/android/telecomm/PhoneCapabilities.java index e64fe80afe51..45168d5a714c 100644 --- a/telecomm/java/android/telecomm/CallCapabilities.java +++ b/telecomm/java/android/telecomm/PhoneCapabilities.java @@ -16,8 +16,12 @@ package android.telecomm; -/** Defines actions a call currently supports. */ -public final class CallCapabilities { +/** + * Defines capabilities a phone call can support, such as conference calling and video telephony. + * Also defines properties of a phone call, such as whether it is using VoLTE technology. + + */ +public final class PhoneCapabilities { /** Call can currently be put on hold or unheld. */ public static final int HOLD = 0x00000001; @@ -98,5 +102,5 @@ public final class CallCapabilities { return builder.toString(); } - private CallCapabilities() {} + private PhoneCapabilities() {} } diff --git a/telecomm/java/android/telecomm/CallPropertyPresentation.java b/telecomm/java/android/telecomm/PropertyPresentation.java index 319e56503a87..fe97b3d6be3e 100644 --- a/telecomm/java/android/telecomm/CallPropertyPresentation.java +++ b/telecomm/java/android/telecomm/PropertyPresentation.java @@ -16,8 +16,10 @@ package android.telecomm; -/** Defines how numbers and names are displayed in caller id. */ -public class CallPropertyPresentation { +/** + * Defines how properties such as phone numbers and names are displayed to the user. + */ +public class PropertyPresentation { /** Property is displayed normally. */ public static final int ALLOWED = 1; diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java index a8636d49e290..13b08343aad3 100644 --- a/telecomm/java/android/telecomm/RemoteConnection.java +++ b/telecomm/java/android/telecomm/RemoteConnection.java @@ -16,22 +16,24 @@ package android.telecomm; +import com.android.internal.telecomm.IConnectionService; + import android.app.PendingIntent; import android.net.Uri; import android.os.RemoteException; import android.telephony.DisconnectCause; -import com.android.internal.telecomm.IConnectionService; - import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; /** - * RemoteConnection object used by RemoteConnectionService. + * A connection provided to a {@link ConnectionService} by another {@code ConnectionService} + * running in a different process. + * + * @see ConnectionService#createRemoteOutgoingConnection(PhoneAccountHandle, ConnectionRequest) + * @see ConnectionService#createRemoteIncomingConnection(PhoneAccountHandle, ConnectionRequest) */ public final class RemoteConnection { @@ -100,7 +102,7 @@ public final class RemoteConnection { * Invoked when the post-dial sequence in the outgoing {@code Connection} has reached a * pause character. This causes the post-dial signals to stop pending user confirmation. An * implementation should present this choice to the user and invoke - * {@link #postDialContinue(boolean)} when the user makes the choice. + * {@link RemoteConnection#postDialContinue(boolean)} when the user makes the choice. * * @param connection The {@code RemoteConnection} invoking this method. * @param remainingPostDialSequence The post-dial characters that remain to be sent. @@ -131,7 +133,7 @@ public final class RemoteConnection { * * @param connection The {@code RemoteConnection} invoking this method. * @param handle The new handle of the {@code RemoteConnection}. - * @param presentation The {@link CallPropertyPresentation} which controls how the + * @param presentation The {@link PropertyPresentation} which controls how the * handle is shown. */ public void onHandleChanged(RemoteConnection connection, Uri handle, int presentation) {} @@ -142,7 +144,7 @@ public final class RemoteConnection { * * @param connection The {@code RemoteConnection} invoking this method. * @param callerDisplayName The new caller display name of the {@code RemoteConnection}. - * @param presentation The {@link CallPropertyPresentation} which controls how the + * @param presentation The {@link PropertyPresentation} which controls how the * caller display name is shown. */ public void onCallerDisplayNameChanged( @@ -180,11 +182,10 @@ public final class RemoteConnection { private IConnectionService mConnectionService; private final String mConnectionId; - private final Set<Listener> mListeners = Collections.newSetFromMap( - new ConcurrentHashMap<Listener, Boolean>(2)); + private final Set<Listener> mListeners = new HashSet<>(); private final Set<RemoteConnection> mConferenceableConnections = new HashSet<>(); - private int mState = Connection.State.NEW; + private int mState = Connection.STATE_NEW; private int mDisconnectCauseCode = DisconnectCause.NOT_VALID; private String mDisconnectCauseMessage; private boolean mRequestingRingback; @@ -203,12 +204,14 @@ public final class RemoteConnection { /** * @hide */ - RemoteConnection(IConnectionService connectionService, ConnectionRequest request) { + RemoteConnection( + String id, + IConnectionService connectionService, + ConnectionRequest request) { + mConnectionId = id; mConnectionService = connectionService; - mConnectionId = request == null ? "NULL" : request.getCallId(); - mConnected = true; - mState = Connection.State.INITIALIZING; + mState = Connection.STATE_INITIALIZING; } /** @@ -219,10 +222,10 @@ public final class RemoteConnection { * @param failureCode * @param failureMessage */ - private RemoteConnection(int failureCode, String failureMessage) { - this(null, null); + RemoteConnection(int failureCode, String failureMessage) { + this("NULL", null, null); mConnected = false; - mState = Connection.State.FAILED; + mState = Connection.STATE_FAILED; mFailureCode = failureCode; mFailureMessage = failureMessage; } @@ -271,7 +274,7 @@ public final class RemoteConnection { } /** - * @return For a {@link Connection.State#DISCONNECTED} {@code RemoteConnection}, the + * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, the * disconnect cause expressed as a code chosen from among those declared in * {@link DisconnectCause}. */ @@ -280,7 +283,7 @@ public final class RemoteConnection { } /** - * @return For a {@link Connection.State#DISCONNECTED} {@code RemoteConnection}, an optional + * @return For a {@link Connection#STATE_DISCONNECTED} {@code RemoteConnection}, an optional * reason for disconnection expressed as a free text message. */ public String getDisconnectCauseMessage() { @@ -289,7 +292,7 @@ public final class RemoteConnection { /** * @return A bitmask of the capabilities of the {@code RemoteConnection}, as defined in - * {@link CallCapabilities}. + * {@link PhoneCapabilities}. */ public int getCallCapabilities() { return mCallCapabilities; @@ -303,7 +306,7 @@ public final class RemoteConnection { } /** - * @return The current {@link android.telecomm.StatusHints} of this {@code RemoteConnection}, + * @return The current {@link StatusHints} of this {@code RemoteConnection}, * or {@code null} if none have been set. */ public StatusHints getStatusHints() { @@ -320,7 +323,7 @@ public final class RemoteConnection { /** * @return The presentation requirements for the handle. See - * {@link android.telecomm.CallPropertyPresentation} for valid values. + * {@link PropertyPresentation} for valid values. */ public int getHandlePresentation() { return mHandlePresentation; @@ -335,7 +338,7 @@ public final class RemoteConnection { /** * @return The presentation requirements for the caller display name. See - * {@link android.telecomm.CallPropertyPresentation} for valid values. + * {@link PropertyPresentation} for valid values. */ public int getCallerDisplayNamePresentation() { return mCallerDisplayNamePresentation; @@ -343,7 +346,7 @@ public final class RemoteConnection { /** * @return The video state of the {@code RemoteConnection}. See - * {@link VideoCallProfile.VideoState}. + * {@link VideoProfile.VideoState}. */ public int getVideoState() { return mVideoState; @@ -385,7 +388,7 @@ public final class RemoteConnection { } /** - * Instructs this {@link Connection.State#RINGING} {@code RemoteConnection} to answer. + * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to answer. * @param videoState The video state in which to answer the call. */ public void answer(int videoState) { @@ -398,7 +401,7 @@ public final class RemoteConnection { } /** - * Instructs this {@link Connection.State#RINGING} {@code RemoteConnection} to reject. + * Instructs this {@link Connection#STATE_RINGING} {@code RemoteConnection} to reject. */ public void reject() { try { @@ -422,7 +425,7 @@ public final class RemoteConnection { } /** - * Instructs this {@link Connection.State#HOLDING} call to release from hold. + * Instructs this {@link Connection#STATE_HOLDING} call to release from hold. */ public void unhold() { try { @@ -510,24 +513,11 @@ public final class RemoteConnection { } /** - * Instructs this {@code RemoteConnection} to swap itself with an existing background call, - * if one such call exists. - */ - public void swapWithBackgroundCall() { - try { - if (mConnected) { - mConnectionService.swapWithBackgroundCall(mConnectionId); - } - } catch (RemoteException ignored) { - } - } - - /** * Set the audio state of this {@code RemoteConnection}. * * @param state The audio state of this {@code RemoteConnection}. */ - public void setAudioState(CallAudioState state) { + public void setAudioState(AudioState state) { try { if (mConnected) { mConnectionService.onAudioStateChanged(mConnectionId, state); @@ -552,8 +542,8 @@ public final class RemoteConnection { * @hide */ void setDisconnected(int cause, String message) { - if (mState != Connection.State.DISCONNECTED) { - mState = Connection.State.DISCONNECTED; + if (mState != Connection.STATE_DISCONNECTED) { + mState = Connection.STATE_DISCONNECTED; mDisconnectCauseCode = cause; mDisconnectCauseMessage = message; @@ -591,7 +581,7 @@ public final class RemoteConnection { void setDestroyed() { if (!mListeners.isEmpty()) { // Make sure that the listeners are notified that the call is destroyed first. - if (mState != Connection.State.DISCONNECTED) { + if (mState != Connection.STATE_DISCONNECTED) { setDisconnected(DisconnectCause.ERROR_UNSPECIFIED, "Connection destroyed."); } @@ -676,7 +666,7 @@ public final class RemoteConnection { } /** - * Create a RemoteConnection which is in the {@link Connection.State#FAILED} state. Attempting + * Create a RemoteConnection which is in the {@link Connection#STATE_FAILED} state. Attempting * to use it for anything will almost certainly result in bad things happening. Do not do this. * * @return a failed {@link RemoteConnection} diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java index 95b62ba65cf7..9a1729f20bef 100644 --- a/telecomm/java/android/telecomm/RemoteConnectionService.java +++ b/telecomm/java/android/telecomm/RemoteConnectionService.java @@ -11,7 +11,7 @@ * 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 - R* limitations under the License. + * limitations under the License. */ package android.telecomm; @@ -25,7 +25,7 @@ import android.telephony.DisconnectCause; import com.android.internal.telecomm.IConnectionService; import com.android.internal.telecomm.IConnectionServiceAdapter; -import com.android.internal.telecomm.IVideoCallProvider; +import com.android.internal.telecomm.IVideoProvider; import com.android.internal.telecomm.RemoteServiceCallback; import java.util.HashMap; @@ -43,14 +43,17 @@ import java.util.UUID; */ final class RemoteConnectionService { - private static final RemoteConnection NULL_CONNECTION = new RemoteConnection(null, null); + private static final RemoteConnection + NULL_CONNECTION = new RemoteConnection("NULL", null, null); private final IConnectionServiceAdapter mServantDelegate = new IConnectionServiceAdapter() { @Override - public void handleCreateConnectionSuccessful(ConnectionRequest request, + public void handleCreateConnectionSuccessful( + String id, + ConnectionRequest request, ParcelableConnection parcel) { - RemoteConnection connection = findConnectionForAction( - request.getCallId(), "handleCreateConnectionSuccessful"); + RemoteConnection connection = + findConnectionForAction(id, "handleCreateConnectionSuccessful"); if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) { mPendingConnections.remove(connection); connection.setState(parcel.getState()); @@ -65,37 +68,40 @@ final class RemoteConnectionService { } @Override - public void handleCreateConnectionFailed(ConnectionRequest request, int errorCode, + public void handleCreateConnectionFailed( + String id, + ConnectionRequest request, + int errorCode, String errorMessage) { // TODO: How do we propagate the failure codes? - findConnectionForAction( - request.getCallId(), "handleCreateConnectionFailed") + findConnectionForAction(id, "handleCreateConnectionFailed") .setDestroyed(); } @Override - public void handleCreateConnectionCancelled(ConnectionRequest request) { - findConnectionForAction( - request.getCallId(), "handleCreateConnectionCancelled") + public void handleCreateConnectionCancelled( + String id, + ConnectionRequest request) { + findConnectionForAction(id, "handleCreateConnectionCancelled") .setDestroyed(); } @Override public void setActive(String callId) { findConnectionForAction(callId, "setActive") - .setState(Connection.State.ACTIVE); + .setState(Connection.STATE_ACTIVE); } @Override public void setRinging(String callId) { findConnectionForAction(callId, "setRinging") - .setState(Connection.State.RINGING); + .setState(Connection.STATE_RINGING); } @Override public void setDialing(String callId) { findConnectionForAction(callId, "setDialing") - .setState(Connection.State.DIALING); + .setState(Connection.STATE_DIALING); } @Override @@ -108,7 +114,7 @@ final class RemoteConnectionService { @Override public void setOnHold(String callId) { findConnectionForAction(callId, "setOnHold") - .setState(Connection.State.HOLDING); + .setState(Connection.STATE_HOLDING); } @Override @@ -151,8 +157,7 @@ final class RemoteConnectionService { } @Override - public void setVideoCallProvider(String callId, - IVideoCallProvider videoCallProvider) { + public void setVideoProvider(String callId, IVideoProvider videoProvider) { // not supported for remote connections. } @@ -244,9 +249,9 @@ final class RemoteConnectionService { PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request, boolean isIncoming) { + final String id = UUID.randomUUID().toString(); final ConnectionRequest newRequest = new ConnectionRequest( request.getAccountHandle(), - UUID.randomUUID().toString(), request.getHandle(), request.getHandlePresentation(), request.getExtras(), @@ -256,17 +261,18 @@ final class RemoteConnectionService { mConnectionService.addConnectionServiceAdapter(mServant.getStub()); } RemoteConnection connection = - new RemoteConnection(mConnectionService, newRequest); + new RemoteConnection(id, mConnectionService, newRequest); mPendingConnections.add(connection); - mConnectionById.put(newRequest.getCallId(), connection); + mConnectionById.put(id, connection); mConnectionService.createConnection( connectionManagerPhoneAccount, + id, newRequest, isIncoming); connection.addListener(new RemoteConnection.Listener() { @Override public void onDestroyed(RemoteConnection connection) { - mConnectionById.remove(newRequest.getCallId()); + mConnectionById.remove(id); if (mConnectionById.isEmpty()) { try { mConnectionService.removeConnectionServiceAdapter(mServant.getStub()); @@ -277,11 +283,13 @@ final class RemoteConnectionService { }); return connection; } catch (RemoteException e) { - return RemoteConnection.failure(DisconnectCause.ERROR_UNSPECIFIED, e.toString()); + return RemoteConnection + .failure(DisconnectCause.ERROR_UNSPECIFIED, e.toString()); } } - private RemoteConnection findConnectionForAction(String callId, String action) { + private RemoteConnection findConnectionForAction( + String callId, String action) { if (mConnectionById.containsKey(callId)) { return mConnectionById.get(callId); } diff --git a/telecomm/java/android/telecomm/Response.java b/telecomm/java/android/telecomm/Response.java index 13c0702fa6c3..f87975615421 100644 --- a/telecomm/java/android/telecomm/Response.java +++ b/telecomm/java/android/telecomm/Response.java @@ -17,7 +17,10 @@ package android.telecomm; /** - * Used to inform a client of asynchronously returned results. + * <strong>OBSOLETE</strong> Used to inform a client of asynchronously returned results. + * <p> + * <strong>TODO:</strong> Remove onCreateConferenceConnection() async method + * then delete this interface. */ public interface Response<IN, OUT> { diff --git a/telecomm/java/android/telecomm/StatusHints.java b/telecomm/java/android/telecomm/StatusHints.java index 496a38c2014c..f7c4f2fdf589 100644 --- a/telecomm/java/android/telecomm/StatusHints.java +++ b/telecomm/java/android/telecomm/StatusHints.java @@ -20,11 +20,9 @@ import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; -import android.net.Uri; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; -import android.util.DisplayMetrics; import java.util.MissingResourceException; import java.util.Objects; @@ -36,13 +34,13 @@ public final class StatusHints implements Parcelable { private final ComponentName mComponentName; private final CharSequence mLabel; - private final int mIconId; + private final int mIconResId; private final Bundle mExtras; - public StatusHints(ComponentName componentName, CharSequence label, int iconId, Bundle extras) { + public StatusHints(ComponentName componentName, CharSequence label, int iconResId, Bundle extras) { mComponentName = componentName; mLabel = label; - mIconId = iconId; + mIconResId = iconResId; mExtras = extras; } @@ -61,17 +59,19 @@ public final class StatusHints implements Parcelable { } /** - * @return The icon resource identifier. + * The icon resource ID for the icon to show. + * + * @return A resource ID. */ - public int getIconId() { - return mIconId; + public int getIconResId() { + return mIconResId; } /** * @return An icon displayed in the in-call UI. */ public Drawable getIcon(Context context) { - return getIcon(context, mIconId); + return getIcon(context, mIconResId); } /** @@ -90,7 +90,7 @@ public final class StatusHints implements Parcelable { public void writeToParcel(Parcel out, int flags) { out.writeParcelable(mComponentName, flags); out.writeCharSequence(mLabel); - out.writeInt(mIconId); + out.writeInt(mIconResId); out.writeParcelable(mExtras, 0); } @@ -108,8 +108,8 @@ public final class StatusHints implements Parcelable { private StatusHints(Parcel in) { mComponentName = in.readParcelable(getClass().getClassLoader()); mLabel = in.readCharSequence(); - mIconId = in.readInt(); - mExtras = (Bundle) in.readParcelable(getClass().getClassLoader()); + mIconResId = in.readInt(); + mExtras = in.readParcelable(getClass().getClassLoader()); } private Drawable getIcon(Context context, int resId) { @@ -121,7 +121,7 @@ public final class StatusHints implements Parcelable { return null; } try { - return packageContext.getResources().getDrawable(resId); + return packageContext.getDrawable(resId); } catch (MissingResourceException e) { Log.e(this, e, "Cannot find icon %d in package %s", resId, mComponentName.getPackageName()); @@ -135,7 +135,7 @@ public final class StatusHints implements Parcelable { StatusHints otherHints = (StatusHints) other; return Objects.equals(otherHints.getComponentName(), getComponentName()) && Objects.equals(otherHints.getLabel(), getLabel()) && - otherHints.getIconId() == getIconId() && + otherHints.getIconResId() == getIconResId() && Objects.equals(otherHints.getExtras(), getExtras()); } return false; @@ -143,7 +143,7 @@ public final class StatusHints implements Parcelable { @Override public int hashCode() { - return Objects.hashCode(mComponentName) + Objects.hashCode(mLabel) + mIconId + + return Objects.hashCode(mComponentName) + Objects.hashCode(mLabel) + mIconResId + Objects.hashCode(mExtras); } } diff --git a/telecomm/java/android/telecomm/TelecommManager.java b/telecomm/java/android/telecomm/TelecommManager.java index 0f31c526d48a..5192b0f7ccb0 100644 --- a/telecomm/java/android/telecomm/TelecommManager.java +++ b/telecomm/java/android/telecomm/TelecommManager.java @@ -72,10 +72,10 @@ public class TelecommManager { * Optional extra for {@link android.content.Intent#ACTION_CALL} containing an integer that * determines the desired video state for an outgoing call. * Valid options: - * {@link android.telecomm.VideoCallProfile.VideoState#AUDIO_ONLY}, - * {@link android.telecomm.VideoCallProfile.VideoState#BIDIRECTIONAL}, - * {@link android.telecomm.VideoCallProfile.VideoState#RX_ENABLED}, - * {@link android.telecomm.VideoCallProfile.VideoState#TX_ENABLED}. + * {@link VideoProfile.VideoState#AUDIO_ONLY}, + * {@link VideoProfile.VideoState#BIDIRECTIONAL}, + * {@link VideoProfile.VideoState#RX_ENABLED}, + * {@link VideoProfile.VideoState#TX_ENABLED}. */ public static final String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.intent.extra.START_CALL_WITH_VIDEO_STATE"; @@ -101,6 +101,17 @@ public class TelecommManager { "android.intent.extra.INCOMING_CALL_EXTRAS"; /** + * Optional extra for {@link android.content.Intent#ACTION_CALL} and + * {@link android.content.Intent#ACTION_DIAL} {@code Intent} containing a {@link Bundle} + * which contains metadata about the call. This {@link Bundle} will be saved into + * {@code Call.Details}. + * + * @hide + */ + public static final String EXTRA_OUTGOING_CALL_EXTRAS = + "android.intent.extra.OUTGOING_CALL_EXTRAS"; + + /** * Optional extra for {@link android.telephony.TelephonyManager#ACTION_PHONE_STATE_CHANGED} * containing the disconnect code. */ @@ -282,10 +293,10 @@ public class TelecommManager { public List<PhoneAccountHandle> getEnabledPhoneAccounts() { try { if (isServiceConnected()) { - return getTelecommService().getEnabledPhoneAccounts(); + return getTelecommService().getOutgoingPhoneAccounts(); } } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelecommService#getEnabledPhoneAccounts", e); + Log.e(TAG, "Error calling ITelecommService#getOutgoingPhoneAccounts", e); } return null; } diff --git a/telecomm/java/android/telecomm/VideoCallImpl.java b/telecomm/java/android/telecomm/VideoCallImpl.java index c32bcd275c2f..c10865f4cc0f 100644 --- a/telecomm/java/android/telecomm/VideoCallImpl.java +++ b/telecomm/java/android/telecomm/VideoCallImpl.java @@ -25,13 +25,15 @@ import android.telecomm.InCallService.VideoCall; import android.view.Surface; import com.android.internal.os.SomeArgs; -import com.android.internal.telecomm.IVideoCallCallback; -import com.android.internal.telecomm.IVideoCallProvider; +import com.android.internal.telecomm.IVideoCallback; +import com.android.internal.telecomm.IVideoProvider; /** * Implementation of a Video Call, which allows InCallUi to communicate commands to the underlying - * {@link ConnectionService.VideoCallProvider}, and direct callbacks from the - * {@link ConnectionService.VideoCallProvider} to the appropriate {@link VideoCall.Listener}. + * {@link Connection.VideoProvider}, and direct callbacks from the + * {@link Connection.VideoProvider} to the appropriate {@link VideoCall.Listener}. + * + * {@hide} */ public class VideoCallImpl extends VideoCall { private static final int MSG_RECEIVE_SESSION_MODIFY_REQUEST = 1; @@ -41,30 +43,30 @@ public class VideoCallImpl extends VideoCall { private static final int MSG_CHANGE_CALL_DATA_USAGE = 5; private static final int MSG_CHANGE_CAMERA_CAPABILITIES = 6; - private final IVideoCallProvider mVideoCallProvider; + private final IVideoProvider mVideoProvider; private final VideoCallListenerBinder mBinder; private VideoCall.Listener mVideoCallListener; private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() { @Override public void binderDied() { - mVideoCallProvider.asBinder().unlinkToDeath(this, 0); + mVideoProvider.asBinder().unlinkToDeath(this, 0); } }; /** - * IVideoCallCallback stub implementation. + * IVideoCallback stub implementation. */ - private final class VideoCallListenerBinder extends IVideoCallCallback.Stub { + private final class VideoCallListenerBinder extends IVideoCallback.Stub { @Override - public void receiveSessionModifyRequest(VideoCallProfile videoCallProfile) { + public void receiveSessionModifyRequest(VideoProfile videoProfile) { mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_REQUEST, - videoCallProfile).sendToTarget(); + videoProfile).sendToTarget(); } @Override - public void receiveSessionModifyResponse(int status, VideoCallProfile requestProfile, - VideoCallProfile responseProfile) { + public void receiveSessionModifyResponse(int status, VideoProfile requestProfile, + VideoProfile responseProfile) { SomeArgs args = SomeArgs.obtain(); args.arg1 = status; args.arg2 = requestProfile; @@ -91,7 +93,7 @@ public class VideoCallImpl extends VideoCall { } @Override - public void changeCameraCapabilities(CallCameraCapabilities cameraCapabilities) { + public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) { mHandler.obtainMessage(MSG_CHANGE_CAMERA_CAPABILITIES, cameraCapabilities).sendToTarget(); } @@ -108,14 +110,14 @@ public class VideoCallImpl extends VideoCall { SomeArgs args; switch (msg.what) { case MSG_RECEIVE_SESSION_MODIFY_REQUEST: - mVideoCallListener.onSessionModifyRequestReceived((VideoCallProfile) msg.obj); + mVideoCallListener.onSessionModifyRequestReceived((VideoProfile) msg.obj); break; case MSG_RECEIVE_SESSION_MODIFY_RESPONSE: args = (SomeArgs) msg.obj; try { int status = (int) args.arg1; - VideoCallProfile requestProfile = (VideoCallProfile) args.arg2; - VideoCallProfile responseProfile = (VideoCallProfile) args.arg3; + VideoProfile requestProfile = (VideoProfile) args.arg2; + VideoProfile responseProfile = (VideoProfile) args.arg3; mVideoCallListener.onSessionModifyResponseReceived( status, requestProfile, responseProfile); @@ -141,7 +143,7 @@ public class VideoCallImpl extends VideoCall { break; case MSG_CHANGE_CAMERA_CAPABILITIES: mVideoCallListener.onCameraCapabilitiesChanged( - (CallCameraCapabilities) msg.obj); + (CameraCapabilities) msg.obj); break; default: break; @@ -150,12 +152,12 @@ public class VideoCallImpl extends VideoCall { }; /** {@hide} */ - VideoCallImpl(IVideoCallProvider videoCallProvider) throws RemoteException { - mVideoCallProvider = videoCallProvider; - mVideoCallProvider.asBinder().linkToDeath(mDeathRecipient, 0); + VideoCallImpl(IVideoProvider videoProvider) throws RemoteException { + mVideoProvider = videoProvider; + mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0); mBinder = new VideoCallListenerBinder(); - mVideoCallProvider.setVideoCallListener(mBinder); + mVideoProvider.setVideoListener(mBinder); } /** {@inheritDoc} */ @@ -166,7 +168,7 @@ public class VideoCallImpl extends VideoCall { /** {@inheritDoc} */ public void setCamera(String cameraId) { try { - mVideoCallProvider.setCamera(cameraId); + mVideoProvider.setCamera(cameraId); } catch (RemoteException e) { } } @@ -174,7 +176,7 @@ public class VideoCallImpl extends VideoCall { /** {@inheritDoc} */ public void setPreviewSurface(Surface surface) { try { - mVideoCallProvider.setPreviewSurface(surface); + mVideoProvider.setPreviewSurface(surface); } catch (RemoteException e) { } } @@ -182,7 +184,7 @@ public class VideoCallImpl extends VideoCall { /** {@inheritDoc} */ public void setDisplaySurface(Surface surface) { try { - mVideoCallProvider.setDisplaySurface(surface); + mVideoProvider.setDisplaySurface(surface); } catch (RemoteException e) { } } @@ -190,7 +192,7 @@ public class VideoCallImpl extends VideoCall { /** {@inheritDoc} */ public void setDeviceOrientation(int rotation) { try { - mVideoCallProvider.setDeviceOrientation(rotation); + mVideoProvider.setDeviceOrientation(rotation); } catch (RemoteException e) { } } @@ -198,23 +200,23 @@ public class VideoCallImpl extends VideoCall { /** {@inheritDoc} */ public void setZoom(float value) { try { - mVideoCallProvider.setZoom(value); + mVideoProvider.setZoom(value); } catch (RemoteException e) { } } /** {@inheritDoc} */ - public void sendSessionModifyRequest(VideoCallProfile requestProfile) { + public void sendSessionModifyRequest(VideoProfile requestProfile) { try { - mVideoCallProvider.sendSessionModifyRequest(requestProfile); + mVideoProvider.sendSessionModifyRequest(requestProfile); } catch (RemoteException e) { } } /** {@inheritDoc} */ - public void sendSessionModifyResponse(VideoCallProfile responseProfile) { + public void sendSessionModifyResponse(VideoProfile responseProfile) { try { - mVideoCallProvider.sendSessionModifyResponse(responseProfile); + mVideoProvider.sendSessionModifyResponse(responseProfile); } catch (RemoteException e) { } } @@ -222,7 +224,7 @@ public class VideoCallImpl extends VideoCall { /** {@inheritDoc} */ public void requestCameraCapabilities() { try { - mVideoCallProvider.requestCameraCapabilities(); + mVideoProvider.requestCameraCapabilities(); } catch (RemoteException e) { } } @@ -230,7 +232,7 @@ public class VideoCallImpl extends VideoCall { /** {@inheritDoc} */ public void requestCallDataUsage() { try { - mVideoCallProvider.requestCallDataUsage(); + mVideoProvider.requestCallDataUsage(); } catch (RemoteException e) { } } @@ -238,7 +240,7 @@ public class VideoCallImpl extends VideoCall { /** {@inheritDoc} */ public void setPauseImage(String uri) { try { - mVideoCallProvider.setPauseImage(uri); + mVideoProvider.setPauseImage(uri); } catch (RemoteException e) { } } diff --git a/telecomm/java/android/telecomm/CallCameraCapabilities.aidl b/telecomm/java/android/telecomm/VideoProfile.aidl index 25b6106e39e3..e756fa771a53 100644 --- a/telecomm/java/android/telecomm/CallCameraCapabilities.aidl +++ b/telecomm/java/android/telecomm/VideoProfile.aidl @@ -17,4 +17,7 @@ package android.telecomm; -parcelable CallCameraCapabilities; +/** + * {@hide} + */ +parcelable VideoProfile; diff --git a/telecomm/java/android/telecomm/VideoCallProfile.java b/telecomm/java/android/telecomm/VideoProfile.java index 24c699634544..b1479781c3ca 100644 --- a/telecomm/java/android/telecomm/VideoCallProfile.java +++ b/telecomm/java/android/telecomm/VideoProfile.java @@ -22,7 +22,7 @@ import android.os.Parcelable; /** * Represents attributes of video calls. */ -public class VideoCallProfile implements Parcelable { +public class VideoProfile implements Parcelable { /** * "High" video quality. */ @@ -48,32 +48,32 @@ public class VideoCallProfile implements Parcelable { private final int mQuality; /** - * Creates an instance of the VideoCallProfile + * Creates an instance of the VideoProfile * * @param videoState The video state. */ - public VideoCallProfile(int videoState) { + public VideoProfile(int videoState) { this(videoState, QUALITY_DEFAULT); } /** - * Creates an instance of the VideoCallProfile + * Creates an instance of the VideoProfile * * @param videoState The video state. * @param quality The video quality. */ - public VideoCallProfile(int videoState, int quality) { + public VideoProfile(int videoState, int quality) { mVideoState = videoState; mQuality = quality; } /** * The video state of the call. - * Valid values: {@link VideoCallProfile.VideoState#AUDIO_ONLY}, - * {@link VideoCallProfile.VideoState#BIDIRECTIONAL}, - * {@link VideoCallProfile.VideoState#TX_ENABLED}, - * {@link VideoCallProfile.VideoState#RX_ENABLED}, - * {@link VideoCallProfile.VideoState#PAUSED}. + * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY}, + * {@link VideoProfile.VideoState#BIDIRECTIONAL}, + * {@link VideoProfile.VideoState#TX_ENABLED}, + * {@link VideoProfile.VideoState#RX_ENABLED}, + * {@link VideoProfile.VideoState#PAUSED}. */ public int getVideoState() { return mVideoState; @@ -81,18 +81,18 @@ public class VideoCallProfile implements Parcelable { /** * The desired video quality for the call. - * Valid values: {@link VideoCallProfile#QUALITY_HIGH}, {@link VideoCallProfile#QUALITY_MEDIUM}, - * {@link VideoCallProfile#QUALITY_LOW}, {@link VideoCallProfile#QUALITY_DEFAULT}. + * Valid values: {@link VideoProfile#QUALITY_HIGH}, {@link VideoProfile#QUALITY_MEDIUM}, + * {@link VideoProfile#QUALITY_LOW}, {@link VideoProfile#QUALITY_DEFAULT}. */ public int getQuality() { return mQuality; } /** - * Responsible for creating VideoCallProfile objects from deserialized Parcels. + * Responsible for creating VideoProfile objects from deserialized Parcels. **/ - public static final Parcelable.Creator<VideoCallProfile> CREATOR = - new Parcelable.Creator<VideoCallProfile> () { + public static final Parcelable.Creator<VideoProfile> CREATOR = + new Parcelable.Creator<VideoProfile> () { /** * Creates a MediaProfile instances from a parcel. * @@ -100,17 +100,17 @@ public class VideoCallProfile implements Parcelable { * @return The MediaProfile. */ @Override - public VideoCallProfile createFromParcel(Parcel source) { + public VideoProfile createFromParcel(Parcel source) { int state = source.readInt(); int quality = source.readInt(); - ClassLoader classLoader = VideoCallProfile.class.getClassLoader(); - return new VideoCallProfile(state, quality); + ClassLoader classLoader = VideoProfile.class.getClassLoader(); + return new VideoProfile(state, quality); } @Override - public VideoCallProfile[] newArray(int size) { - return new VideoCallProfile[size]; + public VideoProfile[] newArray(int size) { + return new VideoProfile[size]; } }; diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl index 7abb4dd8f39a..c41242413782 100644 --- a/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl +++ b/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl @@ -17,7 +17,7 @@ package com.android.internal.telecomm; import android.os.Bundle; -import android.telecomm.CallAudioState; +import android.telecomm.AudioState; import android.telecomm.ConnectionRequest; import android.telecomm.PhoneAccountHandle; @@ -37,6 +37,7 @@ oneway interface IConnectionService { void createConnection( in PhoneAccountHandle connectionManagerPhoneAccount, + String callId, in ConnectionRequest request, boolean isIncoming); @@ -52,7 +53,7 @@ oneway interface IConnectionService { void unhold(String callId); - void onAudioStateChanged(String activeCallId, in CallAudioState audioState); + void onAudioStateChanged(String activeCallId, in AudioState audioState); void playDtmfTone(String callId, char digit); @@ -62,8 +63,6 @@ oneway interface IConnectionService { void splitFromConference(String callId); - void swapWithBackgroundCall(String callId); - void onPostDialContinue(String callId, boolean proceed); void onPhoneAccountClicked(String callId); diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl index c6f97123910d..fd4e9314c8e5 100644 --- a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl +++ b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl @@ -22,7 +22,7 @@ import android.telecomm.ConnectionRequest; import android.telecomm.ParcelableConnection; import android.telecomm.StatusHints; -import com.android.internal.telecomm.IVideoCallProvider; +import com.android.internal.telecomm.IVideoProvider; import com.android.internal.telecomm.RemoteServiceCallback; /** @@ -34,12 +34,18 @@ import com.android.internal.telecomm.RemoteServiceCallback; */ oneway interface IConnectionServiceAdapter { void handleCreateConnectionSuccessful( - in ConnectionRequest request, in ParcelableConnection connection); + String callId, + in ConnectionRequest request, + in ParcelableConnection connection); void handleCreateConnectionFailed( - in ConnectionRequest request, int errorCode, String errorMessage); + String callId, + in ConnectionRequest request, + int errorCode, String errorMessage); - void handleCreateConnectionCancelled(in ConnectionRequest request); + void handleCreateConnectionCancelled( + String callId, + in ConnectionRequest request); void setActive(String callId); @@ -65,7 +71,7 @@ oneway interface IConnectionServiceAdapter { void queryRemoteConnectionServices(RemoteServiceCallback callback); - void setVideoCallProvider(String callId, IVideoCallProvider videoCallProvider); + void setVideoProvider(String callId, IVideoProvider videoProvider); void setVideoState(String callId, int videoState); diff --git a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl index 8bc950f54c48..2ce5c6be6d63 100644 --- a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl +++ b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl @@ -16,7 +16,6 @@ package com.android.internal.telecomm; -import android.telecomm.CallAudioState; import android.telecomm.PhoneAccountHandle; /** @@ -55,8 +54,6 @@ oneway interface IInCallAdapter { void splitFromConference(String callId); - void swapWithBackgroundCall(String callId); - void turnOnProximitySensor(); void turnOffProximitySensor(boolean screenOnImmediately); diff --git a/telecomm/java/com/android/internal/telecomm/IInCallService.aidl b/telecomm/java/com/android/internal/telecomm/IInCallService.aidl index 8ec61963f6e0..5d4992f65230 100644 --- a/telecomm/java/com/android/internal/telecomm/IInCallService.aidl +++ b/telecomm/java/com/android/internal/telecomm/IInCallService.aidl @@ -17,7 +17,7 @@ package com.android.internal.telecomm; import android.app.PendingIntent; -import android.telecomm.CallAudioState; +import android.telecomm.AudioState; import android.telecomm.ParcelableCall; import com.android.internal.telecomm.IInCallAdapter; @@ -40,7 +40,7 @@ oneway interface IInCallService { void setPostDialWait(String callId, String remaining); - void onAudioStateChanged(in CallAudioState audioState); + void onAudioStateChanged(in AudioState audioState); void bringToForeground(boolean showDialpad); diff --git a/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl b/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl index 5036948029ee..3c1dea6cadfe 100644 --- a/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl +++ b/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl @@ -40,9 +40,9 @@ interface ITelecommService { PhoneAccountHandle getDefaultOutgoingPhoneAccount(); /** - * @see TelecommManager#getEnabledPhoneAccounts + * @see TelecommManager#getOutgoingPhoneAccounts */ - List<PhoneAccountHandle> getEnabledPhoneAccounts(); + List<PhoneAccountHandle> getOutgoingPhoneAccounts(); /** * @see TelecommManager#getPhoneAccount diff --git a/telecomm/java/com/android/internal/telecomm/IVideoCallCallback.aidl b/telecomm/java/com/android/internal/telecomm/IVideoCallback.aidl index 1a8f68e7629b..186f083dc633 100644 --- a/telecomm/java/com/android/internal/telecomm/IVideoCallCallback.aidl +++ b/telecomm/java/com/android/internal/telecomm/IVideoCallback.aidl @@ -16,22 +16,24 @@ package com.android.internal.telecomm; -import android.telecomm.CallCameraCapabilities; -import android.telecomm.VideoCallProfile; - -/** - * Internal definition of a callback interface, used for an InCallUi to respond to video telephony - * changes. - * - * @see android.telecomm.InCallService.VideoCall.Listener - * - * {@hide} - */ -oneway interface IVideoCallCallback { - void receiveSessionModifyRequest(in VideoCallProfile videoCallProfile); - - void receiveSessionModifyResponse(int status, in VideoCallProfile requestedProfile, - in VideoCallProfile responseProfile); +import android.telecomm.CameraCapabilities; +import android.telecomm.VideoProfile; + + /** + * Internal definition of a callback interface, used for an InCallUi to respond to video + * telephony changes. + * + * @see android.telecomm.InCallService.VideoCall.Listener + * + * {@hide} + */ +oneway interface IVideoCallback { + void receiveSessionModifyRequest(in VideoProfile videoProfile); + + void receiveSessionModifyResponse( + int status, + in VideoProfile requestedProfile, + in VideoProfile responseProfile); void handleCallSessionEvent(int event); @@ -39,5 +41,5 @@ oneway interface IVideoCallCallback { void changeCallDataUsage(int dataUsage); - void changeCameraCapabilities(in CallCameraCapabilities callCameraCapabilities); + void changeCameraCapabilities(in CameraCapabilities cameraCapabilities); } diff --git a/telecomm/java/com/android/internal/telecomm/IVideoCallProvider.aidl b/telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl index c1ba74974c52..9d3ad7f55590 100644 --- a/telecomm/java/com/android/internal/telecomm/IVideoCallProvider.aidl +++ b/telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl @@ -17,15 +17,15 @@ package com.android.internal.telecomm; import android.view.Surface; -import android.telecomm.VideoCallProfile; +import android.telecomm.VideoProfile; /** * Internal remote interface for a video call provider. - * @see android.telecomm.VideoCallProvider + * @see android.telecomm.VideoProvider * @hide */ -oneway interface IVideoCallProvider { - void setVideoCallListener(IBinder videoCallListenerBinder); +oneway interface IVideoProvider { + void setVideoListener(IBinder videoListenerBinder); void setCamera(String cameraId); @@ -37,9 +37,9 @@ oneway interface IVideoCallProvider { void setZoom(float value); - void sendSessionModifyRequest(in VideoCallProfile reqProfile); + void sendSessionModifyRequest(in VideoProfile reqProfile); - void sendSessionModifyResponse(in VideoCallProfile responseProfile); + void sendSessionModifyResponse(in VideoProfile responseProfile); void requestCameraCapabilities(); diff --git a/telephony/java/com/android/ims/ImsCallProfile.java b/telephony/java/com/android/ims/ImsCallProfile.java index adcb4350fb4c..dcd0b792f720 100644 --- a/telephony/java/com/android/ims/ImsCallProfile.java +++ b/telephony/java/com/android/ims/ImsCallProfile.java @@ -19,7 +19,7 @@ package com.android.ims; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; -import android.telecomm.VideoCallProfile; +import android.telecomm.VideoProfile; /** * Parcelable object to handle IMS call profile. @@ -290,7 +290,7 @@ public class ImsCallProfile implements Parcelable { /** * Converts from the call types defined in {@link com.android.ims.ImsCallProfile} to the - * video state values defined in {@link android.telecomm.VideoCallProfile}. + * video state values defined in {@link VideoProfile}. * * @param callType The call type. * @return The video state. @@ -298,32 +298,32 @@ public class ImsCallProfile implements Parcelable { public static int getVideoStateFromCallType(int callType) { switch (callType) { case CALL_TYPE_VT_NODIR: - return VideoCallProfile.VideoState.PAUSED | - VideoCallProfile.VideoState.BIDIRECTIONAL; + return VideoProfile.VideoState.PAUSED | + VideoProfile.VideoState.BIDIRECTIONAL; case CALL_TYPE_VT_TX: - return VideoCallProfile.VideoState.TX_ENABLED; + return VideoProfile.VideoState.TX_ENABLED; case CALL_TYPE_VT_RX: - return VideoCallProfile.VideoState.RX_ENABLED; + return VideoProfile.VideoState.RX_ENABLED; case CALL_TYPE_VT: - return VideoCallProfile.VideoState.BIDIRECTIONAL; + return VideoProfile.VideoState.BIDIRECTIONAL; case CALL_TYPE_VOICE: - return VideoCallProfile.VideoState.AUDIO_ONLY; + return VideoProfile.VideoState.AUDIO_ONLY; default: - return VideoCallProfile.VideoState.AUDIO_ONLY; + return VideoProfile.VideoState.AUDIO_ONLY; } } /** - * Converts from the video state values defined in {@link android.telecomm.VideoCallProfile} + * Converts from the video state values defined in {@link VideoProfile} * to the call types defined in {@link ImsCallProfile}. * * @param videoState The video state. * @return The call type. */ public static int getCallTypeFromVideoState(int videoState) { - boolean videoTx = isVideoStateSet(videoState, VideoCallProfile.VideoState.TX_ENABLED); - boolean videoRx = isVideoStateSet(videoState, VideoCallProfile.VideoState.RX_ENABLED); - boolean isPaused = isVideoStateSet(videoState, VideoCallProfile.VideoState.PAUSED); + boolean videoTx = isVideoStateSet(videoState, VideoProfile.VideoState.TX_ENABLED); + boolean videoRx = isVideoStateSet(videoState, VideoProfile.VideoState.RX_ENABLED); + boolean isPaused = isVideoStateSet(videoState, VideoProfile.VideoState.PAUSED); if (isPaused) { return ImsCallProfile.CALL_TYPE_VT_NODIR; } else if (videoTx && !videoRx) { diff --git a/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl b/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl index 6b8ec5246e02..67bfe416978f 100644 --- a/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl +++ b/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl @@ -16,8 +16,8 @@ package com.android.ims.internal; -import android.telecomm.CallCameraCapabilities; -import android.telecomm.VideoCallProfile; +import android.telecomm.CameraCapabilities; +import android.telecomm.VideoProfile; /** * Internal remote interface for IMS's video call provider. @@ -32,10 +32,10 @@ import android.telecomm.VideoCallProfile; * {@hide} */ oneway interface IImsVideoCallCallback { - void receiveSessionModifyRequest(in VideoCallProfile videoCallProfile); + void receiveSessionModifyRequest(in VideoProfile videoProfile); - void receiveSessionModifyResponse(int status, in VideoCallProfile requestedProfile, - in VideoCallProfile responseProfile); + void receiveSessionModifyResponse(int status, in VideoProfile requestedProfile, + in VideoProfile responseProfile); void handleCallSessionEvent(int event); @@ -43,5 +43,5 @@ oneway interface IImsVideoCallCallback { void changeCallDataUsage(int dataUsage); - void changeCameraCapabilities(in CallCameraCapabilities callCameraCapabilities); + void changeCameraCapabilities(in CameraCapabilities cameraCapabilities); } diff --git a/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl b/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl index f8389ecf14c6..4db0d1460967 100644 --- a/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl +++ b/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl @@ -17,7 +17,7 @@ package com.android.ims.internal; import android.view.Surface; -import android.telecomm.VideoCallProfile; +import android.telecomm.VideoProfile; import com.android.ims.internal.IImsVideoCallCallback; @@ -52,9 +52,9 @@ oneway interface IImsVideoCallProvider { void setZoom(float value); - void sendSessionModifyRequest(in VideoCallProfile reqProfile); + void sendSessionModifyRequest(in VideoProfile reqProfile); - void sendSessionModifyResponse(in VideoCallProfile responseProfile); + void sendSessionModifyResponse(in VideoProfile responseProfile); void requestCameraCapabilities(); diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 15298599e91b..a8a90579adb0 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -287,6 +287,7 @@ cat include/telephony/ril.h | \ int RIL_REQUEST_ALLOW_DATA = 123; int RIL_REQUEST_GET_HARDWARE_CONFIG = 124; int RIL_REQUEST_SIM_AUTHENTICATION = 125; + int RIL_REQUEST_SET_DATA_PROFILE = 128; int RIL_UNSOL_RESPONSE_BASE = 1000; int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000; diff --git a/tests/FeatureSplit/feature1/Android.mk b/tests/FeatureSplit/feature1/Android.mk index 305982412be5..adfb575a0da6 100644 --- a/tests/FeatureSplit/feature1/Android.mk +++ b/tests/FeatureSplit/feature1/Android.mk @@ -26,7 +26,6 @@ featureOfApk := $(call intermediates-dir-for,APPS,$(featureOf))/package.apk localRStamp := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)/src/R.stamp $(localRStamp): $(featureOfApk) -$(info $(localRStamp)) LOCAL_AAPT_FLAGS := --feature-of $(featureOfApk) include $(BUILD_PACKAGE) diff --git a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/AppListFragment.java b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/AppListFragment.java index c0f3a7f75825..526ea5d02fbd 100644 --- a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/AppListFragment.java +++ b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/AppListFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 The Android Open Source Project + * 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. diff --git a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java index 3fc468d7f7a3..2fc77dc132aa 100644 --- a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java +++ b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/BrowserListFragment.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 The Android Open Source Project + * 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. diff --git a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/MainActivity.java b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/MainActivity.java index ed91aad22de0..4c2823439804 100644 --- a/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/MainActivity.java +++ b/tests/MusicBrowserDemo/src/com/example/android/musicbrowserdemo/MainActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 The Android Open Source Project + * 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. diff --git a/tools/aapt/ApkBuilder.cpp b/tools/aapt/ApkBuilder.cpp index 12f60400e99d..01e02e270b63 100644 --- a/tools/aapt/ApkBuilder.cpp +++ b/tools/aapt/ApkBuilder.cpp @@ -85,11 +85,24 @@ ApkSplit::ApkSplit(const std::set<ConfigDescription>& configs, const sp<Resource if (mName.size() > 0) { mName.append(","); mDirName.append("_"); + mPackageSafeName.append("."); } String8 configStr = iter->toString(); + String8 packageConfigStr(configStr); + size_t len = packageConfigStr.length(); + if (len > 0) { + char* buf = packageConfigStr.lockBuffer(len); + for (char* end = buf + len; buf < end; ++buf) { + if (*buf == '-') { + *buf = '_'; + } + } + packageConfigStr.unlockBuffer(len); + } mName.append(configStr); mDirName.append(configStr); + mPackageSafeName.append(packageConfigStr); } } diff --git a/tools/aapt/ApkBuilder.h b/tools/aapt/ApkBuilder.h index db23c8488bdd..0d7f06b1f323 100644 --- a/tools/aapt/ApkBuilder.h +++ b/tools/aapt/ApkBuilder.h @@ -95,6 +95,10 @@ public: return mDirName; } + const android::String8& getPackageSafeName() const { + return mPackageSafeName; + } + bool isBase() const { return mIsBase; } @@ -111,6 +115,7 @@ private: const bool mIsBase; String8 mName; String8 mDirName; + String8 mPackageSafeName; std::set<OutputEntry> mFiles; }; diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index 2401b3a9b6fb..010d59ba1923 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -937,8 +937,8 @@ status_t generateAndroidManifestForSplit(Bundle* bundle, const sp<AaptAssets>& a } // Add the 'split' attribute which describes the configurations included. - String8 splitName("config_"); - splitName.append(split->getDirectorySafeName()); + String8 splitName("config."); + splitName.append(split->getPackageSafeName()); manifest->addAttribute(String16(), String16("split"), String16(splitName)); // Build an empty <application> tag (required). diff --git a/tools/layoutlib/.idea/copyright/profiles_settings.xml b/tools/layoutlib/.idea/copyright/profiles_settings.xml index e7bedf3377d4..20145de481f1 100644 --- a/tools/layoutlib/.idea/copyright/profiles_settings.xml +++ b/tools/layoutlib/.idea/copyright/profiles_settings.xml @@ -1,3 +1,3 @@ <component name="CopyrightManager"> - <settings default="" /> + <settings default="Android" /> </component>
\ No newline at end of file diff --git a/tools/layoutlib/bridge/resources/bars/README b/tools/layoutlib/bridge/resources/bars/README new file mode 100644 index 000000000000..c84ef804ccab --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/README @@ -0,0 +1,8 @@ +The directory contains the resources for StatusBar and Navigation Bar. + +The resources are not arranged as per the standard resources configuration. +They are stored per API. However, to prevent duplication of resources, each API +resource directory is used as a backup for all earlier API levels. + +For example, for the back icon for ICS, we search first in v18, where we don't +find it, and then in v19. diff --git a/tools/layoutlib/bridge/resources/bars/status_bar.xml b/tools/layoutlib/bridge/resources/bars/status_bar.xml index 51b474dab97f..75bfb6e270e0 100644 --- a/tools/layoutlib/bridge/resources/bars/status_bar.xml +++ b/tools/layoutlib/bridge/resources/bars/status_bar.xml @@ -13,5 +13,5 @@ android:layout_width="wrap_content" android:layout_marginLeft="3dp" android:layout_marginRight="5dp" - android:layout_marginTop="1dp"/> + android:layout_marginTop="2dp"/> </merge> diff --git a/tools/layoutlib/bridge/resources/bars/v11/README b/tools/layoutlib/bridge/resources/bars/v11/README deleted file mode 100644 index ae094e2beefe..000000000000 --- a/tools/layoutlib/bridge/resources/bars/v11/README +++ /dev/null @@ -1 +0,0 @@ -Resources for Api level 11-20 diff --git a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png Binary files differnew file mode 100644 index 000000000000..c920ec4fe71a --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png diff --git a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png Binary files differnew file mode 100644 index 000000000000..931daeddceb5 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png Binary files differnew file mode 100644 index 000000000000..943332e5929c --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png diff --git a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png Binary files differnew file mode 100644 index 000000000000..6e1ac9189e8f --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png Binary files differnew file mode 100644 index 000000000000..36c61e13ade3 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png diff --git a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png Binary files differnew file mode 100644 index 000000000000..625c61dc4393 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_back.png Binary files differindex 84e6bc89c082..84e6bc89c082 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/hdpi/ic_sysbar_back.png +++ b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_back.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_home.png Binary files differindex 38e4f45719e7..38e4f45719e7 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/hdpi/ic_sysbar_home.png +++ b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_home.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_recent.png Binary files differindex bf9f3009c32c..bf9f3009c32c 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/hdpi/ic_sysbar_recent.png +++ b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_recent.png diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png Binary files differnew file mode 100644 index 000000000000..6248cfd7b09b --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_back.png Binary files differindex 782ebfe3f2ba..782ebfe3f2ba 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-hdpi/ic_sysbar_back.png +++ b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_back.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_recent.png Binary files differindex 677b47137a3f..677b47137a3f 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-hdpi/ic_sysbar_recent.png +++ b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_recent.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_back.png Binary files differindex a1b806266959..a1b806266959 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-mdpi/ic_sysbar_back.png +++ b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_back.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_recent.png Binary files differindex fcdbefe9f506..fcdbefe9f506 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-mdpi/ic_sysbar_recent.png +++ b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_recent.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_back.png Binary files differindex 633d86482938..633d86482938 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-xhdpi/ic_sysbar_back.png +++ b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_back.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_recent.png Binary files differindex 4665e2a6fef9..4665e2a6fef9 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/ldrtl-xhdpi/ic_sysbar_recent.png +++ b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_recent.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_back.png Binary files differindex a00bc5b5f33b..a00bc5b5f33b 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/mdpi/ic_sysbar_back.png +++ b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_back.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_home.png Binary files differindex dc3183bf640f..dc3183bf640f 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/mdpi/ic_sysbar_home.png +++ b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_home.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_recent.png Binary files differindex b07f611ab98c..b07f611ab98c 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/mdpi/ic_sysbar_recent.png +++ b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_recent.png diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png Binary files differnew file mode 100644 index 000000000000..441de0ce78f8 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_back.png Binary files differindex bd60cd65878a..bd60cd65878a 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/xhdpi/ic_sysbar_back.png +++ b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_back.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_home.png Binary files differindex c5bc5c96ef05..c5bc5c96ef05 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/xhdpi/ic_sysbar_home.png +++ b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_home.png diff --git a/tools/layoutlib/bridge/resources/bars/v11/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_recent.png Binary files differindex f621d9cc7242..f621d9cc7242 100644 --- a/tools/layoutlib/bridge/resources/bars/v11/xhdpi/ic_sysbar_recent.png +++ b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_recent.png diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png Binary files differnew file mode 100644 index 000000000000..459a1a2e83ce --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png Binary files differnew file mode 100644 index 000000000000..79cfcee70c4b --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png Binary files differnew file mode 100644 index 000000000000..64f6a22fe65b --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png Binary files differnew file mode 100644 index 000000000000..6e0b071206d5 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png Binary files differnew file mode 100644 index 000000000000..494b005326d8 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png Binary files differnew file mode 100644 index 000000000000..f17189a0645d --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_charge_anim100.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_charge_anim100.png Binary files differdeleted file mode 100644 index 829378ea9f8f..000000000000 --- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_charge_anim100.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/status_bar_background.9.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/status_bar_background.9.png Binary files differdeleted file mode 100644 index a4be29879663..000000000000 --- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/status_bar_background.9.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png Binary files differnew file mode 100644 index 000000000000..2a9757dea17e --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_charge_anim100.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_charge_anim100.png Binary files differdeleted file mode 100644 index 2773a70691a8..000000000000 --- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_charge_anim100.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/status_bar_background.9.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/status_bar_background.9.png Binary files differdeleted file mode 100644 index eb7c1a4d7819..000000000000 --- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/status_bar_background.9.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png Binary files differnew file mode 100644 index 000000000000..555bcd972415 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_charge_anim100.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_charge_anim100.png Binary files differdeleted file mode 100644 index c7fd7194fafa..000000000000 --- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_charge_anim100.png +++ /dev/null diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png Binary files differnew file mode 100644 index 000000000000..6474aadeeab0 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png diff --git a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png Binary files differnew file mode 100644 index 000000000000..754cdf6564d6 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png diff --git a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png Binary files differnew file mode 100644 index 000000000000..b5326d257961 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png Binary files differnew file mode 100644 index 000000000000..7023ea7b420c --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png diff --git a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png Binary files differnew file mode 100644 index 000000000000..17a955dcc3db --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png diff --git a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png Binary files differnew file mode 100644 index 000000000000..19165ab40ea0 --- /dev/null +++ b/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java index bf4e288ced91..bd80cb8b2374 100644 --- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java @@ -26,11 +26,12 @@ import android.content.res.AssetManager; import java.awt.Font; import java.awt.FontFormatException; import java.io.File; +import java.io.FileNotFoundException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Scanner; import java.util.Set; import static android.graphics.Typeface_Delegate.SYSTEM_FONTS; @@ -54,14 +55,7 @@ public class FontFamily_Delegate { private static final String FONT_SUFFIX_BOLDITALIC = "BoldItalic.ttf"; private static final String FONT_SUFFIX_BOLD = "Bold.ttf"; private static final String FONT_SUFFIX_ITALIC = "Italic.ttf"; - - private static final Set<String> MISSING_FONTS = - Collections.unmodifiableSet(new HashSet<String>(Arrays.asList( - "NotoSansHans-Regular.otf", - "NotoSansHant-Regular.otf", - "NotoSansJP-Regular.otf", - "NotoSansKR-Regular.otf" - ))); + private static final String FN_ALL_FONTS_LIST = "fontsInSdk.txt"; /** * A class associating {@link Font} with its metadata. @@ -80,6 +74,7 @@ public class FontFamily_Delegate { private static String sFontLocation; private static final List<FontFamily_Delegate> sPostInitDelegate = new ArrayList<FontFamily_Delegate>(); + private static Set<String> SDK_FONTS; // ---- delegate data ---- @@ -113,6 +108,31 @@ public class FontFamily_Delegate { public static synchronized void setFontLocation(String fontLocation) { sFontLocation = fontLocation; + // init list of bundled fonts. + File allFonts = new File(fontLocation, FN_ALL_FONTS_LIST); + // Current number of fonts is 103. Use the next round number to leave scope for more fonts + // in the future. + Set<String> allFontsList = new HashSet<String>(128); + Scanner scanner = null; + try { + scanner = new Scanner(allFonts); + while (scanner.hasNext()) { + String name = scanner.next(); + // Skip font configuration files. + if (!name.endsWith(".xml")) { + allFontsList.add(name); + } + } + } catch (FileNotFoundException e) { + Bridge.getLog().error(LayoutLog.TAG_BROKEN, + "Unable to load the list of fonts. Try re-installing the SDK Platform from the SDK Manager.", + e, null); + } finally { + if (scanner != null) { + scanner.close(); + } + } + SDK_FONTS = Collections.unmodifiableSet(allFontsList); for (FontFamily_Delegate fontFamily : sPostInitDelegate) { fontFamily.init(); } @@ -225,13 +245,6 @@ public class FontFamily_Delegate { /*package*/ static boolean nAddFont(long nativeFamily, String path) { FontFamily_Delegate delegate = getDelegate(nativeFamily); if (delegate != null) { - // If the font to be added is known to be missing from the SDK, don't try to load it and - // mark the FontFamily to be not valid. - if (path.startsWith(SYSTEM_FONTS) && - MISSING_FONTS.contains(path.substring(SYSTEM_FONTS.length()))) { - return delegate.mValid = false; - } - delegate.mValid = true; if (sFontLocation == null) { delegate.mPath.add(path); return true; @@ -259,6 +272,14 @@ public class FontFamily_Delegate { } private boolean addFont(String path) { + // If the font is not in the list of fonts bundled with the SDK, don't try to load it and + // mark the FontFamily to be not valid. + if (path.startsWith(SYSTEM_FONTS) && + !SDK_FONTS.contains(path.substring(SYSTEM_FONTS.length()))) { + return mValid = false; + } + // Set valid to true, even if the font fails to load. + mValid = true; Font font = loadFont(path); if (font == null) { return false; diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java index 09b57feeaf28..f8bc2ae276c0 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -444,7 +444,8 @@ public class IWindowManagerImpl implements IWindowManager { } @Override - public void keyguardGoingAway() throws RemoteException { + public void keyguardGoingAway(boolean disableWindowAnimations, + boolean keyguardGoingToNotificationShade) throws RemoteException { } @Override diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java index 089cad3527c1..9b814f5e47a7 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java @@ -16,31 +16,58 @@ package com.android.layoutlib.bridge.bars; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static android.os.Build.VERSION_CODES.GINGERBREAD; +import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH; +import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2; +import static android.os.Build.VERSION_CODES.KITKAT; + /** * Various helper methods to simulate older versions of platform. */ public class Config { - public static final String DEFAULT_RESOURCE_DIR = "/bars/v21/"; + // each of these resource dirs must end in '/' + private static final String GINGERBREAD_DIR = "/bars/v9/"; + private static final String JELLYBEAN_DIR = "/bars/v18/"; + private static final String KITKAT_DIR = "/bars/v19/"; + private static final String DEFAULT_RESOURCE_DIR = "/bars/v21/"; + + private static final List<String> sDefaultResourceDir = + Collections.singletonList(DEFAULT_RESOURCE_DIR); public static boolean showOnScreenNavBar(int platformVersion) { - // return true if ICS or later. - return platformVersion >= 14 || platformVersion == 0; + return platformVersion == 0 || platformVersion >= ICE_CREAM_SANDWICH; } public static int getStatusBarColor(int platformVersion) { // return white for froyo and earlier; black otherwise. - return platformVersion >= 9 || platformVersion == 0 ? 0xFF000000 : 0xFFFFFFFF; - } - - public static boolean usesCustomResourceDir(int platformVersion) { - return platformVersion > 10 && platformVersion < 21; + return platformVersion == 0 || platformVersion >= GINGERBREAD ? 0xFF000000 : 0xFFFFFFFF; } - public static String getResourceDir(int platformVersion) { - if (usesCustomResourceDir(platformVersion)) { - return "/bars/v11/"; + public static List<String> getResourceDirs(int platformVersion) { + // Special case the most used scenario. + if (platformVersion == 0) { + return sDefaultResourceDir; } - return DEFAULT_RESOURCE_DIR; + List<String> list = new ArrayList<String>(4); + // Gingerbread - uses custom battery and wifi icons. + if (platformVersion <= GINGERBREAD) { + list.add(GINGERBREAD_DIR); + } + // ICS - JellyBean uses custom battery, wifi. + if (platformVersion <= JELLY_BEAN_MR2) { + list.add(JELLYBEAN_DIR); + } + // KitKat - uses custom wifi and nav icons. + if (platformVersion <= KITKAT) { + list.add(KITKAT_DIR); + } + list.add(DEFAULT_RESOURCE_DIR); + + return Collections.unmodifiableList(list); } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java index 4da9f04df24f..bed232ab4195 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java @@ -47,8 +47,6 @@ import android.widget.TextView; import java.io.IOException; import java.io.InputStream; -import static com.android.layoutlib.bridge.bars.Config.DEFAULT_RESOURCE_DIR; - /** * Base "bar" class for the window decor around the the edited layout. * This is basically an horizontal layout that loads a given layout on creation (it is read @@ -60,11 +58,6 @@ import static com.android.layoutlib.bridge.bars.Config.DEFAULT_RESOURCE_DIR; */ abstract class CustomBar extends LinearLayout { - // An upper-bound on the length of the path to the directory to find the icon in. - // This assumes that resource directory name for different api levels have same length. - private static final int ICON_PATH_LENGTH = DEFAULT_RESOURCE_DIR.length() - + LayoutDirection.RTL.getResourceValue().length() + 9; // 9 = "-xxxhdpi/".length - private final int mSimulatedPlatformVersion; @@ -97,72 +90,6 @@ abstract class CustomBar extends LinearLayout { } } - private InputStream getIcon(String iconName, Density[] densityInOut, LayoutDirection direction, - StringBuilder[] pathOut, boolean tryOtherDensities) { - pathOut[0] = new StringBuilder(ICON_PATH_LENGTH + iconName.length()); - - if (Config.usesCustomResourceDir(mSimulatedPlatformVersion)) { - // current density. - Density density = densityInOut[0]; - InputStream stream = getIcon(iconName, Config.getResourceDir(mSimulatedPlatformVersion), - densityInOut, direction, pathOut, tryOtherDensities); - if (stream != null) { - return stream; - } - // reset the density. - densityInOut[0] = density; - } - return getIcon(iconName, DEFAULT_RESOURCE_DIR, densityInOut, direction, pathOut, - tryOtherDensities); - - } - - private InputStream getIcon(String iconName, String dir, Density[] densityInOut, - LayoutDirection direction, StringBuilder[] pathOut, boolean tryOtherDensities) { - // current density - Density density = densityInOut[0]; - - pathOut[0].setLength(0); - - // bitmap url relative to this class - if (direction == LayoutDirection.RTL) { - pathOut[0].append(dir) - .append(direction.getResourceValue()) - .append('-') - .append(density.getResourceValue()) - .append('/') - .append(iconName); - } else { - // Since we do not have any ldltr resource, skip the check. - pathOut[0].append(dir) - .append(density.getResourceValue()) - .append('/') - .append(iconName); - } - - InputStream stream = getClass().getResourceAsStream(pathOut[0].toString()); - if (stream == null && tryOtherDensities) { - for (Density d : Density.values()) { - if (d != density) { - densityInOut[0] = d; - stream = getIcon(iconName, dir, densityInOut, direction, pathOut, - false /*tryOtherDensities*/); - if (stream != null) { - return stream; - } - } - } - // couldn't find resource with direction qualifier, try without. - if (direction == LayoutDirection.RTL) { - densityInOut[0] = density; - stream = getIcon(iconName, dir, densityInOut, null, pathOut, - true /*tryOtherDensities*/); - } - } - - return stream; - } - protected void loadIcon(int index, String iconName, Density density) { loadIcon(index, iconName, density, false); } @@ -172,15 +99,14 @@ abstract class CustomBar extends LinearLayout { if (child instanceof ImageView) { ImageView imageView = (ImageView) child; - StringBuilder[] pathOut = new StringBuilder[1]; - Density[] densityInOut = new Density[]{density}; LayoutDirection dir = isRtl ? LayoutDirection.RTL : null; - InputStream stream = getIcon(iconName, densityInOut, dir, pathOut, - true /*tryOtherDensities*/); - density = densityInOut[0]; - String path = pathOut[0].toString(); + IconLoader iconLoader = new IconLoader(iconName, density, mSimulatedPlatformVersion, + dir); + InputStream stream = iconLoader.getIcon(); if (stream != null) { + density = iconLoader.getDensity(); + String path = iconLoader.getPath(); // look for a cached bitmap Bitmap bitmap = Bridge.getCachedBitmap(path, true /*isFramework*/); if (bitmap == null) { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java new file mode 100644 index 000000000000..9ab2e82f00c8 --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java @@ -0,0 +1,125 @@ +/* + * 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. + */ + +package com.android.layoutlib.bridge.bars; + +import com.android.resources.Density; +import com.android.resources.LayoutDirection; + +import java.io.InputStream; + +public class IconLoader { + + private final String mIconName; + private final Density mDesiredDensity; + private final int mPlatformVersion; + private final LayoutDirection mDirection; + + private Density mCurrentDensity; + private StringBuilder mCurrentPath; + + IconLoader(String iconName, Density density, int platformVersion, LayoutDirection direction) { + mIconName = iconName; + mDesiredDensity = density; + mPlatformVersion = platformVersion; + mDirection = direction; + // An upper bound on the length of the path for the icon: /bars/v21/ldrtl-xxxhdpi/ + final int iconPathLength = 24; + mCurrentPath = new StringBuilder(iconPathLength + iconName.length()); + } + + public InputStream getIcon() { + for (String resourceDir : Config.getResourceDirs(mPlatformVersion)) { + mCurrentDensity = null; + InputStream stream = getIcon(resourceDir); + if (stream != null) { + return stream; + } + } + return null; + } + + /** + * Should only be called after {@link #getIcon()}. Returns the density of the icon, if found by + * {@code getIcon()}. If no icon was found, then the return value has no meaning. + */ + public Density getDensity() { + return mCurrentDensity; + } + + /** + * Should only be called after {@link #getIcon()}. Returns the path to the icon, if found by + * {@code getIcon()}. If no icon was found, then the return value has no meaning. + */ + public String getPath() { + return mCurrentPath.toString(); + } + + /** + * Search for icon in the resource directory. This iterates over all densities. + * If a match is found, mCurrentDensity will be set to the icon's density. + */ + private InputStream getIcon(String resourceDir) { + // First check for the desired density. + InputStream stream = getIcon(resourceDir, mDesiredDensity); + if (stream != null) { + mCurrentDensity = mDesiredDensity; + return stream; + } + // Didn't find in the desired density. Search in all. + for (Density density : Density.values()) { + if (density == mDesiredDensity) { + // Skip the desired density since it's already been checked. + continue; + } + stream = getIcon(resourceDir, density); + if (stream != null) { + mCurrentDensity = density; + return stream; + } + } + return null; + } + + /** + * Returns the icon for given density present in the given resource directory, taking layout + * direction into consideration. + */ + private InputStream getIcon(String resourceDir, Density density) { + mCurrentPath.setLength(0); + // Currently we don't have any LTR only resources and hence the check is skipped. If they + // are ever added, change to: + // if (mDirection == LayoutDirection.RTL || mDirection == LayoutDirection.LTR) { + if (mDirection == LayoutDirection.RTL) { + mCurrentPath.append(resourceDir) + .append(mDirection.getResourceValue()) + .append('-') + .append(density.getResourceValue()) + .append('/') + .append(mIconName); + InputStream stream = getClass().getResourceAsStream(mCurrentPath.toString()); + if (stream != null) { + return stream; + } + mCurrentPath.setLength(0); + } + mCurrentPath.append(resourceDir) + .append(density.getResourceValue()) + .append('/') + .append(mIconName); + return getClass().getResourceAsStream(mCurrentPath.toString()); + } +} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java index 4cbdd4d2854c..1795db968802 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java @@ -42,7 +42,7 @@ public class StatusBar extends CustomBar { // We do know the order though. // 0 is the spacer loadIcon(1, "stat_sys_wifi_signal_4_fully.png", density); - loadIcon(2, "stat_sys_battery_charge_anim100.png", density); + loadIcon(2, "stat_sys_battery_100.png", density); } @Override |