diff options
158 files changed, 3016 insertions, 2121 deletions
diff --git a/api/current.txt b/api/current.txt index efadf77d6507..a543cbf6f669 100644 --- a/api/current.txt +++ b/api/current.txt @@ -865,6 +865,7 @@ package android {      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 persistable = 16843832; // 0x1010438      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 @@ -1821,46 +1822,50 @@ package android {      field public static final int TextAppearance_Medium = 16973892; // 0x1030044      field public static final int TextAppearance_Medium_Inverse = 16973893; // 0x1030045      field public static final int TextAppearance_Quantum = 16974346; // 0x103020a -    field public static final int TextAppearance_Quantum_Body1 = 16974534; // 0x10302c6 -    field public static final int TextAppearance_Quantum_Body2 = 16974533; // 0x10302c5 -    field public static final int TextAppearance_Quantum_Button = 16974537; // 0x10302c9 -    field public static final int TextAppearance_Quantum_Caption = 16974535; // 0x10302c7 +    field public static final int TextAppearance_Quantum_Body1 = 16974538; // 0x10302ca +    field public static final int TextAppearance_Quantum_Body2 = 16974537; // 0x10302c9 +    field public static final int TextAppearance_Quantum_Button = 16974541; // 0x10302cd +    field public static final int TextAppearance_Quantum_Caption = 16974539; // 0x10302cb      field public static final int TextAppearance_Quantum_DialogWindowTitle = 16974347; // 0x103020b -    field public static final int TextAppearance_Quantum_Display1 = 16974529; // 0x10302c1 -    field public static final int TextAppearance_Quantum_Display2 = 16974528; // 0x10302c0 -    field public static final int TextAppearance_Quantum_Display3 = 16974527; // 0x10302bf -    field public static final int TextAppearance_Quantum_Display4 = 16974526; // 0x10302be -    field public static final int TextAppearance_Quantum_Headline = 16974530; // 0x10302c2 +    field public static final int TextAppearance_Quantum_Display1 = 16974533; // 0x10302c5 +    field public static final int TextAppearance_Quantum_Display2 = 16974532; // 0x10302c4 +    field public static final int TextAppearance_Quantum_Display3 = 16974531; // 0x10302c3 +    field public static final int TextAppearance_Quantum_Display4 = 16974530; // 0x10302c2 +    field public static final int TextAppearance_Quantum_Headline = 16974534; // 0x10302c6      field public static final int TextAppearance_Quantum_Inverse = 16974348; // 0x103020c      field public static final int TextAppearance_Quantum_Large = 16974349; // 0x103020d      field public static final int TextAppearance_Quantum_Large_Inverse = 16974350; // 0x103020e      field public static final int TextAppearance_Quantum_Medium = 16974351; // 0x103020f      field public static final int TextAppearance_Quantum_Medium_Inverse = 16974352; // 0x1030210 -    field public static final int TextAppearance_Quantum_Menu = 16974536; // 0x10302c8 +    field public static final int TextAppearance_Quantum_Menu = 16974540; // 0x10302cc      field public static final int TextAppearance_Quantum_SearchResult_Subtitle = 16974353; // 0x1030211      field public static final int TextAppearance_Quantum_SearchResult_Title = 16974354; // 0x1030212      field public static final int TextAppearance_Quantum_Small = 16974355; // 0x1030213      field public static final int TextAppearance_Quantum_Small_Inverse = 16974356; // 0x1030214 -    field public static final int TextAppearance_Quantum_Subhead = 16974532; // 0x10302c4 -    field public static final int TextAppearance_Quantum_Title = 16974531; // 0x10302c3 +    field public static final int TextAppearance_Quantum_Subhead = 16974536; // 0x10302c8 +    field public static final int TextAppearance_Quantum_Title = 16974535; // 0x10302c7      field public static final int TextAppearance_Quantum_Widget = 16974358; // 0x1030216      field public static final int TextAppearance_Quantum_Widget_ActionBar_Menu = 16974359; // 0x1030217      field public static final int TextAppearance_Quantum_Widget_ActionBar_Subtitle = 16974360; // 0x1030218 -    field public static final int TextAppearance_Quantum_Widget_ActionBar_Title = 16974361; // 0x1030219 -    field public static final int TextAppearance_Quantum_Widget_ActionMode_Subtitle = 16974362; // 0x103021a -    field public static final int TextAppearance_Quantum_Widget_ActionMode_Title = 16974363; // 0x103021b -    field public static final int TextAppearance_Quantum_Widget_Button = 16974364; // 0x103021c -    field public static final int TextAppearance_Quantum_Widget_DropDownHint = 16974365; // 0x103021d -    field public static final int TextAppearance_Quantum_Widget_DropDownItem = 16974366; // 0x103021e -    field public static final int TextAppearance_Quantum_Widget_EditText = 16974367; // 0x103021f -    field public static final int TextAppearance_Quantum_Widget_IconMenu_Item = 16974368; // 0x1030220 -    field public static final int TextAppearance_Quantum_Widget_PopupMenu = 16974369; // 0x1030221 -    field public static final int TextAppearance_Quantum_Widget_PopupMenu_Large = 16974370; // 0x1030222 -    field public static final int TextAppearance_Quantum_Widget_PopupMenu_Small = 16974371; // 0x1030223 -    field public static final int TextAppearance_Quantum_Widget_TabWidget = 16974372; // 0x1030224 -    field public static final int TextAppearance_Quantum_Widget_TextView = 16974373; // 0x1030225 -    field public static final int TextAppearance_Quantum_Widget_TextView_PopupMenu = 16974374; // 0x1030226 -    field public static final int TextAppearance_Quantum_Widget_TextView_SpinnerItem = 16974375; // 0x1030227 +    field public static final int TextAppearance_Quantum_Widget_ActionBar_Subtitle_Inverse = 16974361; // 0x1030219 +    field public static final int TextAppearance_Quantum_Widget_ActionBar_Title = 16974362; // 0x103021a +    field public static final int TextAppearance_Quantum_Widget_ActionBar_Title_Inverse = 16974363; // 0x103021b +    field public static final int TextAppearance_Quantum_Widget_ActionMode_Subtitle = 16974364; // 0x103021c +    field public static final int TextAppearance_Quantum_Widget_ActionMode_Subtitle_Inverse = 16974365; // 0x103021d +    field public static final int TextAppearance_Quantum_Widget_ActionMode_Title = 16974366; // 0x103021e +    field public static final int TextAppearance_Quantum_Widget_ActionMode_Title_Inverse = 16974367; // 0x103021f +    field public static final int TextAppearance_Quantum_Widget_Button = 16974368; // 0x1030220 +    field public static final int TextAppearance_Quantum_Widget_DropDownHint = 16974369; // 0x1030221 +    field public static final int TextAppearance_Quantum_Widget_DropDownItem = 16974370; // 0x1030222 +    field public static final int TextAppearance_Quantum_Widget_EditText = 16974371; // 0x1030223 +    field public static final int TextAppearance_Quantum_Widget_IconMenu_Item = 16974372; // 0x1030224 +    field public static final int TextAppearance_Quantum_Widget_PopupMenu = 16974373; // 0x1030225 +    field public static final int TextAppearance_Quantum_Widget_PopupMenu_Large = 16974374; // 0x1030226 +    field public static final int TextAppearance_Quantum_Widget_PopupMenu_Small = 16974375; // 0x1030227 +    field public static final int TextAppearance_Quantum_Widget_TabWidget = 16974376; // 0x1030228 +    field public static final int TextAppearance_Quantum_Widget_TextView = 16974377; // 0x1030229 +    field public static final int TextAppearance_Quantum_Widget_TextView_PopupMenu = 16974378; // 0x103022a +    field public static final int TextAppearance_Quantum_Widget_TextView_SpinnerItem = 16974379; // 0x103022b      field public static final int TextAppearance_Quantum_WindowTitle = 16974357; // 0x1030215      field public static final int TextAppearance_Small = 16973894; // 0x1030046      field public static final int TextAppearance_Small_Inverse = 16973895; // 0x1030047 @@ -1956,34 +1961,34 @@ package android {      field public static final int Theme_NoTitleBar_Fullscreen = 16973831; // 0x1030007      field public static final int Theme_NoTitleBar_OverlayActionModes = 16973930; // 0x103006a      field public static final int Theme_Panel = 16973913; // 0x1030059 -    field public static final int Theme_Quantum = 16974376; // 0x1030228 -    field public static final int Theme_Quantum_Dialog = 16974377; // 0x1030229 -    field public static final int Theme_Quantum_DialogWhenLarge = 16974381; // 0x103022d -    field public static final int Theme_Quantum_DialogWhenLarge_NoActionBar = 16974382; // 0x103022e -    field public static final int Theme_Quantum_Dialog_MinWidth = 16974378; // 0x103022a -    field public static final int Theme_Quantum_Dialog_NoActionBar = 16974379; // 0x103022b -    field public static final int Theme_Quantum_Dialog_NoActionBar_MinWidth = 16974380; // 0x103022c -    field public static final int Theme_Quantum_InputMethod = 16974383; // 0x103022f -    field public static final int Theme_Quantum_Light = 16974391; // 0x1030237 -    field public static final int Theme_Quantum_Light_DarkActionBar = 16974392; // 0x1030238 -    field public static final int Theme_Quantum_Light_Dialog = 16974393; // 0x1030239 -    field public static final int Theme_Quantum_Light_DialogWhenLarge = 16974397; // 0x103023d -    field public static final int Theme_Quantum_Light_DialogWhenLarge_NoActionBar = 16974398; // 0x103023e -    field public static final int Theme_Quantum_Light_Dialog_MinWidth = 16974394; // 0x103023a -    field public static final int Theme_Quantum_Light_Dialog_NoActionBar = 16974395; // 0x103023b -    field public static final int Theme_Quantum_Light_Dialog_NoActionBar_MinWidth = 16974396; // 0x103023c -    field public static final int Theme_Quantum_Light_NoActionBar = 16974399; // 0x103023f -    field public static final int Theme_Quantum_Light_NoActionBar_Fullscreen = 16974400; // 0x1030240 -    field public static final int Theme_Quantum_Light_NoActionBar_Overscan = 16974401; // 0x1030241 -    field public static final int Theme_Quantum_Light_NoActionBar_TranslucentDecor = 16974402; // 0x1030242 -    field public static final int Theme_Quantum_Light_Panel = 16974403; // 0x1030243 -    field public static final int Theme_Quantum_NoActionBar = 16974384; // 0x1030230 -    field public static final int Theme_Quantum_NoActionBar_Fullscreen = 16974385; // 0x1030231 -    field public static final int Theme_Quantum_NoActionBar_Overscan = 16974386; // 0x1030232 -    field public static final int Theme_Quantum_NoActionBar_TranslucentDecor = 16974387; // 0x1030233 -    field public static final int Theme_Quantum_Panel = 16974388; // 0x1030234 -    field public static final int Theme_Quantum_Wallpaper = 16974389; // 0x1030235 -    field public static final int Theme_Quantum_Wallpaper_NoTitleBar = 16974390; // 0x1030236 +    field public static final int Theme_Quantum = 16974380; // 0x103022c +    field public static final int Theme_Quantum_Dialog = 16974381; // 0x103022d +    field public static final int Theme_Quantum_DialogWhenLarge = 16974385; // 0x1030231 +    field public static final int Theme_Quantum_DialogWhenLarge_NoActionBar = 16974386; // 0x1030232 +    field public static final int Theme_Quantum_Dialog_MinWidth = 16974382; // 0x103022e +    field public static final int Theme_Quantum_Dialog_NoActionBar = 16974383; // 0x103022f +    field public static final int Theme_Quantum_Dialog_NoActionBar_MinWidth = 16974384; // 0x1030230 +    field public static final int Theme_Quantum_InputMethod = 16974387; // 0x1030233 +    field public static final int Theme_Quantum_Light = 16974395; // 0x103023b +    field public static final int Theme_Quantum_Light_DarkActionBar = 16974396; // 0x103023c +    field public static final int Theme_Quantum_Light_Dialog = 16974397; // 0x103023d +    field public static final int Theme_Quantum_Light_DialogWhenLarge = 16974401; // 0x1030241 +    field public static final int Theme_Quantum_Light_DialogWhenLarge_NoActionBar = 16974402; // 0x1030242 +    field public static final int Theme_Quantum_Light_Dialog_MinWidth = 16974398; // 0x103023e +    field public static final int Theme_Quantum_Light_Dialog_NoActionBar = 16974399; // 0x103023f +    field public static final int Theme_Quantum_Light_Dialog_NoActionBar_MinWidth = 16974400; // 0x1030240 +    field public static final int Theme_Quantum_Light_NoActionBar = 16974403; // 0x1030243 +    field public static final int Theme_Quantum_Light_NoActionBar_Fullscreen = 16974404; // 0x1030244 +    field public static final int Theme_Quantum_Light_NoActionBar_Overscan = 16974405; // 0x1030245 +    field public static final int Theme_Quantum_Light_NoActionBar_TranslucentDecor = 16974406; // 0x1030246 +    field public static final int Theme_Quantum_Light_Panel = 16974407; // 0x1030247 +    field public static final int Theme_Quantum_NoActionBar = 16974388; // 0x1030234 +    field public static final int Theme_Quantum_NoActionBar_Fullscreen = 16974389; // 0x1030235 +    field public static final int Theme_Quantum_NoActionBar_Overscan = 16974390; // 0x1030236 +    field public static final int Theme_Quantum_NoActionBar_TranslucentDecor = 16974391; // 0x1030237 +    field public static final int Theme_Quantum_Panel = 16974392; // 0x1030238 +    field public static final int Theme_Quantum_Wallpaper = 16974393; // 0x1030239 +    field public static final int Theme_Quantum_Wallpaper_NoTitleBar = 16974394; // 0x103023a      field public static final int Theme_Translucent = 16973839; // 0x103000f      field public static final int Theme_Translucent_NoTitleBar = 16973840; // 0x1030010      field public static final int Theme_Translucent_NoTitleBar_Fullscreen = 16973841; // 0x1030011 @@ -2187,7 +2192,7 @@ package android {      field public static final int Widget_Holo_Light_ActionMode_Inverse = 16974119; // 0x1030127      field public static final int Widget_Holo_Light_AutoCompleteTextView = 16974011; // 0x10300bb      field public static final int Widget_Holo_Light_Button = 16974006; // 0x10300b6 -    field public static final int Widget_Holo_Light_Button_Borderless = 16974538; // 0x10302ca +    field public static final int Widget_Holo_Light_Button_Borderless = 16974542; // 0x10302ce      field public static final int Widget_Holo_Light_Button_Borderless_Small = 16974107; // 0x103011b      field public static final int Widget_Holo_Light_Button_Inset = 16974008; // 0x10300b8      field public static final int Widget_Holo_Light_Button_Small = 16974007; // 0x10300b7 @@ -2272,128 +2277,128 @@ package android {      field public static final int Widget_ProgressBar_Large_Inverse = 16973916; // 0x103005c      field public static final int Widget_ProgressBar_Small = 16973854; // 0x103001e      field public static final int Widget_ProgressBar_Small_Inverse = 16973917; // 0x103005d -    field public static final int Widget_Quantum = 16974404; // 0x1030244 -    field public static final int Widget_Quantum_ActionBar = 16974405; // 0x1030245 -    field public static final int Widget_Quantum_ActionBar_Solid = 16974406; // 0x1030246 -    field public static final int Widget_Quantum_ActionBar_TabBar = 16974407; // 0x1030247 -    field public static final int Widget_Quantum_ActionBar_TabText = 16974408; // 0x1030248 -    field public static final int Widget_Quantum_ActionBar_TabView = 16974409; // 0x1030249 -    field public static final int Widget_Quantum_ActionButton = 16974410; // 0x103024a -    field public static final int Widget_Quantum_ActionButton_CloseMode = 16974411; // 0x103024b -    field public static final int Widget_Quantum_ActionButton_Overflow = 16974412; // 0x103024c -    field public static final int Widget_Quantum_ActionButton_TextButton = 16974413; // 0x103024d -    field public static final int Widget_Quantum_ActionMode = 16974414; // 0x103024e -    field public static final int Widget_Quantum_AutoCompleteTextView = 16974415; // 0x103024f -    field public static final int Widget_Quantum_Button = 16974416; // 0x1030250 -    field public static final int Widget_Quantum_ButtonBar = 16974422; // 0x1030256 -    field public static final int Widget_Quantum_ButtonBar_AlertDialog = 16974423; // 0x1030257 -    field public static final int Widget_Quantum_Button_Borderless = 16974417; // 0x1030251 -    field public static final int Widget_Quantum_Button_Borderless_Small = 16974418; // 0x1030252 -    field public static final int Widget_Quantum_Button_Inset = 16974419; // 0x1030253 -    field public static final int Widget_Quantum_Button_Paper = 16974522; // 0x10302ba -    field public static final int Widget_Quantum_Button_Paper_Color = 16974523; // 0x10302bb -    field public static final int Widget_Quantum_Button_Small = 16974420; // 0x1030254 -    field public static final int Widget_Quantum_Button_Toggle = 16974421; // 0x1030255 -    field public static final int Widget_Quantum_CalendarView = 16974424; // 0x1030258 -    field public static final int Widget_Quantum_CheckedTextView = 16974425; // 0x1030259 -    field public static final int Widget_Quantum_CompoundButton_CheckBox = 16974426; // 0x103025a -    field public static final int Widget_Quantum_CompoundButton_RadioButton = 16974427; // 0x103025b -    field public static final int Widget_Quantum_CompoundButton_Star = 16974428; // 0x103025c -    field public static final int Widget_Quantum_DatePicker = 16974429; // 0x103025d -    field public static final int Widget_Quantum_DropDownItem = 16974430; // 0x103025e -    field public static final int Widget_Quantum_DropDownItem_Spinner = 16974431; // 0x103025f -    field public static final int Widget_Quantum_EditText = 16974432; // 0x1030260 -    field public static final int Widget_Quantum_ExpandableListView = 16974433; // 0x1030261 -    field public static final int Widget_Quantum_FastScroll = 16974434; // 0x1030262 -    field public static final int Widget_Quantum_FragmentBreadCrumbs = 16974435; // 0x1030263 -    field public static final int Widget_Quantum_GridView = 16974436; // 0x1030264 -    field public static final int Widget_Quantum_HorizontalScrollView = 16974437; // 0x1030265 -    field public static final int Widget_Quantum_ImageButton = 16974438; // 0x1030266 -    field public static final int Widget_Quantum_Light = 16974463; // 0x103027f -    field public static final int Widget_Quantum_Light_ActionBar = 16974464; // 0x1030280 -    field public static final int Widget_Quantum_Light_ActionBar_Solid = 16974465; // 0x1030281 -    field public static final int Widget_Quantum_Light_ActionBar_TabBar = 16974466; // 0x1030282 -    field public static final int Widget_Quantum_Light_ActionBar_TabText = 16974467; // 0x1030283 -    field public static final int Widget_Quantum_Light_ActionBar_TabView = 16974468; // 0x1030284 -    field public static final int Widget_Quantum_Light_ActionButton = 16974469; // 0x1030285 -    field public static final int Widget_Quantum_Light_ActionButton_CloseMode = 16974470; // 0x1030286 -    field public static final int Widget_Quantum_Light_ActionButton_Overflow = 16974471; // 0x1030287 -    field public static final int Widget_Quantum_Light_ActionMode = 16974472; // 0x1030288 -    field public static final int Widget_Quantum_Light_AutoCompleteTextView = 16974473; // 0x1030289 -    field public static final int Widget_Quantum_Light_Button = 16974474; // 0x103028a -    field public static final int Widget_Quantum_Light_ButtonBar = 16974479; // 0x103028f -    field public static final int Widget_Quantum_Light_ButtonBar_AlertDialog = 16974480; // 0x1030290 -    field public static final int Widget_Quantum_Light_Button_Borderless_Small = 16974475; // 0x103028b -    field public static final int Widget_Quantum_Light_Button_Inset = 16974476; // 0x103028c -    field public static final int Widget_Quantum_Light_Button_Paper = 16974524; // 0x10302bc -    field public static final int Widget_Quantum_Light_Button_Paper_Color = 16974525; // 0x10302bd -    field public static final int Widget_Quantum_Light_Button_Small = 16974477; // 0x103028d -    field public static final int Widget_Quantum_Light_Button_Toggle = 16974478; // 0x103028e -    field public static final int Widget_Quantum_Light_CalendarView = 16974481; // 0x1030291 -    field public static final int Widget_Quantum_Light_CheckedTextView = 16974482; // 0x1030292 -    field public static final int Widget_Quantum_Light_CompoundButton_CheckBox = 16974483; // 0x1030293 -    field public static final int Widget_Quantum_Light_CompoundButton_RadioButton = 16974484; // 0x1030294 -    field public static final int Widget_Quantum_Light_CompoundButton_Star = 16974485; // 0x1030295 -    field public static final int Widget_Quantum_Light_DropDownItem = 16974486; // 0x1030296 -    field public static final int Widget_Quantum_Light_DropDownItem_Spinner = 16974487; // 0x1030297 -    field public static final int Widget_Quantum_Light_EditText = 16974488; // 0x1030298 -    field public static final int Widget_Quantum_Light_ExpandableListView = 16974489; // 0x1030299 -    field public static final int Widget_Quantum_Light_FastScroll = 16974490; // 0x103029a -    field public static final int Widget_Quantum_Light_FragmentBreadCrumbs = 16974491; // 0x103029b -    field public static final int Widget_Quantum_Light_GridView = 16974492; // 0x103029c -    field public static final int Widget_Quantum_Light_HorizontalScrollView = 16974493; // 0x103029d -    field public static final int Widget_Quantum_Light_ImageButton = 16974494; // 0x103029e -    field public static final int Widget_Quantum_Light_ListPopupWindow = 16974495; // 0x103029f -    field public static final int Widget_Quantum_Light_ListView = 16974496; // 0x10302a0 -    field public static final int Widget_Quantum_Light_ListView_DropDown = 16974497; // 0x10302a1 -    field public static final int Widget_Quantum_Light_MediaRouteButton = 16974498; // 0x10302a2 -    field public static final int Widget_Quantum_Light_PopupMenu = 16974499; // 0x10302a3 -    field public static final int Widget_Quantum_Light_PopupWindow = 16974500; // 0x10302a4 -    field public static final int Widget_Quantum_Light_ProgressBar = 16974501; // 0x10302a5 -    field public static final int Widget_Quantum_Light_ProgressBar_Horizontal = 16974502; // 0x10302a6 -    field public static final int Widget_Quantum_Light_ProgressBar_Inverse = 16974503; // 0x10302a7 -    field public static final int Widget_Quantum_Light_ProgressBar_Large = 16974504; // 0x10302a8 -    field public static final int Widget_Quantum_Light_ProgressBar_Large_Inverse = 16974505; // 0x10302a9 -    field public static final int Widget_Quantum_Light_ProgressBar_Small = 16974506; // 0x10302aa -    field public static final int Widget_Quantum_Light_ProgressBar_Small_Inverse = 16974507; // 0x10302ab -    field public static final int Widget_Quantum_Light_ProgressBar_Small_Title = 16974508; // 0x10302ac -    field public static final int Widget_Quantum_Light_RatingBar = 16974509; // 0x10302ad -    field public static final int Widget_Quantum_Light_RatingBar_Indicator = 16974510; // 0x10302ae -    field public static final int Widget_Quantum_Light_RatingBar_Small = 16974511; // 0x10302af -    field public static final int Widget_Quantum_Light_ScrollView = 16974512; // 0x10302b0 -    field public static final int Widget_Quantum_Light_SeekBar = 16974513; // 0x10302b1 -    field public static final int Widget_Quantum_Light_SegmentedButton = 16974514; // 0x10302b2 -    field public static final int Widget_Quantum_Light_Spinner = 16974515; // 0x10302b3 -    field public static final int Widget_Quantum_Light_Tab = 16974516; // 0x10302b4 -    field public static final int Widget_Quantum_Light_TabWidget = 16974517; // 0x10302b5 -    field public static final int Widget_Quantum_Light_TextView = 16974518; // 0x10302b6 -    field public static final int Widget_Quantum_Light_TextView_SpinnerItem = 16974519; // 0x10302b7 -    field public static final int Widget_Quantum_Light_WebTextView = 16974520; // 0x10302b8 -    field public static final int Widget_Quantum_Light_WebView = 16974521; // 0x10302b9 -    field public static final int Widget_Quantum_ListPopupWindow = 16974439; // 0x1030267 -    field public static final int Widget_Quantum_ListView = 16974440; // 0x1030268 -    field public static final int Widget_Quantum_ListView_DropDown = 16974441; // 0x1030269 -    field public static final int Widget_Quantum_MediaRouteButton = 16974442; // 0x103026a -    field public static final int Widget_Quantum_PopupMenu = 16974443; // 0x103026b -    field public static final int Widget_Quantum_PopupWindow = 16974444; // 0x103026c -    field public static final int Widget_Quantum_ProgressBar = 16974445; // 0x103026d -    field public static final int Widget_Quantum_ProgressBar_Horizontal = 16974446; // 0x103026e -    field public static final int Widget_Quantum_ProgressBar_Large = 16974447; // 0x103026f -    field public static final int Widget_Quantum_ProgressBar_Small = 16974448; // 0x1030270 -    field public static final int Widget_Quantum_ProgressBar_Small_Title = 16974449; // 0x1030271 -    field public static final int Widget_Quantum_RatingBar = 16974450; // 0x1030272 -    field public static final int Widget_Quantum_RatingBar_Indicator = 16974451; // 0x1030273 -    field public static final int Widget_Quantum_RatingBar_Small = 16974452; // 0x1030274 -    field public static final int Widget_Quantum_ScrollView = 16974453; // 0x1030275 -    field public static final int Widget_Quantum_SeekBar = 16974454; // 0x1030276 -    field public static final int Widget_Quantum_SegmentedButton = 16974455; // 0x1030277 -    field public static final int Widget_Quantum_Spinner = 16974456; // 0x1030278 -    field public static final int Widget_Quantum_Tab = 16974457; // 0x1030279 -    field public static final int Widget_Quantum_TabWidget = 16974458; // 0x103027a -    field public static final int Widget_Quantum_TextView = 16974459; // 0x103027b -    field public static final int Widget_Quantum_TextView_SpinnerItem = 16974460; // 0x103027c -    field public static final int Widget_Quantum_WebTextView = 16974461; // 0x103027d -    field public static final int Widget_Quantum_WebView = 16974462; // 0x103027e +    field public static final int Widget_Quantum = 16974408; // 0x1030248 +    field public static final int Widget_Quantum_ActionBar = 16974409; // 0x1030249 +    field public static final int Widget_Quantum_ActionBar_Solid = 16974410; // 0x103024a +    field public static final int Widget_Quantum_ActionBar_TabBar = 16974411; // 0x103024b +    field public static final int Widget_Quantum_ActionBar_TabText = 16974412; // 0x103024c +    field public static final int Widget_Quantum_ActionBar_TabView = 16974413; // 0x103024d +    field public static final int Widget_Quantum_ActionButton = 16974414; // 0x103024e +    field public static final int Widget_Quantum_ActionButton_CloseMode = 16974415; // 0x103024f +    field public static final int Widget_Quantum_ActionButton_Overflow = 16974416; // 0x1030250 +    field public static final int Widget_Quantum_ActionButton_TextButton = 16974417; // 0x1030251 +    field public static final int Widget_Quantum_ActionMode = 16974418; // 0x1030252 +    field public static final int Widget_Quantum_AutoCompleteTextView = 16974419; // 0x1030253 +    field public static final int Widget_Quantum_Button = 16974420; // 0x1030254 +    field public static final int Widget_Quantum_ButtonBar = 16974426; // 0x103025a +    field public static final int Widget_Quantum_ButtonBar_AlertDialog = 16974427; // 0x103025b +    field public static final int Widget_Quantum_Button_Borderless = 16974421; // 0x1030255 +    field public static final int Widget_Quantum_Button_Borderless_Small = 16974422; // 0x1030256 +    field public static final int Widget_Quantum_Button_Inset = 16974423; // 0x1030257 +    field public static final int Widget_Quantum_Button_Paper = 16974526; // 0x10302be +    field public static final int Widget_Quantum_Button_Paper_Color = 16974527; // 0x10302bf +    field public static final int Widget_Quantum_Button_Small = 16974424; // 0x1030258 +    field public static final int Widget_Quantum_Button_Toggle = 16974425; // 0x1030259 +    field public static final int Widget_Quantum_CalendarView = 16974428; // 0x103025c +    field public static final int Widget_Quantum_CheckedTextView = 16974429; // 0x103025d +    field public static final int Widget_Quantum_CompoundButton_CheckBox = 16974430; // 0x103025e +    field public static final int Widget_Quantum_CompoundButton_RadioButton = 16974431; // 0x103025f +    field public static final int Widget_Quantum_CompoundButton_Star = 16974432; // 0x1030260 +    field public static final int Widget_Quantum_DatePicker = 16974433; // 0x1030261 +    field public static final int Widget_Quantum_DropDownItem = 16974434; // 0x1030262 +    field public static final int Widget_Quantum_DropDownItem_Spinner = 16974435; // 0x1030263 +    field public static final int Widget_Quantum_EditText = 16974436; // 0x1030264 +    field public static final int Widget_Quantum_ExpandableListView = 16974437; // 0x1030265 +    field public static final int Widget_Quantum_FastScroll = 16974438; // 0x1030266 +    field public static final int Widget_Quantum_FragmentBreadCrumbs = 16974439; // 0x1030267 +    field public static final int Widget_Quantum_GridView = 16974440; // 0x1030268 +    field public static final int Widget_Quantum_HorizontalScrollView = 16974441; // 0x1030269 +    field public static final int Widget_Quantum_ImageButton = 16974442; // 0x103026a +    field public static final int Widget_Quantum_Light = 16974467; // 0x1030283 +    field public static final int Widget_Quantum_Light_ActionBar = 16974468; // 0x1030284 +    field public static final int Widget_Quantum_Light_ActionBar_Solid = 16974469; // 0x1030285 +    field public static final int Widget_Quantum_Light_ActionBar_TabBar = 16974470; // 0x1030286 +    field public static final int Widget_Quantum_Light_ActionBar_TabText = 16974471; // 0x1030287 +    field public static final int Widget_Quantum_Light_ActionBar_TabView = 16974472; // 0x1030288 +    field public static final int Widget_Quantum_Light_ActionButton = 16974473; // 0x1030289 +    field public static final int Widget_Quantum_Light_ActionButton_CloseMode = 16974474; // 0x103028a +    field public static final int Widget_Quantum_Light_ActionButton_Overflow = 16974475; // 0x103028b +    field public static final int Widget_Quantum_Light_ActionMode = 16974476; // 0x103028c +    field public static final int Widget_Quantum_Light_AutoCompleteTextView = 16974477; // 0x103028d +    field public static final int Widget_Quantum_Light_Button = 16974478; // 0x103028e +    field public static final int Widget_Quantum_Light_ButtonBar = 16974483; // 0x1030293 +    field public static final int Widget_Quantum_Light_ButtonBar_AlertDialog = 16974484; // 0x1030294 +    field public static final int Widget_Quantum_Light_Button_Borderless_Small = 16974479; // 0x103028f +    field public static final int Widget_Quantum_Light_Button_Inset = 16974480; // 0x1030290 +    field public static final int Widget_Quantum_Light_Button_Paper = 16974528; // 0x10302c0 +    field public static final int Widget_Quantum_Light_Button_Paper_Color = 16974529; // 0x10302c1 +    field public static final int Widget_Quantum_Light_Button_Small = 16974481; // 0x1030291 +    field public static final int Widget_Quantum_Light_Button_Toggle = 16974482; // 0x1030292 +    field public static final int Widget_Quantum_Light_CalendarView = 16974485; // 0x1030295 +    field public static final int Widget_Quantum_Light_CheckedTextView = 16974486; // 0x1030296 +    field public static final int Widget_Quantum_Light_CompoundButton_CheckBox = 16974487; // 0x1030297 +    field public static final int Widget_Quantum_Light_CompoundButton_RadioButton = 16974488; // 0x1030298 +    field public static final int Widget_Quantum_Light_CompoundButton_Star = 16974489; // 0x1030299 +    field public static final int Widget_Quantum_Light_DropDownItem = 16974490; // 0x103029a +    field public static final int Widget_Quantum_Light_DropDownItem_Spinner = 16974491; // 0x103029b +    field public static final int Widget_Quantum_Light_EditText = 16974492; // 0x103029c +    field public static final int Widget_Quantum_Light_ExpandableListView = 16974493; // 0x103029d +    field public static final int Widget_Quantum_Light_FastScroll = 16974494; // 0x103029e +    field public static final int Widget_Quantum_Light_FragmentBreadCrumbs = 16974495; // 0x103029f +    field public static final int Widget_Quantum_Light_GridView = 16974496; // 0x10302a0 +    field public static final int Widget_Quantum_Light_HorizontalScrollView = 16974497; // 0x10302a1 +    field public static final int Widget_Quantum_Light_ImageButton = 16974498; // 0x10302a2 +    field public static final int Widget_Quantum_Light_ListPopupWindow = 16974499; // 0x10302a3 +    field public static final int Widget_Quantum_Light_ListView = 16974500; // 0x10302a4 +    field public static final int Widget_Quantum_Light_ListView_DropDown = 16974501; // 0x10302a5 +    field public static final int Widget_Quantum_Light_MediaRouteButton = 16974502; // 0x10302a6 +    field public static final int Widget_Quantum_Light_PopupMenu = 16974503; // 0x10302a7 +    field public static final int Widget_Quantum_Light_PopupWindow = 16974504; // 0x10302a8 +    field public static final int Widget_Quantum_Light_ProgressBar = 16974505; // 0x10302a9 +    field public static final int Widget_Quantum_Light_ProgressBar_Horizontal = 16974506; // 0x10302aa +    field public static final int Widget_Quantum_Light_ProgressBar_Inverse = 16974507; // 0x10302ab +    field public static final int Widget_Quantum_Light_ProgressBar_Large = 16974508; // 0x10302ac +    field public static final int Widget_Quantum_Light_ProgressBar_Large_Inverse = 16974509; // 0x10302ad +    field public static final int Widget_Quantum_Light_ProgressBar_Small = 16974510; // 0x10302ae +    field public static final int Widget_Quantum_Light_ProgressBar_Small_Inverse = 16974511; // 0x10302af +    field public static final int Widget_Quantum_Light_ProgressBar_Small_Title = 16974512; // 0x10302b0 +    field public static final int Widget_Quantum_Light_RatingBar = 16974513; // 0x10302b1 +    field public static final int Widget_Quantum_Light_RatingBar_Indicator = 16974514; // 0x10302b2 +    field public static final int Widget_Quantum_Light_RatingBar_Small = 16974515; // 0x10302b3 +    field public static final int Widget_Quantum_Light_ScrollView = 16974516; // 0x10302b4 +    field public static final int Widget_Quantum_Light_SeekBar = 16974517; // 0x10302b5 +    field public static final int Widget_Quantum_Light_SegmentedButton = 16974518; // 0x10302b6 +    field public static final int Widget_Quantum_Light_Spinner = 16974519; // 0x10302b7 +    field public static final int Widget_Quantum_Light_Tab = 16974520; // 0x10302b8 +    field public static final int Widget_Quantum_Light_TabWidget = 16974521; // 0x10302b9 +    field public static final int Widget_Quantum_Light_TextView = 16974522; // 0x10302ba +    field public static final int Widget_Quantum_Light_TextView_SpinnerItem = 16974523; // 0x10302bb +    field public static final int Widget_Quantum_Light_WebTextView = 16974524; // 0x10302bc +    field public static final int Widget_Quantum_Light_WebView = 16974525; // 0x10302bd +    field public static final int Widget_Quantum_ListPopupWindow = 16974443; // 0x103026b +    field public static final int Widget_Quantum_ListView = 16974444; // 0x103026c +    field public static final int Widget_Quantum_ListView_DropDown = 16974445; // 0x103026d +    field public static final int Widget_Quantum_MediaRouteButton = 16974446; // 0x103026e +    field public static final int Widget_Quantum_PopupMenu = 16974447; // 0x103026f +    field public static final int Widget_Quantum_PopupWindow = 16974448; // 0x1030270 +    field public static final int Widget_Quantum_ProgressBar = 16974449; // 0x1030271 +    field public static final int Widget_Quantum_ProgressBar_Horizontal = 16974450; // 0x1030272 +    field public static final int Widget_Quantum_ProgressBar_Large = 16974451; // 0x1030273 +    field public static final int Widget_Quantum_ProgressBar_Small = 16974452; // 0x1030274 +    field public static final int Widget_Quantum_ProgressBar_Small_Title = 16974453; // 0x1030275 +    field public static final int Widget_Quantum_RatingBar = 16974454; // 0x1030276 +    field public static final int Widget_Quantum_RatingBar_Indicator = 16974455; // 0x1030277 +    field public static final int Widget_Quantum_RatingBar_Small = 16974456; // 0x1030278 +    field public static final int Widget_Quantum_ScrollView = 16974457; // 0x1030279 +    field public static final int Widget_Quantum_SeekBar = 16974458; // 0x103027a +    field public static final int Widget_Quantum_SegmentedButton = 16974459; // 0x103027b +    field public static final int Widget_Quantum_Spinner = 16974460; // 0x103027c +    field public static final int Widget_Quantum_Tab = 16974461; // 0x103027d +    field public static final int Widget_Quantum_TabWidget = 16974462; // 0x103027e +    field public static final int Widget_Quantum_TextView = 16974463; // 0x103027f +    field public static final int Widget_Quantum_TextView_SpinnerItem = 16974464; // 0x1030280 +    field public static final int Widget_Quantum_WebTextView = 16974465; // 0x1030281 +    field public static final int Widget_Quantum_WebView = 16974466; // 0x1030282      field public static final int Widget_RatingBar = 16973857; // 0x1030021      field public static final int Widget_ScrollView = 16973869; // 0x103002d      field public static final int Widget_SeekBar = 16973856; // 0x1030020 @@ -3258,6 +3263,7 @@ package android.app {      method public void reportFullyDrawn();      method public final boolean requestWindowFeature(int);      method public final void runOnUiThread(java.lang.Runnable); +    method public void setActivityLabelAndIcon(java.lang.CharSequence, android.graphics.Bitmap);      method public void setContentTransitionManager(android.transition.TransitionManager);      method public void setContentView(int);      method public void setContentView(android.view.View); @@ -3274,8 +3280,6 @@ package android.app {      method public final void setProgressBarIndeterminate(boolean);      method public final void setProgressBarIndeterminateVisibility(boolean);      method public final void setProgressBarVisibility(boolean); -    method public void setRecentsIcon(android.graphics.Bitmap); -    method public void setRecentsLabel(java.lang.CharSequence);      method public void setRequestedOrientation(int);      method public final void setResult(int);      method public final void setResult(int, android.content.Intent); @@ -12083,11 +12087,16 @@ package android.hardware.hdmi {      field public static final int MESSAGE_VENDOR_COMMAND_WITH_ID = 160; // 0xa0      field public static final int MESSAGE_VENDOR_REMOTE_BUTTON_DOWN = 138; // 0x8a      field public static final int MESSAGE_VENDOR_REMOTE_BUTTON_UP = 139; // 0x8b +    field public static final int POWER_STATUS_ON = 0; // 0x0 +    field public static final int POWER_STATUS_STANDBY = 1; // 0x1 +    field public static final int POWER_STATUS_UNKNOWN = -1; // 0xffffffff +    field public static final int POWER_TRANSIENT_TO_ON = 2; // 0x2 +    field public static final int POWER_TRANSIENT_TO_STANDBY = 3; // 0x3    }    public final class HdmiCecClient { +    method public boolean isTvOn();      method public void sendActiveSource(); -    method public void sendGiveDevicePowerStatus(int);      method public void sendImageViewOn();      method public void sendInactiveSource();      method public void sendTextViewOn(); diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp index 8d2b739fc301..bdbb08c94967 100644 --- a/cmds/app_process/app_main.cpp +++ b/cmds/app_process/app_main.cpp @@ -30,8 +30,9 @@ void app_usage()  class AppRuntime : public AndroidRuntime  {  public: -    AppRuntime() -        : mParentDir(NULL) +    AppRuntime(char* argBlockStart, const size_t argBlockLength) +        : AndroidRuntime(argBlockStart, argBlockLength) +        , mParentDir(NULL)          , mClassName(NULL)          , mClass(NULL)          , mArgC(0) @@ -125,29 +126,30 @@ public:  using namespace android; -/* - * sets argv0 to as much of newArgv0 as will fit - */ -static void setArgv0(const char *argv0, const char *newArgv0) -{ -    strlcpy(const_cast<char *>(argv0), newArgv0, strlen(argv0)); +static size_t computeArgBlockSize(int argc, char* const argv[]) { +    // TODO: This assumes that all arguments are allocated in +    // contiguous memory. There isn't any documented guarantee +    // that this is the case, but this is how the kernel does it +    // (see fs/exec.c). +    // +    // Also note that this is a constant for "normal" android apps. +    // Since they're forked from zygote, the size of their command line +    // is the size of the zygote command line. +    // +    // We change the process name of the process by over-writing +    // the start of the argument block (argv[0]) with the new name of +    // the process, so we'd mysteriously start getting truncated process +    // names if the zygote command line decreases in size. +    uintptr_t start = reinterpret_cast<uintptr_t>(argv[0]); +    uintptr_t end = reinterpret_cast<uintptr_t>(argv[argc - 1]); +    end += strlen(argv[argc - 1]); + +    return (end - start);  }  int main(int argc, char* const argv[])  { -    // These are global variables in ProcessState.cpp -    mArgC = argc; -    mArgV = argv; - -    mArgLen = 0; -    for (int i=0; i<argc; i++) { -        mArgLen += strlen(argv[i]) + 1; -    } -    mArgLen--; - -    AppRuntime runtime; -    const char* argv0 = argv[0]; - +    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));      // Process command line arguments      // ignore argv[0]      argc--; @@ -184,7 +186,7 @@ int main(int argc, char* const argv[])      }      if (niceName && *niceName) { -        setArgv0(argv0, niceName); +        runtime.setArgv0(niceName);          set_process_name(niceName);      } diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index e38bbb3e7770..20e7311b94d5 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -4701,42 +4701,31 @@ public class Activity extends ContextThemeWrapper      }      /** -     * Set a label to be used in the Recents task display. The activities of a task are traversed -     * in order from the topmost activity to the bottommost. As soon as one activity returns a -     * non-null Recents label the traversal is ended and that value will be used in -     * {@link ActivityManager.RecentTaskInfo#activityLabel} +     * Set a label and icon to be used in the Recents task display. When {@link +     * ActivityManager#getRecentTasks} is called, the activities of each task are +     * traversed in order from the topmost activity to the bottommost. As soon as one activity is +     * found with either a non-null label or a non-null icon set by this call the traversal is +     * ended. For each task those values will be returned in {@link +     * ActivityManager.RecentTaskInfo#activityLabel} and {@link +     * ActivityManager.RecentTaskInfo#activityIcon}.       *       * @see ActivityManager#getRecentTasks +     * @see ActivityManager.RecentTaskInfo       * -     * @param recentsLabel The label to use in the RecentTaskInfo. +     * @param activityLabel The label to use in the RecentTaskInfo. +     * @param activityIcon The Bitmap to use in the RecentTaskInfo.       */ -    public void setRecentsLabel(CharSequence recentsLabel) { -        try { -            ActivityManagerNative.getDefault().setRecentsLabel(mToken, recentsLabel); -        } catch (RemoteException e) { -        } -    } - -    /** -     * Set an icon to be used in the Recents task display. The activities of a task are traversed -     * in order from the topmost activity to the bottommost. As soon as one activity returns a -     * non-null Recents icon the traversal is ended and that value will be used in -     * {@link ActivityManager.RecentTaskInfo#activityIcon}. -     * -     * @see ActivityManager#getRecentTasks -     * -     * @param recentsIcon The Bitmap to use in the RecentTaskInfo. -     */ -    public void setRecentsIcon(Bitmap recentsIcon) { +    public void setActivityLabelAndIcon(CharSequence activityLabel, Bitmap activityIcon) {          final Bitmap scaledIcon; -        if (recentsIcon != null) { +        if (activityIcon != null) {              final int size = ActivityManager.getLauncherLargeIconSizeInner(this); -            scaledIcon = Bitmap.createScaledBitmap(recentsIcon, size, size, true); +            scaledIcon = Bitmap.createScaledBitmap(activityIcon, size, size, true);          } else {              scaledIcon = null;          }          try { -            ActivityManagerNative.getDefault().setRecentsIcon(mToken, scaledIcon); +            ActivityManagerNative.getDefault().setActivityLabelAndIcon(mToken, activityLabel, +                    scaledIcon);          } catch (RemoteException e) {          }      } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 9d6a340c8aca..c027e990ec86 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -516,14 +516,14 @@ public class ActivityManager {          public int userId;          /** -         * The label of the highest activity in the task stack to have set a label -         * {@link Activity#setRecentsLabel}. +         * The label of the highest activity in the task stack to have set a label using +         * {@link Activity#setActivityLabelAndIcon(CharSequence, android.graphics.Bitmap)}.           */          public CharSequence activityLabel;          /**           * The Bitmap icon of the highest activity in the task stack to set a Bitmap using -         * {@link Activity#setRecentsIcon}. +         * {@link Activity#setActivityLabelAndIcon(CharSequence, android.graphics.Bitmap)}.           */          public Bitmap activityIcon; @@ -563,11 +563,7 @@ public class ActivityManager {          public void readFromParcel(Parcel source) {              id = source.readInt();              persistentId = source.readInt(); -            if (source.readInt() != 0) { -                baseIntent = Intent.CREATOR.createFromParcel(source); -            } else { -                baseIntent = null; -            } +            baseIntent = source.readInt() > 0 ? Intent.CREATOR.createFromParcel(source) : null;              origActivity = ComponentName.readFromParcel(source);              description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);              activityLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 707a038f4f09..a37a35a1e754 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -2129,21 +2129,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM              return true;          } -        case SET_RECENTS_LABEL_TRANSACTION: { +        case SET_ACTIVITY_LABEL_ICON_TRANSACTION: {              data.enforceInterface(IActivityManager.descriptor);              IBinder token = data.readStrongBinder(); -            CharSequence recentsLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(data); -            setRecentsLabel(token, recentsLabel); -            reply.writeNoException(); -            return true; -        } - -        case SET_RECENTS_ICON_TRANSACTION: { -            data.enforceInterface(IActivityManager.descriptor); -            IBinder token = data.readStrongBinder(); -            Bitmap recentsIcon = data.readInt() != 0 +            CharSequence activityLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(data); +            Bitmap activityIcon = data.readInt() > 0                      ? Bitmap.CREATOR.createFromParcel(data) : null; -            setRecentsIcon(token, recentsIcon); +            setActivityLabelAndIcon(token, activityLabel, activityIcon);              reply.writeNoException();              return true;          } @@ -4918,32 +4910,22 @@ class ActivityManagerProxy implements IActivityManager          return isInLockTaskMode;      } -    public void setRecentsLabel(IBinder token, CharSequence recentsLabel) throws RemoteException -    { -        Parcel data = Parcel.obtain(); -        Parcel reply = Parcel.obtain(); -        data.writeInterfaceToken(IActivityManager.descriptor); -        data.writeStrongBinder(token); -        TextUtils.writeToParcel(recentsLabel, data, 0); -        mRemote.transact(SET_RECENTS_LABEL_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); -        reply.readException(); -        data.recycle(); -        reply.recycle(); -    } - -    public void setRecentsIcon(IBinder token, Bitmap recentsBitmap) throws RemoteException +    @Override +    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, +            Bitmap activityIcon) throws RemoteException      {          Parcel data = Parcel.obtain();          Parcel reply = Parcel.obtain();          data.writeInterfaceToken(IActivityManager.descriptor);          data.writeStrongBinder(token); -        if (recentsBitmap != null) { +        TextUtils.writeToParcel(activityLabel, data, 0); +        if (activityIcon != null) {              data.writeInt(1); -            recentsBitmap.writeToParcel(data, 0); +            activityIcon.writeToParcel(data, 0);          } else {              data.writeInt(0);          } -        mRemote.transact(SET_RECENTS_ICON_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY); +        mRemote.transact(SET_ACTIVITY_LABEL_ICON_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);          reply.readException();          data.recycle();          reply.recycle(); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index d1f94f072aa6..7149ab9d989e 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -468,7 +468,8 @@ class ContextImpl extends Context {                                          outerContext.getApplicationInfo().targetSdkVersion,                                          com.android.internal.R.style.Theme_Dialog,                                          com.android.internal.R.style.Theme_Holo_Dialog, -                                        com.android.internal.R.style.Theme_DeviceDefault_Dialog)), +                                        com.android.internal.R.style.Theme_DeviceDefault_Dialog, +                                        com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog)),                          ctx.mMainThread.getHandler());                  }}); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 3b568395dc50..f7416d6c6ca9 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -437,10 +437,8 @@ public interface IActivityManager extends IInterface {      public boolean isInLockTaskMode() throws RemoteException;      /** @hide */ -    public void setRecentsLabel(IBinder token, CharSequence recentsLabel) throws RemoteException; - -    /** @hide */ -    public void setRecentsIcon(IBinder token, Bitmap recentsBitmap) throws RemoteException; +    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, +            Bitmap activityBitmap) throws RemoteException;      /*       * Private non-Binder interfaces @@ -741,6 +739,5 @@ public interface IActivityManager extends IInterface {      int START_LOCK_TASK_BY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+214;      int STOP_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+215;      int IS_IN_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+216; -    int SET_RECENTS_LABEL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+217; -    int SET_RECENTS_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+218; +    int SET_ACTIVITY_LABEL_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+217;  } diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 40275d8fa0bf..9916476a12fe 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -189,6 +189,13 @@ public class ActivityInfo extends ComponentInfo       */      public static final int FLAG_IMMERSIVE = 0x0800;      /** +     * Bit in {@link #flags} indicating that this activity is to be persisted across +     * reboots for display in the Recents list. +     * {@link android.R.attr#persistable} +     * @hide +     */ +    public static final int FLAG_PERSISTABLE = 0x1000; +    /**       * @hide Bit in {@link #flags}: If set, this component will only be seen       * by the primary user.  Only works with broadcast receivers.  Set from the       * {@link android.R.attr#primaryUserOnly} attribute. diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index a89c507b1efc..4b5616f6583f 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -57,7 +57,6 @@ import java.util.Iterator;  import java.util.List;  import java.util.Map;  import java.util.Set; -import java.util.jar.JarEntry;  import java.util.jar.StrictJarFile;  import java.util.zip.ZipEntry; @@ -2448,6 +2447,11 @@ public class PackageParser {              a.info.flags |= ActivityInfo.FLAG_IMMERSIVE;          } +        if (sa.getBoolean( +                com.android.internal.R.styleable.AndroidManifestActivity_persistable, false)) { +            a.info.flags |= ActivityInfo.FLAG_PERSISTABLE; +        } +          if (!receiver) {              if (sa.getBoolean(                      com.android.internal.R.styleable.AndroidManifestActivity_hardwareAccelerated, diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 1955be353dfb..d6eafc6e4018 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -135,17 +135,31 @@ public class Resources {          sPreloadedDrawables[1] = new LongSparseArray<ConstantState>();      } -    /** @hide */ +    /** +     * Returns the most appropriate default theme for the specified target SDK version. +     * <ul> +     * <li>Below API 11: Gingerbread +     * <li>APIs 11 thru 14: Holo +     * <li>APIs 14 thru XX: Device default dark +     * <li>API XX and above: Device default light with dark action bar +     * </ul> +     * +     * @param curTheme The current theme, or 0 if not specified. +     * @param targetSdkVersion The target SDK version. +     * @return A theme resource identifier +     * @hide +     */      public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {          return selectSystemTheme(curTheme, targetSdkVersion,                  com.android.internal.R.style.Theme,                  com.android.internal.R.style.Theme_Holo, -                com.android.internal.R.style.Theme_DeviceDefault); +                com.android.internal.R.style.Theme_DeviceDefault, +                com.android.internal.R.style.Theme_DeviceDefault_Light_DarkActionBar);      } -     +      /** @hide */ -    public static int selectSystemTheme(int curTheme, int targetSdkVersion, -            int orig, int holo, int deviceDefault) { +    public static int selectSystemTheme(int curTheme, int targetSdkVersion, int orig, int holo, +            int dark, int deviceDefault) {          if (curTheme != 0) {              return curTheme;          } @@ -155,9 +169,12 @@ public class Resources {          if (targetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {              return holo;          } +        if (targetSdkVersion < Build.VERSION_CODES.CUR_DEVELOPMENT) { +            return dark; +        }          return deviceDefault;      } -     +      /**       * This exception is thrown by the resource APIs when a requested resource       * can not be found. diff --git a/core/java/android/hardware/hdmi/HdmiCec.java b/core/java/android/hardware/hdmi/HdmiCec.java index 38d9de41697b..8578a320b2f0 100644 --- a/core/java/android/hardware/hdmi/HdmiCec.java +++ b/core/java/android/hardware/hdmi/HdmiCec.java @@ -160,6 +160,12 @@ public final class HdmiCec {      public static final int MESSAGE_SET_EXTERNAL_TIMER = 0xA2;      public static final int MESSAGE_ABORT = 0xFF; +    public static final int POWER_STATUS_UNKNOWN = -1; +    public static final int POWER_STATUS_ON = 0; +    public static final int POWER_STATUS_STANDBY = 1; +    public static final int POWER_TRANSIENT_TO_ON = 2; +    public static final int POWER_TRANSIENT_TO_STANDBY = 3; +      private static final int[] ADDRESS_TO_TYPE = {          DEVICE_TV,  // ADDR_TV          DEVICE_RECORDER,  // ADDR_RECORDER_1 diff --git a/core/java/android/hardware/hdmi/HdmiCecClient.java b/core/java/android/hardware/hdmi/HdmiCecClient.java index d7f4a72c6eb8..1f382e6c73ec 100644 --- a/core/java/android/hardware/hdmi/HdmiCecClient.java +++ b/core/java/android/hardware/hdmi/HdmiCecClient.java @@ -110,16 +110,20 @@ public final class HdmiCecClient {      }      /** -     * Send <GiveDevicePowerStatus> message. +     * Returns true if the TV or attached display is powered on. +     * <p> +     * The result of this method is only meaningful on playback devices (where the device +     * type is {@link HdmiCec#DEVICE_PLAYBACK}). +     * </p>       * -     * @param address logical address of the device to send the message to, such as -     *        {@link HdmiCec#ADDR_TV}. +     * @return true if TV is on; otherwise false.       */ -    public void sendGiveDevicePowerStatus(int address) { +    public boolean isTvOn() {          try { -            mService.sendGiveDevicePowerStatus(mBinder, address); +            return mService.isTvOn(mBinder);          } catch (RemoteException e) { -            Log.e(TAG, "sendGiveDevicePowerStatus threw exception ", e); +            Log.e(TAG, "isTvOn threw exception ", e);          } +        return false;      }  } diff --git a/core/java/android/hardware/hdmi/HdmiCecManager.java b/core/java/android/hardware/hdmi/HdmiCecManager.java index 575785d351f5..10b058ca2ec9 100644 --- a/core/java/android/hardware/hdmi/HdmiCecManager.java +++ b/core/java/android/hardware/hdmi/HdmiCecManager.java @@ -45,6 +45,9 @@ public final class HdmiCecManager {       * @return {@link HdmiCecClient} instance. {@code null} on failure.       */      public HdmiCecClient getClient(int type, HdmiCecClient.Listener listener) { +        if (mService == null) { +            return null; +        }          try {              IBinder b = mService.allocateLogicalDevice(type, getListenerWrapper(listener));              return HdmiCecClient.create(mService, b); diff --git a/core/java/android/hardware/hdmi/IHdmiCecService.aidl b/core/java/android/hardware/hdmi/IHdmiCecService.aidl index 6fefcf8652cd..b5df13171095 100644 --- a/core/java/android/hardware/hdmi/IHdmiCecService.aidl +++ b/core/java/android/hardware/hdmi/IHdmiCecService.aidl @@ -29,12 +29,11 @@ import android.os.IBinder;  interface IHdmiCecService {      IBinder allocateLogicalDevice(int type, IHdmiCecListener listener);      void removeServiceListener(IBinder b, IHdmiCecListener listener); -    void setOsdName(IBinder b, String name);      void sendActiveSource(IBinder b);      void sendInactiveSource(IBinder b);      void sendImageViewOn(IBinder b);      void sendTextViewOn(IBinder b); -    void sendGiveDevicePowerStatus(IBinder b, int address); +    boolean isTvOn(IBinder b);      void sendMessage(IBinder b, in HdmiCecMessage message);  } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 81ad28bba41d..a355d1e6927f 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -647,6 +647,7 @@ public class InputMethodService extends AbstractInputMethodService {                  getApplicationInfo().targetSdkVersion,                  android.R.style.Theme_InputMethod,                  android.R.style.Theme_Holo_InputMethod, +                android.R.style.Theme_DeviceDefault_InputMethod,                  android.R.style.Theme_DeviceDefault_InputMethod);          super.setTheme(mTheme);          super.onCreate(); diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java index d8e8e2c2de60..377ed88997b3 100644 --- a/core/java/android/net/nsd/NsdManager.java +++ b/core/java/android/net/nsd/NsdManager.java @@ -211,6 +211,7 @@ public final class NsdManager {      private Context mContext;      private static final int INVALID_LISTENER_KEY = 0; +    private static final int BUSY_LISTENER_KEY = -1;      private int mListenerKey = 1;      private final SparseArray mListenerMap = new SparseArray();      private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<NsdServiceInfo>(); @@ -317,71 +318,74 @@ public final class NsdManager {                  Log.d(TAG, "Stale key " + message.arg2);                  return;              } -            boolean listenerRemove = true;              NsdServiceInfo ns = getNsdService(message.arg2);              switch (message.what) {                  case DISCOVER_SERVICES_STARTED:                      String s = getNsdServiceInfoType((NsdServiceInfo) message.obj);                      ((DiscoveryListener) listener).onDiscoveryStarted(s); -                    // Keep listener until stop discovery -                    listenerRemove = false;                      break;                  case DISCOVER_SERVICES_FAILED: +                    removeListener(message.arg2);                      ((DiscoveryListener) listener).onStartDiscoveryFailed(getNsdServiceInfoType(ns),                              message.arg1);                      break;                  case SERVICE_FOUND:                      ((DiscoveryListener) listener).onServiceFound((NsdServiceInfo) message.obj); -                    // Keep listener until stop discovery -                    listenerRemove = false;                      break;                  case SERVICE_LOST:                      ((DiscoveryListener) listener).onServiceLost((NsdServiceInfo) message.obj); -                    // Keep listener until stop discovery -                    listenerRemove = false;                      break;                  case STOP_DISCOVERY_FAILED: +                    removeListener(message.arg2);                      ((DiscoveryListener) listener).onStopDiscoveryFailed(getNsdServiceInfoType(ns),                              message.arg1);                      break;                  case STOP_DISCOVERY_SUCCEEDED: +                    removeListener(message.arg2);                      ((DiscoveryListener) listener).onDiscoveryStopped(getNsdServiceInfoType(ns));                      break;                  case REGISTER_SERVICE_FAILED: +                    removeListener(message.arg2);                      ((RegistrationListener) listener).onRegistrationFailed(ns, message.arg1);                      break;                  case REGISTER_SERVICE_SUCCEEDED:                      ((RegistrationListener) listener).onServiceRegistered(                              (NsdServiceInfo) message.obj); -                    // Keep listener until unregister -                    listenerRemove = false;                      break;                  case UNREGISTER_SERVICE_FAILED: +                    removeListener(message.arg2);                      ((RegistrationListener) listener).onUnregistrationFailed(ns, message.arg1);                      break;                  case UNREGISTER_SERVICE_SUCCEEDED: +                    removeListener(message.arg2);                      ((RegistrationListener) listener).onServiceUnregistered(ns);                      break;                  case RESOLVE_SERVICE_FAILED: +                    removeListener(message.arg2);                      ((ResolveListener) listener).onResolveFailed(ns, message.arg1);                      break;                  case RESOLVE_SERVICE_SUCCEEDED: +                    removeListener(message.arg2);                      ((ResolveListener) listener).onServiceResolved((NsdServiceInfo) message.obj);                      break;                  default:                      Log.d(TAG, "Ignored " + message);                      break;              } -            if (listenerRemove) { -                removeListener(message.arg2); -            }          }      } +    // if the listener is already in the map, reject it.  Otherwise, add it and +    // return its key. +      private int putListener(Object listener, NsdServiceInfo s) {          if (listener == null) return INVALID_LISTENER_KEY;          int key;          synchronized (mMapLock) { +            int valueIndex = mListenerMap.indexOfValue(listener); +            if (valueIndex != -1) { +                return BUSY_LISTENER_KEY; +            }              do {                  key = mListenerKey++;              } while (key == INVALID_LISTENER_KEY); @@ -422,7 +426,6 @@ public final class NsdManager {          return INVALID_LISTENER_KEY;      } -      private String getNsdServiceInfoType(NsdServiceInfo s) {          if (s == null) return "?";          return s.getServiceType(); @@ -449,14 +452,18 @@ public final class NsdManager {       * Register a service to be discovered by other services.       *       * <p> The function call immediately returns after sending a request to register service -     * to the framework. The application is notified of a success to initiate -     * discovery through the callback {@link RegistrationListener#onServiceRegistered} or a failure +     * to the framework. The application is notified of a successful registration +     * through the callback {@link RegistrationListener#onServiceRegistered} or a failure       * through {@link RegistrationListener#onRegistrationFailed}.       * +     * <p> The application should call {@link #unregisterService} when the service +     * registration is no longer required, and/or whenever the application is stopped. +     *       * @param serviceInfo The service being registered       * @param protocolType The service discovery protocol       * @param listener The listener notifies of a successful registration and is used to       * unregister this service through a call on {@link #unregisterService}. Cannot be null. +     * Cannot be in use for an active service registration.       */      public void registerService(NsdServiceInfo serviceInfo, int protocolType,              RegistrationListener listener) { @@ -473,8 +480,11 @@ public final class NsdManager {          if (protocolType != PROTOCOL_DNS_SD) {              throw new IllegalArgumentException("Unsupported protocol");          } -        mAsyncChannel.sendMessage(REGISTER_SERVICE, 0, putListener(listener, serviceInfo), -                serviceInfo); +        int key = putListener(listener, serviceInfo); +        if (key == BUSY_LISTENER_KEY) { +            throw new IllegalArgumentException("listener already in use"); +        } +        mAsyncChannel.sendMessage(REGISTER_SERVICE, 0, key, serviceInfo);      }      /** @@ -484,7 +494,11 @@ public final class NsdManager {       *       * @param listener This should be the listener object that was passed to       * {@link #registerService}. It identifies the service that should be unregistered -     * and notifies of a successful unregistration. +     * and notifies of a successful or unsuccessful unregistration via the listener +     * callbacks.  In API versions 20 and above, the listener object may be used for +     * another service registration once the callback has been called.  In API versions <= 19, +     * there is no entirely reliable way to know when a listener may be re-used, and a new +     * listener should be created for each service registration request.       */      public void unregisterService(RegistrationListener listener) {          int id = getListenerKey(listener); @@ -514,12 +528,16 @@ public final class NsdManager {       * <p> Upon failure to start, service discovery is not active and application does       * not need to invoke {@link #stopServiceDiscovery}       * +     * <p> The application should call {@link #stopServiceDiscovery} when discovery of this +     * service type is no longer required, and/or whenever the application is paused or +     * stopped. +     *       * @param serviceType The service type being discovered. Examples include "_http._tcp" for       * http services or "_ipp._tcp" for printers       * @param protocolType The service discovery protocol       * @param listener  The listener notifies of a successful discovery and is used       * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}. -     * Cannot be null. +     * Cannot be null. Cannot be in use for an active service discovery.       */      public void discoverServices(String serviceType, int protocolType, DiscoveryListener listener) {          if (listener == null) { @@ -535,11 +553,17 @@ public final class NsdManager {          NsdServiceInfo s = new NsdServiceInfo();          s.setServiceType(serviceType); -        mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, putListener(listener, s), s); + +        int key = putListener(listener, s); +        if (key == BUSY_LISTENER_KEY) { +            throw new IllegalArgumentException("listener already in use"); +        } + +        mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, key, s);      }      /** -     * Stop service discovery initiated with {@link #discoverServices}. An active service +     * Stop service discovery initiated with {@link #discoverServices}.  An active service       * discovery is notified to the application with {@link DiscoveryListener#onDiscoveryStarted}       * and it stays active until the application invokes a stop service discovery. A successful       * stop is notified to with a call to {@link DiscoveryListener#onDiscoveryStopped}. @@ -548,7 +572,11 @@ public final class NsdManager {       * {@link DiscoveryListener#onStopDiscoveryFailed}.       *       * @param listener This should be the listener object that was passed to {@link #discoverServices}. -     * It identifies the discovery that should be stopped and notifies of a successful stop. +     * It identifies the discovery that should be stopped and notifies of a successful or +     * unsuccessful stop.  In API versions 20 and above, the listener object may be used for +     * another service discovery once the callback has been called.  In API versions <= 19, +     * there is no entirely reliable way to know when a listener may be re-used, and a new +     * listener should be created for each service discovery request.       */      public void stopServiceDiscovery(DiscoveryListener listener) {          int id = getListenerKey(listener); @@ -568,6 +596,7 @@ public final class NsdManager {       *       * @param serviceInfo service to be resolved       * @param listener to receive callback upon success or failure. Cannot be null. +     * Cannot be in use for an active service resolution.       */      public void resolveService(NsdServiceInfo serviceInfo, ResolveListener listener) {          if (TextUtils.isEmpty(serviceInfo.getServiceName()) || @@ -577,8 +606,13 @@ public final class NsdManager {          if (listener == null) {              throw new IllegalArgumentException("listener cannot be null");          } -        mAsyncChannel.sendMessage(RESOLVE_SERVICE, 0, putListener(listener, serviceInfo), -                serviceInfo); + +        int key = putListener(listener, serviceInfo); + +        if (key == BUSY_LISTENER_KEY) { +            throw new IllegalArgumentException("listener already in use"); +        } +        mAsyncChannel.sendMessage(RESOLVE_SERVICE, 0, key, serviceInfo);      }      /** Internal use only @hide */ diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 41808603356c..2ef5b6605b9e 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -713,15 +713,46 @@ public interface IMountService extends IInterface {              public void clearPassword() throws RemoteException {                  Parcel _data = Parcel.obtain();                  Parcel _reply = Parcel.obtain(); +                try { +                    _data.writeInterfaceToken(DESCRIPTOR); +                    mRemote.transact(Stub.TRANSACTION_clearPassword, _data, _reply, IBinder.FLAG_ONEWAY); +                    _reply.readException(); +                } finally { +                    _reply.recycle(); +                    _data.recycle(); +                } +            } + +            public void setField(String field, String data) throws RemoteException { +                Parcel _data = Parcel.obtain(); +                Parcel _reply = Parcel.obtain(); +                try { +                    _data.writeInterfaceToken(DESCRIPTOR); +                    _data.writeString(field); +                    _data.writeString(data); +                    mRemote.transact(Stub.TRANSACTION_setField, _data, _reply, IBinder.FLAG_ONEWAY); +                    _reply.readException(); +                } finally { +                    _reply.recycle(); +                    _data.recycle(); +                } +            } + +            public String getField(String field) throws RemoteException { +                Parcel _data = Parcel.obtain(); +                Parcel _reply = Parcel.obtain();                  String _result;                  try {                      _data.writeInterfaceToken(DESCRIPTOR); -                    mRemote.transact(Stub.TRANSACTION_clearPassword, _data, _reply, 0); +                    _data.writeString(field); +                    mRemote.transact(Stub.TRANSACTION_getField, _data, _reply, 0);                      _reply.readException(); +                    _result = _reply.readString();                  } finally {                      _reply.recycle();                      _data.recycle();                  } +                return _result;              }              public StorageVolume[] getVolumeList() throws RemoteException { @@ -882,6 +913,10 @@ public interface IMountService extends IInterface {          static final int TRANSACTION_clearPassword = IBinder.FIRST_CALL_TRANSACTION + 37; +        static final int TRANSACTION_setField = IBinder.FIRST_CALL_TRANSACTION + 38; + +        static final int TRANSACTION_getField = IBinder.FIRST_CALL_TRANSACTION + 39; +          /**           * Cast an IBinder object into an IMountService interface, generating a           * proxy if needed. @@ -1255,6 +1290,22 @@ public interface IMountService extends IInterface {                      reply.writeNoException();                      return true;                  } +                case TRANSACTION_setField: { +                    data.enforceInterface(DESCRIPTOR); +                    String field = data.readString(); +                    String contents = data.readString(); +                    setField(field, contents); +                    reply.writeNoException(); +                    return true; +                } +                case TRANSACTION_getField: { +                    data.enforceInterface(DESCRIPTOR); +                    String field = data.readString(); +                    String contents = getField(field); +                    reply.writeNoException(); +                    reply.writeString(contents); +                    return true; +                }              }              return super.onTransact(code, data, reply, flags);          } @@ -1504,4 +1555,18 @@ public interface IMountService extends IInterface {       * Securely clear password from vold       */      public void clearPassword() throws RemoteException; + +    /** +     * Set a field in the crypto header. +     * @param field field to set +     * @param contents contents to set in field +     */ +    public void setField(String field, String contents) throws RemoteException; + +    /** +     * Gets a field from the crypto header. +     * @param field field to get +     * @return contents of field +     */ +    public String getField(String field) throws RemoteException;  } diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 7647c2258270..de9eeff0be2d 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -153,11 +153,11 @@ public class DreamService extends Service implements Window.Callback {      private final Handler mHandler = new Handler();      private IBinder mWindowToken;      private Window mWindow; -    private WindowManager mWindowManager; -    private boolean mInteractive = false; +    private boolean mInteractive;      private boolean mLowProfile = true; -    private boolean mFullscreen = false; +    private boolean mFullscreen;      private boolean mScreenBright = true; +    private boolean mStarted;      private boolean mFinished;      private boolean mCanDoze;      private boolean mDozing; @@ -340,7 +340,7 @@ public class DreamService extends Service implements Window.Callback {       * @return The current window manager, or null if the dream is not started.       */      public WindowManager getWindowManager() { -        return mWindowManager; +        return mWindow != null ? mWindow.getWindowManager() : null;      }      /** @@ -623,7 +623,7 @@ public class DreamService extends Service implements Window.Callback {       * @hide experimental       */      public DozeHardware getDozeHardware() { -        if (mCanDoze && mDozeHardware == null) { +        if (mCanDoze && mDozeHardware == null && mWindowToken != null) {              try {                  IDozeHardware hardware = mSandman.getDozeHardware(mWindowToken);                  if (hardware != null) { @@ -701,24 +701,25 @@ public class DreamService extends Service implements Window.Callback {       * Must run on mHandler.       */      private final void detach() { -        if (mWindow == null) { -            // already detached! -            return; +        if (mStarted) { +            if (mDebug) Slog.v(TAG, "detach(): Calling onDreamingStopped()"); +            mStarted = false; +            onDreamingStopped();          } -        if (mDebug) Slog.v(TAG, "detach(): Calling onDreamingStopped()"); -        onDreamingStopped(); - -        if (mDebug) Slog.v(TAG, "detach(): Removing window from window manager"); - -        // force our window to be removed synchronously -        mWindowManager.removeViewImmediate(mWindow.getDecorView()); -        // the following will print a log message if it finds any other leaked windows -        WindowManagerGlobal.getInstance().closeAll(mWindowToken, -                this.getClass().getName(), "Dream"); +        if (mWindow != null) { +            // force our window to be removed synchronously +            if (mDebug) Slog.v(TAG, "detach(): Removing window from window manager"); +            mWindow.getWindowManager().removeViewImmediate(mWindow.getDecorView()); +            mWindow = null; +        } -        mWindow = null; -        mWindowToken = null; +        if (mWindowToken != null) { +            // the following will print a log message if it finds any other leaked windows +            WindowManagerGlobal.getInstance().closeAll(mWindowToken, +                    this.getClass().getName(), "Dream"); +            mWindowToken = null; +        }      }      /** @@ -746,12 +747,13 @@ public class DreamService extends Service implements Window.Callback {          if (mDebug) Slog.v(TAG, "Attached on thread " + Thread.currentThread().getId());          mWindowToken = windowToken; +        mCanDoze = canDoze; +          mWindow = PolicyManager.makeNewWindow(this);          mWindow.setCallback(this);          mWindow.requestFeature(Window.FEATURE_NO_TITLE);          mWindow.setBackgroundDrawable(new ColorDrawable(0xFF000000));          mWindow.setFormat(PixelFormat.OPAQUE); -        mCanDoze = canDoze;          if (mDebug) Slog.v(TAG, String.format("Attaching window token: %s to window of type %s",                  windowToken, WindowManager.LayoutParams.TYPE_DREAM)); @@ -769,26 +771,28 @@ public class DreamService extends Service implements Window.Callback {                      | (mScreenBright ? WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON : 0)                      );          mWindow.setAttributes(lp); - -        if (mDebug) Slog.v(TAG, "Created and attached window: " + mWindow); -          mWindow.setWindowManager(null, windowToken, "dream", true); -        mWindowManager = mWindow.getWindowManager(); -        if (mDebug) Slog.v(TAG, "Window added on thread " + Thread.currentThread().getId());          applySystemUiVisibilityFlags(                  (mLowProfile ? View.SYSTEM_UI_FLAG_LOW_PROFILE : 0),                  View.SYSTEM_UI_FLAG_LOW_PROFILE); -        getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes()); + +        try { +            getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes()); +        } catch (WindowManager.BadTokenException ex) { +            // This can happen because the dream manager service will remove the token +            // immediately without necessarily waiting for the dream to start. +            // We should receive a finish message soon. +            Slog.i(TAG, "attach() called after window token already removed, dream will " +                    + "finish soon"); +            mWindow = null; +            return; +        }          // start it up -        mHandler.post(new Runnable() { -            @Override -            public void run() { -                if (mDebug) Slog.v(TAG, "Calling onDreamingStarted()"); -                onDreamingStarted(); -            } -        }); +        if (mDebug) Slog.v(TAG, "Calling onDreamingStarted()"); +        mStarted = true; +        onDreamingStarted();      }      private void safelyFinish() { @@ -831,7 +835,7 @@ public class DreamService extends Service implements Window.Callback {              WindowManager.LayoutParams lp = mWindow.getAttributes();              lp.flags = applyFlags(lp.flags, flags, mask);              mWindow.setAttributes(lp); -            mWindowManager.updateViewLayout(mWindow.getDecorView(), lp); +            mWindow.getWindowManager().updateViewLayout(mWindow.getDecorView(), lp);          }      } diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java index a27c313fcd40..26eaef816f5f 100644 --- a/core/java/android/view/RenderNode.java +++ b/core/java/android/view/RenderNode.java @@ -16,6 +16,7 @@  package android.view; +import android.annotation.NonNull;  import android.graphics.Matrix;  import android.graphics.Outline; @@ -196,18 +197,20 @@ public class RenderNode {      }      /** -     * Starts recording the display list. All operations performed on the -     * returned canvas are recorded and stored in this display list. +     * Starts recording a display list for the render node. All +     * operations performed on the returned canvas are recorded and +     * stored in this display list.       * -     * Calling this method will mark the display list invalid until -     * {@link #end()} is called. Only valid display lists can be replayed. +     * Calling this method will mark the render node invalid until +     * {@link #end(HardwareRenderer, HardwareCanvas)} is called. +     * Only valid render nodes can be replayed.       * -     * @param width The width of the display list's viewport -     * @param height The height of the display list's viewport +     * @param width The width of the recording viewport +     * @param height The height of the recording viewport       *       * @return A canvas to record drawing operations.       * -     * @see #end() +     * @see #end(HardwareRenderer, HardwareCanvas)       * @see #isValid()       */      public HardwareCanvas start(int width, int height) { @@ -284,7 +287,23 @@ public class RenderNode {      }      /////////////////////////////////////////////////////////////////////////// -    // DisplayList Property Setters +    // Matrix manipulation +    /////////////////////////////////////////////////////////////////////////// + +    public boolean hasIdentityMatrix() { +        return nHasIdentityMatrix(mNativeDisplayList); +    } + +    public void getMatrix(@NonNull Matrix outMatrix) { +        nGetTransformMatrix(mNativeDisplayList, outMatrix.native_instance); +    } + +    public void getInverseMatrix(@NonNull Matrix outMatrix) { +        nGetInverseTransformMatrix(mNativeDisplayList, outMatrix.native_instance); +    } + +    /////////////////////////////////////////////////////////////////////////// +    // RenderProperty Setters      ///////////////////////////////////////////////////////////////////////////      /** @@ -301,7 +320,7 @@ public class RenderNode {      }      /** -     * Set whether the display list should clip itself to its bounds. This property is controlled by +     * Set whether the Render node should clip itself to its bounds. This property is controlled by       * the view's parent.       *       * @param clipToBounds true if the display list should clip to its bounds @@ -312,9 +331,7 @@ public class RenderNode {      /**       * Sets whether the display list should be drawn immediately after the -     * closest ancestor display list where isolateZVolume is true. If the -     * display list itself satisfies this constraint, changing this attribute -     * has no effect on drawing order. +     * closest ancestor display list containing a projection receiver.       *       * @param shouldProject true if the display list should be projected onto a       *            containing volume. @@ -373,9 +390,6 @@ public class RenderNode {       * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)       *       * @param matrix A transform matrix to apply to this display list -     * -     * @see #getMatrix(android.graphics.Matrix) -     * @see #getMatrix()       */      public void setStaticMatrix(Matrix matrix) {          nSetStaticMatrix(mNativeDisplayList, matrix.native_instance); @@ -613,28 +627,6 @@ public class RenderNode {      }      /** -     * Sets all of the transform-related values of the display list -     * -     * @param alpha The alpha value of the display list -     * @param translationX The translationX value of the display list -     * @param translationY The translationY value of the display list -     * @param rotation The rotation value of the display list -     * @param rotationX The rotationX value of the display list -     * @param rotationY The rotationY value of the display list -     * @param scaleX The scaleX value of the display list -     * @param scaleY The scaleY value of the display list -     * -     * @hide -     */ -    public void setTransformationInfo(float alpha, -            float translationX, float translationY, float translationZ, -            float rotation, float rotationX, float rotationY, float scaleX, float scaleY) { -        nSetTransformationInfo(mNativeDisplayList, alpha, -                translationX, translationY, translationZ, -                rotation, rotationX, rotationY, scaleX, scaleY); -    } - -    /**       * Sets the pivot value for the display list on the X axis       *       * @param pivotX The pivot value of the display list on the X axis, in pixels @@ -676,6 +668,10 @@ public class RenderNode {          return nGetPivotY(mNativeDisplayList);      } +    public boolean isPivotExplicitlySet() { +        return nIsPivotExplicitlySet(mNativeDisplayList); +    } +      /**       * Sets the camera distance for the display list. Refer to       * {@link View#setCameraDistance(float)} for more information on how to @@ -842,6 +838,12 @@ public class RenderNode {      private static native void nDestroyDisplayList(long displayList);      private static native void nSetDisplayListName(long displayList, String name); +    // Matrix + +    private static native void nGetTransformMatrix(long displayList, long nativeMatrix); +    private static native void nGetInverseTransformMatrix(long displayList, long nativeMatrix); +    private static native boolean nHasIdentityMatrix(long displayList); +      // Properties      private static native void nOffsetTopAndBottom(long displayList, float offset); @@ -877,9 +879,6 @@ public class RenderNode {      private static native void nSetRotationY(long displayList, float rotationY);      private static native void nSetScaleX(long displayList, float scaleX);      private static native void nSetScaleY(long displayList, float scaleY); -    private static native void nSetTransformationInfo(long displayList, float alpha, -            float translationX, float translationY, float translationZ, -            float rotation, float rotationX, float rotationY, float scaleX, float scaleY);      private static native void nSetStaticMatrix(long displayList, long nativeMatrix);      private static native void nSetAnimationMatrix(long displayList, long animationMatrix); @@ -898,6 +897,7 @@ public class RenderNode {      private static native float nGetRotation(long displayList);      private static native float nGetRotationX(long displayList);      private static native float nGetRotationY(long displayList); +    private static native boolean nIsPivotExplicitlySet(long displayList);      private static native float nGetPivotX(long displayList);      private static native float nGetPivotY(long displayList);      private static native void nOutput(long displayList); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 5be469822375..6c414f654e6c 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -1792,12 +1792,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,      private static final int PFLAG_HOVERED             = 0x10000000;      /** -     * Indicates that pivotX or pivotY were explicitly set and we should not assume the center -     * for transform operations -     * -     * @hide +     * no longer needed, should be reused       */ -    private static final int PFLAG_PIVOT_EXPLICITLY_SET = 0x20000000; +    private static final int PFLAG_DOES_NOTHING_REUSE_PLEASE = 0x20000000;      /** {@hide} */      static final int PFLAG_ACTIVATED                   = 0x40000000; @@ -2930,123 +2927,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,      static class TransformationInfo {          /**           * The transform matrix for the View. This transform is calculated internally -         * based on the rotation, scaleX, and scaleY properties. The identity matrix -         * is used by default. Do *not* use this variable directly; instead call -         * getMatrix(), which will automatically recalculate the matrix if necessary -         * to get the correct matrix based on the latest rotation and scale properties. +         * based on the translation, rotation, and scale properties. +         * +         * Do *not* use this variable directly; instead call getMatrix(), which will +         * load the value from the View's RenderNode.           */          private final Matrix mMatrix = new Matrix();          /** -         * The transform matrix for the View. This transform is calculated internally -         * based on the rotation, scaleX, and scaleY properties. The identity matrix -         * is used by default. Do *not* use this variable directly; instead call -         * getInverseMatrix(), which will automatically recalculate the matrix if necessary -         * to get the correct matrix based on the latest rotation and scale properties. +         * The inverse transform matrix for the View. This transform is calculated +         * internally based on the translation, rotation, and scale properties. +         * +         * Do *not* use this variable directly; instead call getInverseMatrix(), +         * which will load the value from the View's RenderNode.           */          private Matrix mInverseMatrix;          /** -         * An internal variable that tracks whether we need to recalculate the -         * transform matrix, based on whether the rotation or scaleX/Y properties -         * have changed since the matrix was last calculated. -         */ -        boolean mMatrixDirty = false; - -        /** -         * An internal variable that tracks whether we need to recalculate the -         * transform matrix, based on whether the rotation or scaleX/Y properties -         * have changed since the matrix was last calculated. -         */ -        private boolean mInverseMatrixDirty = true; - -        /** -         * A variable that tracks whether we need to recalculate the -         * transform matrix, based on whether the rotation or scaleX/Y properties -         * have changed since the matrix was last calculated. This variable -         * is only valid after a call to updateMatrix() or to a function that -         * calls it such as getMatrix(), hasIdentityMatrix() and getInverseMatrix(). -         */ -        private boolean mMatrixIsIdentity = true; - -        /** -         * The Camera object is used to compute a 3D matrix when rotationX or rotationY are set. -         */ -        private Camera mCamera = null; - -        /** -         * This matrix is used when computing the matrix for 3D rotations. -         */ -        private Matrix matrix3D = null; - -        /** -         * These prev values are used to recalculate a centered pivot point when necessary. The -         * pivot point is only used in matrix operations (when rotation, scale, or translation are -         * set), so thes values are only used then as well. -         */ -        private int mPrevWidth = -1; -        private int mPrevHeight = -1; - -        /** -         * The degrees rotation around the vertical axis through the pivot point. -         */ -        @ViewDebug.ExportedProperty -        float mRotationY = 0f; - -        /** -         * The degrees rotation around the horizontal axis through the pivot point. -         */ -        @ViewDebug.ExportedProperty -        float mRotationX = 0f; - -        /** -         * The degrees rotation around the pivot point. -         */ -        @ViewDebug.ExportedProperty -        float mRotation = 0f; - -        /** -         * The amount of translation of the object away from its left property (post-layout). -         */ -        @ViewDebug.ExportedProperty -        float mTranslationX = 0f; - -        /** -         * The amount of translation of the object away from its top property (post-layout). -         */ -        @ViewDebug.ExportedProperty -        float mTranslationY = 0f; - -        @ViewDebug.ExportedProperty -        float mTranslationZ = 0f; - -        /** -         * The amount of scale in the x direction around the pivot point. A -         * value of 1 means no scaling is applied. -         */ -        @ViewDebug.ExportedProperty -        float mScaleX = 1f; - -        /** -         * The amount of scale in the y direction around the pivot point. A -         * value of 1 means no scaling is applied. -         */ -        @ViewDebug.ExportedProperty -        float mScaleY = 1f; - -        /** -         * The x location of the point around which the view is rotated and scaled. -         */ -        @ViewDebug.ExportedProperty -        float mPivotX = 0f; - -        /** -         * The y location of the point around which the view is rotated and scaled. -         */ -        @ViewDebug.ExportedProperty -        float mPivotY = 0f; - -        /**           * The opacity of the View. This is a value from 0 to 1, where 0 means           * completely transparent and 1 means completely opaque.           */ @@ -3557,7 +3454,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * of the View content. Its DisplayList content is cleared on temporary detach and reset on       * cleanup.       */ -    RenderNode mRenderNode; +    final RenderNode mRenderNode;      /**       * Set to true when the view is sending hover accessibility events because it @@ -3608,6 +3505,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,          setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);          mUserPaddingStart = UNDEFINED_PADDING;          mUserPaddingEnd = UNDEFINED_PADDING; +        mRenderNode = RenderNode.create(getClass().getName());          if (!sCompatibilityDone && context != null) {              final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion; @@ -4172,6 +4070,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      View() {          mResources = null; +        mRenderNode = RenderNode.create(getClass().getName());      }      public String toString() { @@ -4847,10 +4746,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              final float x = r.exactCenterX();              final float y = r.exactCenterY(); -            mBackground.setHotspot(Drawable.HOTSPOT_FOCUS, x, y); +            mBackground.setHotspot(R.attr.state_focused, x, y);              if (!focused) { -                mBackground.removeHotspot(Drawable.HOTSPOT_FOCUS); +                mBackground.removeHotspot(R.attr.state_focused);              }          }      } @@ -9092,6 +8991,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,                          }                          removeTapCallback(); +                    } else { +                        clearHotspot(R.attr.state_pressed);                      }                      break; @@ -9204,6 +9105,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      private void removeUnsetPressCallback() {          if ((mPrivateFlags & PFLAG_PRESSED) != 0 && mUnsetPressedState != null) { +            clearHotspot(R.attr.state_pressed);              setPressed(false);              removeCallbacks(mUnsetPressedState);          } @@ -9682,21 +9584,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @return The current transform matrix for the view       */      public Matrix getMatrix() { -        if (mTransformationInfo != null) { -            updateMatrix(); -            return mTransformationInfo.mMatrix; -        } -        return Matrix.IDENTITY_MATRIX; -    } - -    /** -     * Utility function to determine if the value is far enough away from zero to be -     * considered non-zero. -     * @param value A floating point value to check for zero-ness -     * @return whether the passed-in value is far enough away from zero to be considered non-zero -     */ -    private static boolean nonzero(float value) { -        return (value < -NONZERO_EPSILON || value > NONZERO_EPSILON); +        ensureTransformationInfo(); +        final Matrix matrix = mTransformationInfo.mMatrix; +        mRenderNode.getMatrix(matrix); +        return matrix;      }      /** @@ -9706,11 +9597,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @return True if the transform matrix is the identity matrix, false otherwise.       */      final boolean hasIdentityMatrix() { -        if (mTransformationInfo != null) { -            updateMatrix(); -            return mTransformationInfo.mMatrixIsIdentity; -        } -        return true; +        return mRenderNode.hasIdentityMatrix();      }      void ensureTransformationInfo() { @@ -9719,59 +9606,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,          }      } -    void ensureRenderNode() { -        if (mRenderNode == null) { -            mRenderNode = RenderNode.create(getClass().getName()); -        } -    } - -    /** -     * Recomputes the transform matrix if necessary. -     */ -    private void updateMatrix() { -        final TransformationInfo info = mTransformationInfo; -        if (info == null) { -            return; -        } -        if (info.mMatrixDirty) { -            // transform-related properties have changed since the last time someone -            // asked for the matrix; recalculate it with the current values - -            // Figure out if we need to update the pivot point -            if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { -                if ((mRight - mLeft) != info.mPrevWidth || (mBottom - mTop) != info.mPrevHeight) { -                    info.mPrevWidth = mRight - mLeft; -                    info.mPrevHeight = mBottom - mTop; -                    info.mPivotX = info.mPrevWidth / 2f; -                    info.mPivotY = info.mPrevHeight / 2f; -                } -            } -            info.mMatrix.reset(); -            if (!nonzero(info.mRotationX) && !nonzero(info.mRotationY)) { -                info.mMatrix.setTranslate(info.mTranslationX, info.mTranslationY); -                info.mMatrix.preRotate(info.mRotation, info.mPivotX, info.mPivotY); -                info.mMatrix.preScale(info.mScaleX, info.mScaleY, info.mPivotX, info.mPivotY); -            } else { -                if (info.mCamera == null) { -                    info.mCamera = new Camera(); -                    info.matrix3D = new Matrix(); -                } -                info.mCamera.save(); -                info.mMatrix.preScale(info.mScaleX, info.mScaleY, info.mPivotX, info.mPivotY); -                info.mCamera.rotate(info.mRotationX, info.mRotationY, -info.mRotation); -                info.mCamera.getMatrix(info.matrix3D); -                info.matrix3D.preTranslate(-info.mPivotX, -info.mPivotY); -                info.matrix3D.postTranslate(info.mPivotX + info.mTranslationX, -                        info.mPivotY + info.mTranslationY); -                info.mMatrix.postConcat(info.matrix3D); -                info.mCamera.restore(); -            } -            info.mMatrixDirty = false; -            info.mMatrixIsIdentity = info.mMatrix.isIdentity(); -            info.mInverseMatrixDirty = true; -        } -    } -     /**       * Utility method to retrieve the inverse of the current mMatrix property.       * We cache the matrix to avoid recalculating it when transform properties @@ -9780,19 +9614,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @return The inverse of the current matrix of this view.       */      final Matrix getInverseMatrix() { -        final TransformationInfo info = mTransformationInfo; -        if (info != null) { -            updateMatrix(); -            if (info.mInverseMatrixDirty) { -                if (info.mInverseMatrix == null) { -                    info.mInverseMatrix = new Matrix(); -                } -                info.mMatrix.invert(info.mInverseMatrix); -                info.mInverseMatrixDirty = false; -            } -            return info.mInverseMatrix; +        ensureTransformationInfo(); +        if (mTransformationInfo.mInverseMatrix == null) { +            mTransformationInfo.mInverseMatrix = new Matrix();          } -        return Matrix.IDENTITY_MATRIX; +        final Matrix matrix = mTransformationInfo.mInverseMatrix; +        mRenderNode.getInverseMatrix(matrix); +        return matrix;      }      /** @@ -9803,14 +9631,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @return The distance along the Z axis.       */      public float getCameraDistance() { -        ensureTransformationInfo();          final float dpi = mResources.getDisplayMetrics().densityDpi; -        final TransformationInfo info = mTransformationInfo; -        if (info.mCamera == null) { -            info.mCamera = new Camera(); -            info.matrix3D = new Matrix(); -        } -        return -(info.mCamera.getLocationZ() * dpi); +        return -(mRenderNode.getCameraDistance() * dpi);      }      /** @@ -9853,27 +9675,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @see #setRotationY(float)       */      public void setCameraDistance(float distance) { -        invalidateViewProperty(true, false); - -        ensureTransformationInfo();          final float dpi = mResources.getDisplayMetrics().densityDpi; -        final TransformationInfo info = mTransformationInfo; -        if (info.mCamera == null) { -            info.mCamera = new Camera(); -            info.matrix3D = new Matrix(); -        } - -        info.mCamera.setLocation(0.0f, 0.0f, -Math.abs(distance) / dpi); -        info.mMatrixDirty = true; +        invalidateViewProperty(true, false); +        mRenderNode.setCameraDistance(-Math.abs(distance) / dpi);          invalidateViewProperty(false, false); -        if (mRenderNode != null) { -            mRenderNode.setCameraDistance(-Math.abs(distance) / dpi); -        } -        if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { -            // View was rejected last time it was drawn by its parent; this may have changed -            invalidateParentIfNeeded(); -        } + +        invalidateParentIfNeededAndWasQuickRejected();      }      /** @@ -9887,7 +9695,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getRotation() { -        return mTransformationInfo != null ? mTransformationInfo.mRotation : 0; +        return mRenderNode.getRotation();      }      /** @@ -9905,21 +9713,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @attr ref android.R.styleable#View_rotation       */      public void setRotation(float rotation) { -        ensureTransformationInfo(); -        final TransformationInfo info = mTransformationInfo; -        if (info.mRotation != rotation) { +        if (rotation != getRotation()) {              // Double-invalidation is necessary to capture view's old and new areas              invalidateViewProperty(true, false); -            info.mRotation = rotation; -            info.mMatrixDirty = true; +            mRenderNode.setRotation(rotation);              invalidateViewProperty(false, true); -            if (mRenderNode != null) { -                mRenderNode.setRotation(rotation); -            } -            if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { -                // View was rejected last time it was drawn by its parent; this may have changed -                invalidateParentIfNeeded(); -            } + +            invalidateParentIfNeededAndWasQuickRejected();          }      } @@ -9934,7 +9734,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getRotationY() { -        return mTransformationInfo != null ? mTransformationInfo.mRotationY : 0; +        return mRenderNode.getRotationY();      }      /** @@ -9957,20 +9757,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @attr ref android.R.styleable#View_rotationY       */      public void setRotationY(float rotationY) { -        ensureTransformationInfo(); -        final TransformationInfo info = mTransformationInfo; -        if (info.mRotationY != rotationY) { +        if (rotationY != getRotationY()) {              invalidateViewProperty(true, false); -            info.mRotationY = rotationY; -            info.mMatrixDirty = true; +            mRenderNode.setRotationY(rotationY);              invalidateViewProperty(false, true); -            if (mRenderNode != null) { -                mRenderNode.setRotationY(rotationY); -            } -            if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { -                // View was rejected last time it was drawn by its parent; this may have changed -                invalidateParentIfNeeded(); -            } + +            invalidateParentIfNeededAndWasQuickRejected();          }      } @@ -9985,7 +9777,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getRotationX() { -        return mTransformationInfo != null ? mTransformationInfo.mRotationX : 0; +        return mRenderNode.getRotationX();      }      /** @@ -10008,20 +9800,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @attr ref android.R.styleable#View_rotationX       */      public void setRotationX(float rotationX) { -        ensureTransformationInfo(); -        final TransformationInfo info = mTransformationInfo; -        if (info.mRotationX != rotationX) { +        if (rotationX != getRotationX()) {              invalidateViewProperty(true, false); -            info.mRotationX = rotationX; -            info.mMatrixDirty = true; +            mRenderNode.setRotationX(rotationX);              invalidateViewProperty(false, true); -            if (mRenderNode != null) { -                mRenderNode.setRotationX(rotationX); -            } -            if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { -                // View was rejected last time it was drawn by its parent; this may have changed -                invalidateParentIfNeeded(); -            } + +            invalidateParentIfNeededAndWasQuickRejected();          }      } @@ -10037,7 +9821,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getScaleX() { -        return mTransformationInfo != null ? mTransformationInfo.mScaleX : 1; +        return mRenderNode.getScaleX();      }      /** @@ -10051,20 +9835,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @attr ref android.R.styleable#View_scaleX       */      public void setScaleX(float scaleX) { -        ensureTransformationInfo(); -        final TransformationInfo info = mTransformationInfo; -        if (info.mScaleX != scaleX) { +        if (scaleX != getScaleX()) {              invalidateViewProperty(true, false); -            info.mScaleX = scaleX; -            info.mMatrixDirty = true; +            mRenderNode.setScaleX(scaleX);              invalidateViewProperty(false, true); -            if (mRenderNode != null) { -                mRenderNode.setScaleX(scaleX); -            } -            if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { -                // View was rejected last time it was drawn by its parent; this may have changed -                invalidateParentIfNeeded(); -            } + +            invalidateParentIfNeededAndWasQuickRejected();          }      } @@ -10080,7 +9856,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getScaleY() { -        return mTransformationInfo != null ? mTransformationInfo.mScaleY : 1; +        return mRenderNode.getScaleY();      }      /** @@ -10094,20 +9870,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @attr ref android.R.styleable#View_scaleY       */      public void setScaleY(float scaleY) { -        ensureTransformationInfo(); -        final TransformationInfo info = mTransformationInfo; -        if (info.mScaleY != scaleY) { +        if (scaleY != getScaleY()) {              invalidateViewProperty(true, false); -            info.mScaleY = scaleY; -            info.mMatrixDirty = true; +            mRenderNode.setScaleY(scaleY);              invalidateViewProperty(false, true); -            if (mRenderNode != null) { -                mRenderNode.setScaleY(scaleY); -            } -            if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { -                // View was rejected last time it was drawn by its parent; this may have changed -                invalidateParentIfNeeded(); -            } + +            invalidateParentIfNeededAndWasQuickRejected();          }      } @@ -10125,7 +9893,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getPivotX() { -        return mTransformationInfo != null ? mTransformationInfo.mPivotX : 0; +        return mRenderNode.getPivotX();      }      /** @@ -10144,23 +9912,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @attr ref android.R.styleable#View_transformPivotX       */      public void setPivotX(float pivotX) { -        ensureTransformationInfo(); -        final TransformationInfo info = mTransformationInfo; -        boolean pivotSet = (mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == -                PFLAG_PIVOT_EXPLICITLY_SET; -        if (info.mPivotX != pivotX || !pivotSet) { -            mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET; +        if (mRenderNode.isPivotExplicitlySet() || pivotX != getPivotX()) {              invalidateViewProperty(true, false); -            info.mPivotX = pivotX; -            info.mMatrixDirty = true; +            mRenderNode.setPivotX(pivotX);              invalidateViewProperty(false, true); -            if (mRenderNode != null) { -                mRenderNode.setPivotX(pivotX); -            } -            if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { -                // View was rejected last time it was drawn by its parent; this may have changed -                invalidateParentIfNeeded(); -            } + +            invalidateParentIfNeededAndWasQuickRejected();          }      } @@ -10178,7 +9935,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getPivotY() { -        return mTransformationInfo != null ? mTransformationInfo.mPivotY : 0; +        return mRenderNode.getPivotY();      }      /** @@ -10196,23 +9953,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @attr ref android.R.styleable#View_transformPivotY       */      public void setPivotY(float pivotY) { -        ensureTransformationInfo(); -        final TransformationInfo info = mTransformationInfo; -        boolean pivotSet = (mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == -                PFLAG_PIVOT_EXPLICITLY_SET; -        if (info.mPivotY != pivotY || !pivotSet) { -            mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET; +        if (mRenderNode.isPivotExplicitlySet() || pivotY != getPivotY()) {              invalidateViewProperty(true, false); -            info.mPivotY = pivotY; -            info.mMatrixDirty = true; +            mRenderNode.setPivotY(pivotY);              invalidateViewProperty(false, true); -            if (mRenderNode != null) { -                mRenderNode.setPivotY(pivotY); -            } -            if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { -                // View was rejected last time it was drawn by its parent; this may have changed -                invalidateParentIfNeeded(); -            } + +            invalidateParentIfNeededAndWasQuickRejected();          }      } @@ -10290,9 +10036,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              } else {                  mPrivateFlags &= ~PFLAG_ALPHA_SET;                  invalidateViewProperty(true, false); -                if (mRenderNode != null) { -                    mRenderNode.setAlpha(getFinalAlpha()); -                } +                mRenderNode.setAlpha(getFinalAlpha());              }          }      } @@ -10317,9 +10061,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,                  return true;              } else {                  mPrivateFlags &= ~PFLAG_ALPHA_SET; -                if (mRenderNode != null) { -                    mRenderNode.setAlpha(getFinalAlpha()); -                } +                mRenderNode.setAlpha(getFinalAlpha());              }          }          return false; @@ -10340,9 +10082,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              mTransformationInfo.mTransitionAlpha = alpha;              mPrivateFlags &= ~PFLAG_ALPHA_SET;              invalidateViewProperty(true, false); -            if (mRenderNode != null) { -                mRenderNode.setAlpha(getFinalAlpha()); -            } +            mRenderNode.setAlpha(getFinalAlpha());          }      } @@ -10389,9 +10129,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      public final void setTop(int top) {          if (top != mTop) { -            updateMatrix(); -            final boolean matrixIsIdentity = mTransformationInfo == null -                    || mTransformationInfo.mMatrixIsIdentity; +            final boolean matrixIsIdentity = hasIdentityMatrix();              if (matrixIsIdentity) {                  if (mAttachInfo != null) {                      int minTop; @@ -10414,17 +10152,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              int oldHeight = mBottom - mTop;              mTop = top; -            if (mRenderNode != null) { -                mRenderNode.setTop(mTop); -            } +            mRenderNode.setTop(mTop);              sizeChange(width, mBottom - mTop, width, oldHeight);              if (!matrixIsIdentity) { -                if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { -                    // A change in dimension means an auto-centered pivot point changes, too -                    mTransformationInfo.mMatrixDirty = true; -                }                  mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation                  invalidate(true);              } @@ -10465,9 +10197,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      public final void setBottom(int bottom) {          if (bottom != mBottom) { -            updateMatrix(); -            final boolean matrixIsIdentity = mTransformationInfo == null -                    || mTransformationInfo.mMatrixIsIdentity; +            final boolean matrixIsIdentity = hasIdentityMatrix();              if (matrixIsIdentity) {                  if (mAttachInfo != null) {                      int maxBottom; @@ -10487,17 +10217,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              int oldHeight = mBottom - mTop;              mBottom = bottom; -            if (mRenderNode != null) { -                mRenderNode.setBottom(mBottom); -            } +            mRenderNode.setBottom(mBottom);              sizeChange(width, mBottom - mTop, width, oldHeight);              if (!matrixIsIdentity) { -                if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { -                    // A change in dimension means an auto-centered pivot point changes, too -                    mTransformationInfo.mMatrixDirty = true; -                }                  mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation                  invalidate(true);              } @@ -10529,9 +10253,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      public final void setLeft(int left) {          if (left != mLeft) { -            updateMatrix(); -            final boolean matrixIsIdentity = mTransformationInfo == null -                    || mTransformationInfo.mMatrixIsIdentity; +            final boolean matrixIsIdentity = hasIdentityMatrix();              if (matrixIsIdentity) {                  if (mAttachInfo != null) {                      int minLeft; @@ -10554,17 +10276,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              int height = mBottom - mTop;              mLeft = left; -            if (mRenderNode != null) { -                mRenderNode.setLeft(left); -            } +            mRenderNode.setLeft(left);              sizeChange(mRight - mLeft, height, oldWidth, height);              if (!matrixIsIdentity) { -                if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { -                    // A change in dimension means an auto-centered pivot point changes, too -                    mTransformationInfo.mMatrixDirty = true; -                }                  mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation                  invalidate(true);              } @@ -10596,9 +10312,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      public final void setRight(int right) {          if (right != mRight) { -            updateMatrix(); -            final boolean matrixIsIdentity = mTransformationInfo == null -                    || mTransformationInfo.mMatrixIsIdentity; +            final boolean matrixIsIdentity = hasIdentityMatrix();              if (matrixIsIdentity) {                  if (mAttachInfo != null) {                      int maxRight; @@ -10618,17 +10332,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              int height = mBottom - mTop;              mRight = right; -            if (mRenderNode != null) { -                mRenderNode.setRight(mRight); -            } +            mRenderNode.setRight(mRight);              sizeChange(mRight - mLeft, height, oldWidth, height);              if (!matrixIsIdentity) { -                if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { -                    // A change in dimension means an auto-centered pivot point changes, too -                    mTransformationInfo.mMatrixDirty = true; -                }                  mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation                  invalidate(true);              } @@ -10650,7 +10358,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getX() { -        return mLeft + (mTransformationInfo != null ? mTransformationInfo.mTranslationX : 0); +        return mLeft + getTranslationX();      }      /** @@ -10673,7 +10381,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getY() { -        return mTop + (mTransformationInfo != null ? mTransformationInfo.mTranslationY : 0); +        return mTop + getTranslationY();      }      /** @@ -10697,7 +10405,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getTranslationX() { -        return mTransformationInfo != null ? mTransformationInfo.mTranslationX : 0; +        return mRenderNode.getTranslationX();      }      /** @@ -10711,21 +10419,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @attr ref android.R.styleable#View_translationX       */      public void setTranslationX(float translationX) { -        ensureTransformationInfo(); -        final TransformationInfo info = mTransformationInfo; -        if (info.mTranslationX != translationX) { -            // Double-invalidation is necessary to capture view's old and new areas +        if (translationX != getTranslationX()) {              invalidateViewProperty(true, false); -            info.mTranslationX = translationX; -            info.mMatrixDirty = true; +            mRenderNode.setTranslationX(translationX);              invalidateViewProperty(false, true); -            if (mRenderNode != null) { -                mRenderNode.setTranslationX(translationX); -            } -            if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { -                // View was rejected last time it was drawn by its parent; this may have changed -                invalidateParentIfNeeded(); -            } + +            invalidateParentIfNeededAndWasQuickRejected();          }      } @@ -10739,7 +10438,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getTranslationY() { -        return mTransformationInfo != null ? mTransformationInfo.mTranslationY : 0; +        return mRenderNode.getTranslationY();      }      /** @@ -10753,20 +10452,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @attr ref android.R.styleable#View_translationY       */      public void setTranslationY(float translationY) { -        ensureTransformationInfo(); -        final TransformationInfo info = mTransformationInfo; -        if (info.mTranslationY != translationY) { +        if (translationY != getTranslationY()) {              invalidateViewProperty(true, false); -            info.mTranslationY = translationY; -            info.mMatrixDirty = true; +            mRenderNode.setTranslationY(translationY);              invalidateViewProperty(false, true); -            if (mRenderNode != null) { -                mRenderNode.setTranslationY(translationY); -            } -            if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { -                // View was rejected last time it was drawn by its parent; this may have changed -                invalidateParentIfNeeded(); -            } + +            invalidateParentIfNeededAndWasQuickRejected();          }      } @@ -10777,7 +10468,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      @ViewDebug.ExportedProperty(category = "drawing")      public float getTranslationZ() { -        return mTransformationInfo != null ? mTransformationInfo.mTranslationZ : 0; +        return mRenderNode.getTranslationZ();      }      /** @@ -10786,20 +10477,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @attr ref android.R.styleable#View_translationZ       */      public void setTranslationZ(float translationZ) { -        ensureTransformationInfo(); -        final TransformationInfo info = mTransformationInfo; -        if (info.mTranslationZ != translationZ) { +        if (translationZ != getTranslationZ()) {              invalidateViewProperty(true, false); -            info.mTranslationZ = translationZ; -            info.mMatrixDirty = true; +            mRenderNode.setTranslationZ(translationZ);              invalidateViewProperty(false, true); -            if (mRenderNode != null) { -                mRenderNode.setTranslationZ(translationZ); -            } -            if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { -                // View was rejected last time it was drawn by its parent; this may have changed -                invalidateParentIfNeeded(); -            } + +            invalidateParentIfNeededAndWasQuickRejected();          }      } @@ -10869,10 +10552,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              }              mOutline.set(outline);          } - -        if (mRenderNode != null) { -            mRenderNode.setOutline(mOutline); -        } +        mRenderNode.setOutline(mOutline);      }      /** @@ -10907,9 +10587,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              } else {                  mPrivateFlags3 &= ~PFLAG3_CLIP_TO_OUTLINE;              } -            if (mRenderNode != null) { -                mRenderNode.setClipToOutline(clipToOutline); -            } +            mRenderNode.setClipToOutline(clipToOutline);          }      } @@ -10920,11 +10598,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      public void setRevealClip(boolean shouldClip, boolean inverseClip,              float x, float y, float radius) { -        if (mRenderNode != null) { -            mRenderNode.setRevealClip(shouldClip, inverseClip, x, y, radius); -            // TODO: Handle this invalidate in a better way, or purely in native. -            invalidate(); -        } +        mRenderNode.setRevealClip(shouldClip, inverseClip, x, y, radius); +        // TODO: Handle this invalidate in a better way, or purely in native. +        invalidate();      }      /** @@ -10933,14 +10609,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @param outRect The hit rectangle of the view.       */      public void getHitRect(Rect outRect) { -        updateMatrix(); -        final TransformationInfo info = mTransformationInfo; -        if (info == null || info.mMatrixIsIdentity || mAttachInfo == null) { +        if (hasIdentityMatrix() || mAttachInfo == null) {              outRect.set(mLeft, mTop, mRight, mBottom);          } else {              final RectF tmpRect = mAttachInfo.mTmpTransformRect;              tmpRect.set(0, 0, getWidth(), getHeight()); -            info.mMatrix.mapRect(tmpRect); +            getMatrix().mapRect(tmpRect); // TODO: mRenderNode.mapRect(tmpRect)              outRect.set((int) tmpRect.left + mLeft, (int) tmpRect.top + mTop,                      (int) tmpRect.right + mLeft, (int) tmpRect.bottom + mTop);          } @@ -11029,11 +10703,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      public void offsetTopAndBottom(int offset) {          if (offset != 0) { -            updateMatrix(); -            final boolean matrixIsIdentity = mTransformationInfo == null -                    || mTransformationInfo.mMatrixIsIdentity; +            final boolean matrixIsIdentity = hasIdentityMatrix();              if (matrixIsIdentity) { -                if (mRenderNode != null) { +                if (isHardwareAccelerated()) {                      invalidateViewProperty(false, false);                  } else {                      final ViewParent p = mParent; @@ -11061,8 +10733,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              mTop += offset;              mBottom += offset; -            if (mRenderNode != null) { -                mRenderNode.offsetTopAndBottom(offset); +            mRenderNode.offsetTopAndBottom(offset); +            if (isHardwareAccelerated()) {                  invalidateViewProperty(false, false);              } else {                  if (!matrixIsIdentity) { @@ -11080,11 +10752,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       */      public void offsetLeftAndRight(int offset) {          if (offset != 0) { -            updateMatrix(); -            final boolean matrixIsIdentity = mTransformationInfo == null -                    || mTransformationInfo.mMatrixIsIdentity; +            final boolean matrixIsIdentity = hasIdentityMatrix();              if (matrixIsIdentity) { -                if (mRenderNode != null) { +                if (isHardwareAccelerated()) {                      invalidateViewProperty(false, false);                  } else {                      final ViewParent p = mParent; @@ -11109,8 +10779,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              mLeft += offset;              mRight += offset; -            if (mRenderNode != null) { -                mRenderNode.offsetLeftAndRight(offset); +            mRenderNode.offsetLeftAndRight(offset); +            if (isHardwareAccelerated()) {                  invalidateViewProperty(false, false);              } else {                  if (!matrixIsIdentity) { @@ -11490,7 +11160,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              }              // Damage the entire IsolatedZVolume recieving this view's shadow. -            if (getTranslationZ() != 0) { +            if (isHardwareAccelerated() && getTranslationZ() != 0) {                  damageShadowReceiver();              }          } @@ -11553,7 +11223,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * list properties are not being used in this view       */      void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) { -        if (mRenderNode == null || (mPrivateFlags & PFLAG_DRAW_ANIMATION) == PFLAG_DRAW_ANIMATION) { +        if (!isHardwareAccelerated() +                || !mRenderNode.isValid() +                || (mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) {              if (invalidateParent) {                  invalidateParentCaches();              } @@ -11564,7 +11236,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,          } else {              damageInParent();          } -        if (invalidateParent && getTranslationZ() != 0) { +        if (isHardwareAccelerated() && invalidateParent && getTranslationZ() != 0) {              damageShadowReceiver();          }      } @@ -11581,7 +11253,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              final Rect r = ai.mTmpInvalRect;              r.set(0, 0, mRight - mLeft, mBottom - mTop);              if (mParent instanceof ViewGroup) { -                ((ViewGroup) mParent).invalidateChildFast(this, r); +                ((ViewGroup) mParent).damageChild(this, r);              } else {                  mParent.invalidateChild(this, r);              } @@ -11634,6 +11306,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,      }      /** +     * @hide +     */ +    protected void invalidateParentIfNeededAndWasQuickRejected() { +        if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) != 0) { +            // View was rejected last time it was drawn by its parent; this may have changed +            invalidateParentIfNeeded(); +        } +    } + +    /**       * Indicates whether this View is opaque. An opaque View guarantees that it will       * draw all the pixels overlapping its bounds using a fully opaque color.       * @@ -13976,13 +13658,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,       * @hide       */      public RenderNode getDisplayList() { -        ensureRenderNode();          updateDisplayListIfDirty(mRenderNode, false);          return mRenderNode;      }      private void resetDisplayList() { -        if (mRenderNode != null && mRenderNode.isValid()) { +        if (mRenderNode.isValid()) {              mRenderNode.destroyDisplayListData();          } @@ -14577,21 +14258,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,      }      /** -     * This method is called by getDisplayList() when a display list is created or re-rendered. -     * It sets or resets the current value of all properties on that display list (resetting is -     * necessary when a display list is being re-created, because we need to make sure that -     * previously-set transform values +     * This method is called by getDisplayList() when a display list is recorded for a View. +     * It pushes any properties to the RenderNode that aren't managed by the RenderNode.       */ -    void setDisplayListProperties(RenderNode displayList) { -        if (displayList != null) { -            displayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); -            displayList.setHasOverlappingRendering(hasOverlappingRendering()); +    void setDisplayListProperties(RenderNode renderNode) { +        if (renderNode != null) { +            renderNode.setHasOverlappingRendering(hasOverlappingRendering());              if (mParent instanceof ViewGroup) { -                displayList.setClipToBounds( +                renderNode.setClipToBounds(                          (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);              } -            displayList.setOutline(mOutline); -            displayList.setClipToOutline(getClipToOutline());              float alpha = 1;              if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &                      ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) { @@ -14604,7 +14280,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,                              alpha = t.getAlpha();                          }                          if ((transformType & Transformation.TYPE_MATRIX) != 0) { -                            displayList.setStaticMatrix(t.getMatrix()); +                            renderNode.setStaticMatrix(t.getMatrix());                          }                      }                  } @@ -14617,23 +14293,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,                          alpha = 1;                      }                  } -                displayList.setTransformationInfo(alpha, -                        mTransformationInfo.mTranslationX, mTransformationInfo.mTranslationY, -                        mTransformationInfo.mTranslationZ, -                        mTransformationInfo.mRotation, mTransformationInfo.mRotationX, -                        mTransformationInfo.mRotationY, mTransformationInfo.mScaleX, -                        mTransformationInfo.mScaleY); -                if (mTransformationInfo.mCamera == null) { -                    mTransformationInfo.mCamera = new Camera(); -                    mTransformationInfo.matrix3D = new Matrix(); -                } -                displayList.setCameraDistance(mTransformationInfo.mCamera.getLocationZ()); -                if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == PFLAG_PIVOT_EXPLICITLY_SET) { -                    displayList.setPivotX(getPivotX()); -                    displayList.setPivotY(getPivotY()); -                } +                renderNode.setAlpha(alpha);              } else if (alpha < 1) { -                displayList.setAlpha(alpha); +                renderNode.setAlpha(alpha);              }          }      } @@ -14680,8 +14342,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              }              transformToApply = parent.getChildTransformation();          } else { -            if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) == -                    PFLAG3_VIEW_IS_ANIMATING_TRANSFORM && mRenderNode != null) { +            if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) != 0) {                  // No longer animating: clear out old animation matrix                  mRenderNode.setAnimationMatrix(null);                  mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_TRANSFORM; @@ -15196,9 +14857,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              if ((mPrivateFlags3 & PFLAG3_OUTLINE_DEFINED) == 0) {                  // Outline not currently define, query from background                  mOutline = background.getOutline(); -                if (mRenderNode != null) { -                    mRenderNode.setOutline(mOutline); -                } +                mRenderNode.setOutline(mOutline);              }          } @@ -15533,20 +15192,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,              mTop = top;              mRight = right;              mBottom = bottom; -            if (mRenderNode != null) { -                mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); -            } +            mRenderNode.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);              mPrivateFlags |= PFLAG_HAS_BOUNDS;              if (sizeChanged) { -                if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) { -                    // A change in dimension means an auto-centered pivot point changes, too -                    if (mTransformationInfo != null) { -                        mTransformationInfo.mMatrixDirty = true; -                    } -                }                  sizeChange(newWidth, newHeight, oldWidth, oldHeight);              } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index bcc82fbf8292..d2c6302b9131 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -4449,7 +4449,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager       *       * @hide       */ -    public void invalidateChildFast(View child, final Rect dirty) { +    public void damageChild(View child, final Rect dirty) {          ViewParent parent = this;          final AttachInfo attachInfo = mAttachInfo; @@ -4472,7 +4472,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager                          parentVG.invalidate();                          parent = null;                      } else { -                        parent = parentVG.invalidateChildInParentFast(left, top, dirty); +                        parent = parentVG.damageChildInParent(left, top, dirty);                          left = parentVG.mLeft;                          top = parentVG.mTop;                      } @@ -4494,9 +4494,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager       *       * @hide       */ -    protected ViewParent invalidateChildInParentFast(int left, int top, final Rect dirty) { -        if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN || -                (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) { +    protected ViewParent damageChildInParent(int left, int top, final Rect dirty) { +        if ((mPrivateFlags & PFLAG_DRAWN) != 0 +                || (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) != 0) {              dirty.offset(left - mScrollX, top - mScrollY);              if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0) {                  dirty.union(0, 0, mRight - mLeft, mBottom - mTop); diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java index 47de780d83c0..0cf9dddc6e72 100644 --- a/core/java/android/view/ViewOverlay.java +++ b/core/java/android/view/ViewOverlay.java @@ -290,7 +290,11 @@ public class ViewOverlay {              }          } -        public void invalidateChildFast(View child, final Rect dirty) { +        /** +         * @hide +         */ +        @Override +        public void damageChild(View child, final Rect dirty) {              if (mHostView != null) {                  // Note: This is not a "fast" invalidation. Would be nice to instead invalidate                  // using DisplayList properties and a dirty rect instead of causing a real @@ -309,9 +313,9 @@ public class ViewOverlay {           * @hide           */          @Override -        protected ViewParent invalidateChildInParentFast(int left, int top, Rect dirty) { +        protected ViewParent damageChildInParent(int left, int top, Rect dirty) {              if (mHostView instanceof ViewGroup) { -                return ((ViewGroup) mHostView).invalidateChildInParentFast(left, top, dirty); +                return ((ViewGroup) mHostView).damageChildInParent(left, top, dirty);              }              return null;          } diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index bbae0cad6d93..6b21451c06b7 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -928,48 +928,38 @@ public class ViewPropertyAnimator {          final RenderNode renderNode = mView.mRenderNode;          switch (propertyConstant) {              case TRANSLATION_X: -                info.mTranslationX = value; -                if (renderNode != null) renderNode.setTranslationX(value); +                renderNode.setTranslationX(value);                  break;              case TRANSLATION_Y: -                info.mTranslationY = value; -                if (renderNode != null) renderNode.setTranslationY(value); +                renderNode.setTranslationY(value);                  break;              case TRANSLATION_Z: -                info.mTranslationZ = value; -                if (renderNode != null) renderNode.setTranslationZ(value); +                renderNode.setTranslationZ(value);                  break;              case ROTATION: -                info.mRotation = value; -                if (renderNode != null) renderNode.setRotation(value); +                renderNode.setRotation(value);                  break;              case ROTATION_X: -                info.mRotationX = value; -                if (renderNode != null) renderNode.setRotationX(value); +                renderNode.setRotationX(value);                  break;              case ROTATION_Y: -                info.mRotationY = value; -                if (renderNode != null) renderNode.setRotationY(value); +                renderNode.setRotationY(value);                  break;              case SCALE_X: -                info.mScaleX = value; -                if (renderNode != null) renderNode.setScaleX(value); +                renderNode.setScaleX(value);                  break;              case SCALE_Y: -                info.mScaleY = value; -                if (renderNode != null) renderNode.setScaleY(value); +                renderNode.setScaleY(value);                  break;              case X: -                info.mTranslationX = value - mView.mLeft; -                if (renderNode != null) renderNode.setTranslationX(value - mView.mLeft); +                renderNode.setTranslationX(value - mView.mLeft);                  break;              case Y: -                info.mTranslationY = value - mView.mTop; -                if (renderNode != null) renderNode.setTranslationY(value - mView.mTop); +                renderNode.setTranslationY(value - mView.mTop);                  break;              case ALPHA:                  info.mAlpha = value; -                if (renderNode != null) renderNode.setAlpha(value); +                renderNode.setAlpha(value);                  break;          }      } @@ -981,30 +971,30 @@ public class ViewPropertyAnimator {       * @return float The value of the named property       */      private float getValue(int propertyConstant) { -        final View.TransformationInfo info = mView.mTransformationInfo; +        final RenderNode node = mView.mRenderNode;          switch (propertyConstant) {              case TRANSLATION_X: -                return info.mTranslationX; +                return node.getTranslationX();              case TRANSLATION_Y: -                return info.mTranslationY; +                return node.getTranslationY();              case TRANSLATION_Z: -                return info.mTranslationZ; +                return node.getTranslationZ();              case ROTATION: -                return info.mRotation; +                return node.getRotation();              case ROTATION_X: -                return info.mRotationX; +                return node.getRotationX();              case ROTATION_Y: -                return info.mRotationY; +                return node.getRotationY();              case SCALE_X: -                return info.mScaleX; +                return node.getScaleX();              case SCALE_Y: -                return info.mScaleY; +                return node.getScaleY();              case X: -                return mView.mLeft + info.mTranslationX; +                return mView.mLeft + node.getTranslationX();              case Y: -                return mView.mTop + info.mTranslationY; +                return mView.mTop + node.getTranslationY();              case ALPHA: -                return info.mAlpha; +                return mView.mTransformationInfo.mAlpha;          }          return 0;      } @@ -1123,7 +1113,6 @@ public class ViewPropertyAnimator {                  }              }              if ((propertyMask & TRANSFORM_MASK) != 0) { -                mView.mTransformationInfo.mMatrixDirty = true;                  if (!useRenderNodeProperties) {                      mView.mPrivateFlags |= View.PFLAG_DRAWN; // force another invalidation                  } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index b617f68560d2..a35c28e21c6f 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -678,13 +678,13 @@ public final class ViewRootImpl implements ViewParent,          mAttachInfo.mHardwareAccelerationRequested = false;          // Don't enable hardware acceleration when the application is in compatibility mode -        if (false && mTranslator != null) return; +        if (mTranslator != null) return;          // Try to enable hardware acceleration if requested          final boolean hardwareAccelerated =                  (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0; -        if (true || hardwareAccelerated) { +        if (hardwareAccelerated) {              if (!HardwareRenderer.isAvailable()) {                  return;              } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 687036ca14ef..5e4c14384cdb 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -5163,12 +5163,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener                  final int width = mRight - mLeft;                  final int padding = getCompoundPaddingLeft() + getCompoundPaddingRight();                  final float dx = mLayout.getLineRight(0) - (width - padding); -                canvas.translate(isLayoutRtl ? -dx : +dx, 0.0f); +                canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);              }              if (mMarquee != null && mMarquee.isRunning()) {                  final float dx = -mMarquee.getScroll(); -                canvas.translate(isLayoutRtl ? -dx : +dx, 0.0f); +                canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);              }          } @@ -5182,8 +5182,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener          }          if (mMarquee != null && mMarquee.shouldDrawGhost()) { -            final int dx = (int) mMarquee.getGhostOffset(); -            canvas.translate(isLayoutRtl ? -dx : dx, 0.0f); +            final float dx = mMarquee.getGhostOffset(); +            canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);              layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);          } diff --git a/core/java/android/widget/TimePickerDelegate.java b/core/java/android/widget/TimePickerDelegate.java index c9a9894cf383..79256e567762 100644 --- a/core/java/android/widget/TimePickerDelegate.java +++ b/core/java/android/widget/TimePickerDelegate.java @@ -152,11 +152,11 @@ class TimePickerDelegate extends TimePicker.AbstractTimePickerDelegate implement          final int headerBackgroundColor = a.getColor(                  R.styleable.TimePicker_headerBackgroundColor, 0); -        a.recycle(); -          final int layoutResourceId = a.getResourceId(                  R.styleable.TimePicker_internalLayout, R.layout.time_picker_holo); +        a.recycle(); +          final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(                  Context.LAYOUT_INFLATER_SERVICE); diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java index cc51a8bcc83b..80e1caaf26d8 100644 --- a/core/java/com/android/internal/app/ActionBarImpl.java +++ b/core/java/com/android/internal/app/ActionBarImpl.java @@ -174,7 +174,6 @@ public class ActionBarImpl extends ActionBar {      }      private void init(View decor) { -        mContext = decor.getContext();          mOverlayLayout = (ActionBarOverlayLayout) decor.findViewById(                  com.android.internal.R.id.action_bar_overlay_layout);          if (mOverlayLayout != null) { @@ -193,6 +192,7 @@ public class ActionBarImpl extends ActionBar {                      "with a compatible window decor layout");          } +        mContext = mActionView.getContext();          mActionView.setContextView(mContextView);          mContextDisplayMode = mActionView.isSplitActionBar() ?                  CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL; diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java index f9e5569ba735..ac3274d7aa68 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java +++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java @@ -545,6 +545,7 @@ public class InputMethodUtils {          public boolean isCurrentProfile(int userId) {              synchronized (this) { +                if (userId == mCurrentUserId) return true;                  for (int i = 0; i < mCurrentProfileIds.length; i++) {                      if (userId == mCurrentProfileIds[i]) return true;                  } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 39636fe6b2c2..4c11fa95eddc 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -574,6 +574,7 @@ public final class BatteryStatsImpl extends BatteryStats {              mUptime = in.readLong();              mPastUptime = in.readLong();              mUptimeStart = in.readLong(); +            mRealtime = in.readLong();              mPastRealtime = in.readLong();              mRealtimeStart = in.readLong();              mUnpluggedUptime = in.readLong(); @@ -586,6 +587,7 @@ public final class BatteryStatsImpl extends BatteryStats {              out.writeLong(mUptime);              out.writeLong(runningUptime);              out.writeLong(mUptimeStart); +            out.writeLong(mRealtime);              out.writeLong(runningRealtime);              out.writeLong(mRealtimeStart);              out.writeLong(mUnpluggedUptime); diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index b9bc54d53599..45049103041c 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -564,12 +564,37 @@ public class LockPatternUtils {          }      } +    private void updateCryptoUserInfo() { +        int userId = getCurrentOrCallingUserId(); +        if (userId != UserHandle.USER_OWNER) { +            return; +        } + +        final String ownerInfo = isOwnerInfoEnabled() ? getOwnerInfo(userId) : ""; + +        IBinder service = ServiceManager.getService("mount"); +        if (service == null) { +            Log.e(TAG, "Could not find the mount service to update the user info"); +            return; +        } + +        IMountService mountService = IMountService.Stub.asInterface(service); +        try { +            Log.d(TAG, "Setting owner info"); +            mountService.setField("OwnerInfo", ownerInfo); +        } catch (RemoteException e) { +            Log.e(TAG, "Error changing user info", e); +        } +    } +      public void setOwnerInfo(String info, int userId) {          setString(LOCK_SCREEN_OWNER_INFO, info, userId); +        updateCryptoUserInfo();      }      public void setOwnerInfoEnabled(boolean enabled) {          setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled); +        updateCryptoUserInfo();      }      public String getOwnerInfo(int userId) { diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 6afeb867b9ab..47594519478f 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -229,9 +229,10 @@ int register_com_android_internal_os_RuntimeInit(JNIEnv* env)  /*static*/ JavaVM* AndroidRuntime::mJavaVM = NULL; - -AndroidRuntime::AndroidRuntime() : -        mExitWithoutCleanup(false) +AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) : +        mExitWithoutCleanup(false), +        mArgBlockStart(argBlockStart), +        mArgBlockLength(argBlockLength)  {      SkGraphics::Init();      // this sets our preference for 16bit images during decode @@ -266,6 +267,10 @@ AndroidRuntime::~AndroidRuntime()      return jniRegisterNativeMethods(env, className, gMethods, numMethods);  } +void AndroidRuntime::setArgv0(const char* argv0) { +    strlcpy(mArgBlockStart, argv0, mArgBlockLength); +} +  status_t AndroidRuntime::callMain(const char* className,      jclass clazz, int argc, const char* const argv[])  { diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index cbed99f9acad..a4efed7e65e3 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -19,8 +19,8 @@  #include <utils/Log.h>  #include <binder/IPCThreadState.h> -#include <binder/ProcessState.h>  #include <binder/IServiceManager.h> +#include <cutils/process_name.h>  #include <cutils/sched_policy.h>  #include <utils/String8.h>  #include <utils/Vector.h> @@ -385,7 +385,9 @@ void android_os_Process_setArgV0(JNIEnv* env, jobject clazz, jstring name)      }      if (name8.size() > 0) { -        ProcessState::self()->setArgV0(name8.string()); +        const char* procName = name8.string(); +        set_process_name(procName); +        AndroidRuntime::getRuntime()->setArgv0(procName);      }  } diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp index 3e359d4cf632..d079349cb256 100644 --- a/core/jni/android_view_RenderNode.cpp +++ b/core/jni/android_view_RenderNode.cpp @@ -69,7 +69,7 @@ static void android_view_RenderNode_destroyDisplayList(JNIEnv* env,  }  // ---------------------------------------------------------------------------- -// RenderProperties +// RenderProperties - setters  // ----------------------------------------------------------------------------  static void android_view_RenderNode_setCaching(JNIEnv* env, @@ -209,22 +209,6 @@ static void android_view_RenderNode_setScaleY(JNIEnv* env,      displayList->mutateStagingProperties().setScaleY(sy);  } -static void android_view_RenderNode_setTransformationInfo(JNIEnv* env, -        jobject clazz, jlong displayListPtr, float alpha, -        float translationX, float translationY, float translationZ, -        float rotation, float rotationX, float rotationY, float scaleX, float scaleY) { -    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); -    displayList->mutateStagingProperties().setAlpha(alpha); -    displayList->mutateStagingProperties().setTranslationX(translationX); -    displayList->mutateStagingProperties().setTranslationY(translationY); -    displayList->mutateStagingProperties().setTranslationZ(translationZ); -    displayList->mutateStagingProperties().setRotation(rotation); -    displayList->mutateStagingProperties().setRotationX(rotationX); -    displayList->mutateStagingProperties().setRotationY(rotationY); -    displayList->mutateStagingProperties().setScaleX(scaleX); -    displayList->mutateStagingProperties().setScaleY(scaleY); -} -  static void android_view_RenderNode_setPivotX(JNIEnv* env,          jobject clazz, jlong displayListPtr, float px) {      RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); @@ -286,6 +270,10 @@ static void android_view_RenderNode_offsetTopAndBottom(JNIEnv* env,      displayList->mutateStagingProperties().offsetTopBottom(offset);  } +// ---------------------------------------------------------------------------- +// RenderProperties - getters +// ---------------------------------------------------------------------------- +  static jboolean android_view_RenderNode_hasOverlappingRendering(JNIEnv* env,          jobject clazz, jlong displayListPtr) {      RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); @@ -352,6 +340,12 @@ static jfloat android_view_RenderNode_getTranslationY(JNIEnv* env,      return displayList->stagingProperties().getTranslationY();  } +static jfloat android_view_RenderNode_getTranslationZ(JNIEnv* env, +        jobject clazz, jlong displayListPtr) { +    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); +    return displayList->stagingProperties().getTranslationZ(); +} +  static jfloat android_view_RenderNode_getRotation(JNIEnv* env,          jobject clazz, jlong displayListPtr) {      RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); @@ -370,6 +364,53 @@ static jfloat android_view_RenderNode_getRotationY(JNIEnv* env,      return displayList->stagingProperties().getRotationY();  } +static jboolean android_view_RenderNode_isPivotExplicitlySet(JNIEnv* env, +        jobject clazz, jlong displayListPtr) { +    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); +    return displayList->stagingProperties().isPivotExplicitlySet(); +} + +static jboolean android_view_RenderNode_hasIdentityMatrix(JNIEnv* env, +        jobject clazz, jlong displayListPtr) { +    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); +    return displayList->stagingProperties().getMatrixFlags() == 0; +} + +// ---------------------------------------------------------------------------- +// RenderProperties - computed getters +// ---------------------------------------------------------------------------- + +static void android_view_RenderNode_getTransformMatrix(JNIEnv* env, +        jobject clazz, jlong displayListPtr, jlong outMatrixPtr) { +    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); +    SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr); + +    displayList->mutateStagingProperties().updateMatrix(); +    const SkMatrix* transformMatrix = displayList->stagingProperties().getTransformMatrix(); + +    if (displayList->stagingProperties().getMatrixFlags() == TRANSLATION) { +        outMatrix->setTranslate(displayList->stagingProperties().getTranslationX(), +                displayList->stagingProperties().getTranslationY()); +    } else if (transformMatrix) { +        *outMatrix = *transformMatrix; +    } else { +        outMatrix->setIdentity(); +    } +} + +static void android_view_RenderNode_getInverseTransformMatrix(JNIEnv* env, +        jobject clazz, jlong displayListPtr, jlong outMatrixPtr) { +    // load transform matrix +    android_view_RenderNode_getTransformMatrix(env, clazz, displayListPtr, outMatrixPtr); +    SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr); + +    // return it inverted +    if (!outMatrix->invert(outMatrix)) { +        // failed to load inverse, pass back identity +        outMatrix->setIdentity(); +    } +} +  static jfloat android_view_RenderNode_getPivotX(JNIEnv* env,          jobject clazz, jlong displayListPtr) {      RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); @@ -424,8 +465,6 @@ static JNINativeMethod gMethods[] = {      { "nSetRotationY",         "(JF)V",  (void*) android_view_RenderNode_setRotationY },      { "nSetScaleX",            "(JF)V",  (void*) android_view_RenderNode_setScaleX },      { "nSetScaleY",            "(JF)V",  (void*) android_view_RenderNode_setScaleY }, -    { "nSetTransformationInfo","(JFFFFFFFFF)V", -            (void*) android_view_RenderNode_setTransformationInfo },      { "nSetPivotX",            "(JF)V",  (void*) android_view_RenderNode_setPivotX },      { "nSetPivotY",            "(JF)V",  (void*) android_view_RenderNode_setPivotY },      { "nSetCameraDistance",    "(JF)V",  (void*) android_view_RenderNode_setCameraDistance }, @@ -448,11 +487,18 @@ static JNINativeMethod gMethods[] = {      { "nGetScaleY",               "(J)F",  (void*) android_view_RenderNode_getScaleY },      { "nGetTranslationX",         "(J)F",  (void*) android_view_RenderNode_getTranslationX },      { "nGetTranslationY",         "(J)F",  (void*) android_view_RenderNode_getTranslationY }, +    { "nGetTranslationZ",         "(J)F",  (void*) android_view_RenderNode_getTranslationZ },      { "nGetRotation",             "(J)F",  (void*) android_view_RenderNode_getRotation },      { "nGetRotationX",            "(J)F",  (void*) android_view_RenderNode_getRotationX },      { "nGetRotationY",            "(J)F",  (void*) android_view_RenderNode_getRotationY }, -    { "nGetPivotX",               "(J)F",  (void*) android_view_RenderNode_getPivotX }, -    { "nGetPivotY",               "(J)F",  (void*) android_view_RenderNode_getPivotY }, +    { "nIsPivotExplicitlySet",    "(J)Z",  (void*) android_view_RenderNode_isPivotExplicitlySet }, +    { "nHasIdentityMatrix",       "(J)Z",  (void*) android_view_RenderNode_hasIdentityMatrix }, + +    { "nGetTransformMatrix",       "(JJ)V", (void*) android_view_RenderNode_getTransformMatrix }, +    { "nGetInverseTransformMatrix","(JJ)V", (void*) android_view_RenderNode_getInverseTransformMatrix }, + +    { "nGetPivotX",                "(J)F",  (void*) android_view_RenderNode_getPivotX }, +    { "nGetPivotY",                "(J)F",  (void*) android_view_RenderNode_getPivotY },  #endif  }; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 2a4d872eb811..3857cd1bf1b4 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2585,6 +2585,13 @@          android:description="@string/permdesc_accessNetworkConditions"          android:protectionLevel="signature|system" /> +    <!-- Allows an application to provision and access DRM certificates +         @hide This is not a third-party API (intended for system apps). --> +    <permission android:name="android.permission.ACCESS_DRM_CERTIFICATES" +        android:label="@string/permlab_accessDrmCertificates" +        android:description="@string/permdesc_accessDrmCertificates" +        android:protectionLevel="signature|system" /> +      <!-- The system process is explicitly the only one allowed to launch the           confirmation UI for full backup/restore -->      <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/> diff --git a/core/res/res/drawable/item_background_quantum.xml b/core/res/res/drawable/item_background_quantum.xml index f668ca037f2c..11e1f67e79c0 100644 --- a/core/res/res/drawable/item_background_quantum.xml +++ b/core/res/res/drawable/item_background_quantum.xml @@ -15,4 +15,5 @@  -->  <touch-feedback xmlns:android="http://schemas.android.com/apk/res/android" -    android:tint="?attr/colorButtonPressed" /> +    android:tint="?attr/colorButtonPressed" +    android:pinned="true" /> diff --git a/core/res/res/layout/alert_dialog_quantum.xml b/core/res/res/layout/alert_dialog_quantum.xml index 4cc76ca6dc37..59dba08eddac 100644 --- a/core/res/res/layout/alert_dialog_quantum.xml +++ b/core/res/res/layout/alert_dialog_quantum.xml @@ -20,33 +20,26 @@      android:id="@+id/parentPanel"      android:layout_width="match_parent"      android:layout_height="wrap_content" -    android:layout_marginStart="8dip" -    android:layout_marginEnd="8dip"      android:orientation="vertical">      <LinearLayout android:id="@+id/topPanel"          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:orientation="vertical"> -        <View android:id="@+id/titleDividerTop" -            android:layout_width="match_parent" -            android:layout_height="2dip" -            android:visibility="gone" -            android:background="@android:color/holo_blue_light" />          <LinearLayout android:id="@+id/title_template"              android:layout_width="match_parent"              android:layout_height="wrap_content"              android:orientation="horizontal"              android:gravity="center_vertical|start" -            android:minHeight="@dimen/alert_dialog_title_height" -            android:layout_marginStart="16dip" -            android:layout_marginEnd="16dip"> +            android:paddingStart="16dip" +            android:paddingEnd="16dip" +            android:paddingTop="16dip">              <ImageView android:id="@+id/icon"                  android:layout_width="wrap_content"                  android:layout_height="wrap_content"                  android:paddingEnd="8dip"                  android:src="@null" /> -            <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle" +            <TextView android:id="@+id/alertTitle"                  style="?android:attr/windowTitleStyle"                  android:singleLine="true"                  android:ellipsize="end" @@ -54,11 +47,6 @@                  android:layout_height="wrap_content"                  android:textAlignment="viewStart" />          </LinearLayout> -        <View android:id="@+id/titleDivider" -            android:layout_width="match_parent" -            android:layout_height="2dip" -            android:visibility="gone" -            android:background="@android:color/holo_blue_light" />          <!-- If the client uses a customTitle, it will be added here. -->      </LinearLayout> @@ -78,8 +66,7 @@                  android:layout_height="wrap_content"                  android:paddingStart="16dip"                  android:paddingEnd="16dip" -                android:paddingTop="8dip" -                android:paddingBottom="8dip"/> +                android:paddingTop="16dip" />          </ScrollView>      </LinearLayout> @@ -98,7 +85,7 @@          android:layout_height="wrap_content"          android:minHeight="@dimen/alert_dialog_button_bar_height"          android:orientation="vertical" -        android:dividerPadding="0dip"> +        android:padding="16dip">          <LinearLayout              style="?android:attr/buttonBarStyle"              android:layout_width="match_parent" @@ -106,33 +93,33 @@              android:orientation="horizontal"              android:layoutDirection="locale"              android:measureWithLargestChild="true"> -            <Button android:id="@+id/button2" +            <Button android:id="@+id/button3"                  android:layout_width="wrap_content" +                android:layout_height="wrap_content"                  android:layout_gravity="start" -                android:layout_weight="1" +                android:layout_marginRight="8dip"                  android:maxLines="2" -                style="?android:attr/buttonBarButtonStyle" -                android:textSize="14sp"                  android:minHeight="@dimen/alert_dialog_button_bar_height" -                android:layout_height="wrap_content" /> -            <Button android:id="@+id/button3" -                android:layout_width="wrap_content" -                android:layout_gravity="center_horizontal" +                style="?android:attr/buttonBarButtonStyle" /> +            <View android:layout_width="0dp" +                android:layout_height="0dp"                  android:layout_weight="1" +                android:visibility="invisible" /> +            <Button android:id="@+id/button2" +                android:layout_width="wrap_content" +                android:layout_height="wrap_content" +                android:layout_gravity="end" +                android:layout_marginRight="8dip"                  android:maxLines="2" -                style="?android:attr/buttonBarButtonStyle" -                android:textSize="14sp"                  android:minHeight="@dimen/alert_dialog_button_bar_height" -                android:layout_height="wrap_content" /> +                style="?android:attr/buttonBarButtonStyle" />              <Button android:id="@+id/button1"                  android:layout_width="wrap_content" +                android:layout_height="wrap_content"                  android:layout_gravity="end" -                android:layout_weight="1"                  android:maxLines="2"                  android:minHeight="@dimen/alert_dialog_button_bar_height" -                style="?android:attr/buttonBarButtonStyle" -                android:textSize="14sp" -                android:layout_height="wrap_content" /> +                style="?android:attr/buttonBarButtonStyle" />          </LinearLayout>       </LinearLayout>  </LinearLayout> diff --git a/core/res/res/layout/dialog_custom_title_quantum.xml b/core/res/res/layout/dialog_custom_title_quantum.xml new file mode 100644 index 000000000000..f8a2bf7509cd --- /dev/null +++ b/core/res/res/layout/dialog_custom_title_quantum.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 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. +--> + +<!-- +This is a custom layout for a dialog. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +    android:orientation="vertical" +    android:fitsSystemWindows="true"> +    <FrameLayout android:id="@android:id/title_container" +        android:layout_width="match_parent" +        android:layout_height="@dimen/alert_dialog_title_height" +        android:layout_weight="0" +        android:gravity="center_vertical|start" +        style="?android:attr/windowTitleBackgroundStyle"> +    </FrameLayout> +    <View android:id="@+id/titleDivider" +            android:layout_width="match_parent" +            android:layout_height="2dip" +            android:background="@android:color/holo_blue_light" /> +    <FrameLayout +        android:layout_width="match_parent" android:layout_height="wrap_content" +        android:layout_weight="1" +        android:orientation="vertical" +        android:foreground="?android:attr/windowContentOverlay"> +        <FrameLayout android:id="@android:id/content" +            android:layout_width="match_parent" +            android:layout_height="match_parent" /> +    </FrameLayout> +</LinearLayout> diff --git a/core/res/res/layout/dialog_title_icons_quantum.xml b/core/res/res/layout/dialog_title_icons_quantum.xml new file mode 100644 index 000000000000..e3d771cbf2be --- /dev/null +++ b/core/res/res/layout/dialog_title_icons_quantum.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 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. +--> + +<!-- +This is an optimized layout for a screen, with the minimum set of features +enabled. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +    android:orientation="vertical" +    android:fitsSystemWindows="true"> + +    <LinearLayout android:id="@+id/title_container" +        android:layout_width="match_parent" +        android:layout_height="wrap_content" +        android:orientation="horizontal" +        android:gravity="center_vertical" +        android:minHeight="@android:dimen/alert_dialog_title_height" +        android:paddingStart="16dip" +        android:paddingEnd="16dip"> +        <ImageView android:id="@+id/left_icon" +            android:layout_width="32dip" +            android:layout_height="32dip" +            android:scaleType="fitCenter" +            android:layout_marginEnd="8dip" /> +        <TextView android:id="@android:id/title" +            style="?android:attr/windowTitleStyle" +            android:layout_width="wrap_content" +            android:layout_height="wrap_content" +            android:layout_weight="0" /> +        <ImageView android:id="@+id/right_icon" +            android:layout_width="32dip" +            android:layout_height="32dip" +            android:scaleType="fitCenter" +            android:layout_marginStart="8dip" /> +    </LinearLayout> + +    <View android:id="@+id/titleDivider" +            android:layout_width="match_parent" +            android:layout_height="1dip" +            android:background="@android:color/holo_blue_light" /> + +    <FrameLayout +        android:layout_width="match_parent" android:layout_height="wrap_content" +        android:layout_weight="1" +        android:orientation="vertical" +        android:foreground="?android:attr/windowContentOverlay"> +        <FrameLayout android:id="@android:id/content" +            android:layout_width="match_parent" +            android:layout_height="match_parent" /> +    </FrameLayout> +</LinearLayout> diff --git a/core/res/res/layout/dialog_title_quantum.xml b/core/res/res/layout/dialog_title_quantum.xml new file mode 100644 index 000000000000..0a692ee61c94 --- /dev/null +++ b/core/res/res/layout/dialog_title_quantum.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2011, 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. +*/ + +This is an optimized layout for a screen, with the minimum set of features +enabled. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +    android:orientation="vertical" +    android:fitsSystemWindows="true"> +    <TextView android:id="@android:id/title" style="?android:attr/windowTitleStyle" +        android:layout_width="match_parent" +        android:layout_height="wrap_content" +        android:minHeight="@android:dimen/alert_dialog_title_height" +        android:paddingStart="16dip" +        android:paddingEnd="16dip" +        android:gravity="center_vertical|start" /> +    <View android:id="@+id/titleDivider" +            android:layout_width="match_parent" +            android:layout_height="2dip" +            android:background="@android:color/holo_blue_light" /> +    <FrameLayout +        android:layout_width="match_parent" android:layout_height="wrap_content" +        android:layout_weight="1" +        android:orientation="vertical" +        android:foreground="?android:attr/windowContentOverlay"> +        <FrameLayout android:id="@android:id/content" +            android:layout_width="match_parent" +            android:layout_height="match_parent" /> +    </FrameLayout> +</LinearLayout> diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml index 326573674440..b1afec13075b 100644 --- a/core/res/res/layout/screen_action_bar.xml +++ b/core/res/res/layout/screen_action_bar.xml @@ -24,7 +24,7 @@ This is an optimized layout for a screen with the Action Bar enabled.      android:layout_width="match_parent"      android:layout_height="match_parent"      android:splitMotionEvents="false" -    android:theme="?attr/actionBarTheme"> +    android:theme="?attr/actionBarWidgetTheme">      <FrameLayout android:id="@android:id/content"                   android:layout_width="match_parent"                   android:layout_height="match_parent" /> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 4d43831b8a95..aa5005f00eac 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -677,8 +677,6 @@          <!-- Action bar styles   -->          <!-- =================== -->          <eat-comment /> -        <!-- Theme override for the Action Bar --> -        <attr name="actionBarTheme" format="reference" />          <!-- Default style for tabs within an action bar -->          <attr name="actionBarTabStyle" format="reference" />          <attr name="actionBarTabBarStyle" format="reference" /> @@ -4556,6 +4554,7 @@              <enum name="state_activated" value="8" />              <enum name="state_window_focused" value="9" />          </attr> +        <attr name="versionCode" />      </declare-styleable>      <!-- Define the virtual size of the drawing surface paths will draw to. --> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 39b8a6bb567a..b14453ad35b1 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -866,6 +866,18 @@      <!-- The name of the logical parent of the activity as it appears in the manifest. -->      <attr name="parentActivityName" format="string" /> +    <!-- Define an activity that will persist across reboots. If such an activity is in the +         Recents list when the device is shut off it will appear in the Recents list when +         the device is next powered on. To be persisted all activities in the task from the +         root activity up to the last activity before a <em>break</em> must be declared with +         the persistable attribute. A <em>break</em> is the first activity after the root +         started with Intent.FLAG_CLEAR_TASK_WHEN_RESET. + +         <p>Activities that are declared with the persistable attribute will be provided with a +         forced-persistable Bundle in onCreate() and onSavedInstanceState(), and must only +         be passed a persistable Bundle in their Intent.extras. --> +    <attr name="persistable" format="boolean" /> +      <!-- The <code>manifest</code> tag is the root of an           <code>AndroidManifest.xml</code> file,           describing the contents of an Android package (.apk) file.  One @@ -1528,6 +1540,7 @@          <!-- @hide This broacast receiver will only receive broadcasts for the               primary user.  Can only be used with receivers. -->          <attr name="primaryUserOnly" format="boolean" /> +        <attr name="persistable" />      </declare-styleable>      <!-- The <code>activity-alias</code> tag declares a new diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index d4692f17d3d2..667addeaeee2 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2142,6 +2142,7 @@    <public type="attr" name="colorButtonPressed" />    <public type="attr" name="colorButtonNormalColored" />    <public type="attr" name="colorButtonPressedColored" /> +  <public type="attr" name="persistable" />    <public-padding type="dimen" name="l_resource_pad" end="0x01050010" /> @@ -2181,9 +2182,13 @@    <public type="style" name="TextAppearance.Quantum.Widget" />    <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Menu" />    <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Subtitle" /> +  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse" />    <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Title" /> +  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse" />    <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Subtitle" /> +  <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse" />    <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Title" /> +  <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse" />    <public type="style" name="TextAppearance.Quantum.Widget.Button" />    <public type="style" name="TextAppearance.Quantum.Widget.DropDownHint" />    <public type="style" name="TextAppearance.Quantum.Widget.DropDownItem" /> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 3a4f059a44fc..902aea81dc13 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2002,6 +2002,11 @@      <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->      <string name="permdesc_setInputCalibration">Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps.</string> +    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> +    <string name="permlab_accessDrmCertificates">access DRM certificates</string> +    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> +    <string name="permdesc_accessDrmCertificates">Allows an application to provision and use DRM certficates. Should never be needed for normal apps.</string> +      <!-- Policy administration -->      <!-- Title of policy access to limiting the user's password choices --> diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml index 84a1ca42273f..85d8761c2d5c 100644 --- a/core/res/res/values/styles_quantum.xml +++ b/core/res/res/values/styles_quantum.xml @@ -394,6 +394,7 @@ please see styles_device_defaults.xml.      <style name="Widget.Quantum.Button" parent="Widget.Button">          <item name="background">@drawable/btn_default_quantum</item>          <item name="textAppearance">?attr/textAppearanceButton</item> +        <item name="textColor">?attr/textColorPrimary</item>          <item name="minHeight">48dip</item>          <item name="minWidth">96dip</item>      </style> @@ -443,23 +444,13 @@ please see styles_device_defaults.xml.      </style>      <style name="Widget.Quantum.ButtonBar"> -        <item name="paddingTop">0dip</item> -        <item name="paddingStart">0dip</item> -        <item name="paddingEnd">0dip</item> -        <item name="paddingBottom">0dip</item> -        <item name="divider">?attr/dividerVertical</item> -        <item name="showDividers">middle</item> -        <item name="dividerPadding">12dip</item>          <item name="background">@null</item>      </style>      <style name="Widget.Quantum.ButtonBar.AlertDialog">          <item name="background">@null</item> -        <item name="dividerPadding">0dp</item>      </style> -    <style name="Widget.Quantum.ButtonBar.Button"/> -      <style name="Widget.Quantum.SegmentedButton" parent="SegmentedButton">          <item name="background">@drawable/btn_group_holo_dark</item>      </style> @@ -740,7 +731,7 @@ please see styles_device_defaults.xml.          <item name="contentDescription">@string/action_menu_overflow_description</item>      </style> -    <style name="Widget.Quantum.ActionButton.TextButton" parent="Widget.Quantum.ButtonBar.Button"/> +    <style name="Widget.Quantum.ActionButton.TextButton" parent="Widget.Quantum.ButtonBar"/>      <style name="Widget.Quantum.ActionBar.TabView" parent="Widget.ActionBar.TabView">          <item name="background">@drawable/tab_indicator_quantum</item> @@ -1063,8 +1054,7 @@ please see styles_device_defaults.xml.      <style name="WindowTitle.Quantum">          <item name="singleLine">true</item>          <item name="textAppearance">@style/TextAppearance.Quantum.WindowTitle</item> -        <item name="shadowColor">#BB000000</item> -        <item name="shadowRadius">2.75</item> +        <item name="shadowRadius">0</item>      </style>      <style name="DialogWindowTitle.Quantum"> diff --git a/core/res/res/values/themes_quantum.xml b/core/res/res/values/themes_quantum.xml index d39a1f868276..50f1ca68c8f1 100644 --- a/core/res/res/values/themes_quantum.xml +++ b/core/res/res/values/themes_quantum.xml @@ -154,7 +154,7 @@ please see themes_device_defaults.xml.          <item name="windowTitleStyle">@style/WindowTitle.Quantum</item>          <item name="windowTitleSize">25dip</item>          <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Quantum</item> -        <item name="windowContentTransitions">true</item> +        <item name="windowContentTransitions">false</item>          <item name="windowAnimationStyle">@style/Animation.Quantum.Activity</item>          <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>          <item name="windowActionBar">true</item> @@ -162,9 +162,9 @@ please see themes_device_defaults.xml.          <!-- Dialog attributes -->          <item name="dialogTheme">@style/Theme.Quantum.Dialog</item> -        <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item> -        <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item> -        <item name="dialogTitleDecorLayout">@layout/dialog_title_holo</item> +        <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_quantum</item> +        <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_quantum</item> +        <item name="dialogTitleDecorLayout">@layout/dialog_title_quantum</item>          <!-- AlertDialog attributes -->          <item name="alertDialogTheme">@style/Theme.Quantum.Dialog.Alert</item> @@ -488,9 +488,9 @@ please see themes_device_defaults.xml.          <!-- Dialog attributes -->          <item name="dialogTheme">@style/Theme.Quantum.Light.Dialog</item> -        <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item> -        <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item> -        <item name="dialogTitleDecorLayout">@layout/dialog_title_holo</item> +        <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_quantum</item> +        <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_quantum</item> +        <item name="dialogTitleDecorLayout">@layout/dialog_title_quantum</item>          <!-- AlertDialog attributes -->          <item name="alertDialogTheme">@style/Theme.Quantum.Light.Dialog.Alert</item> @@ -694,7 +694,7 @@ please see themes_device_defaults.xml.           with an inverse color profile. The dark action bar sharply stands out against           the light content. -->      <style name="Theme.Quantum.Light.DarkActionBar"> -        <item name="actionBarTheme">@style/Theme.Quantum</item> +        <item name="actionBarWidgetTheme">@style/Theme.Quantum</item>      </style>      <!-- Variant of the quantum (dark) theme with no action bar. --> diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 73d5b7437fc9..0a234aa17279 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -368,7 +368,10 @@                    <span class="en">Media Playback</span></a>                  </li>              <li><a href="<?cs var:toroot ?>guide/topics/media/mediarouter.html"> -                  <span class="en">MediaRouter</span></a> +                  <span class="en">Media Router</span></a> +                </li> +            <li><a href="<?cs var:toroot ?>guide/topics/media/mediarouteprovider.html"> +                  <span class="en">Media Route Provider</span></a>                  </li>              <li><a href="<?cs var:toroot ?>guide/appendix/media-formats.html">                     <span class="en">Supported Media Formats</span></a> diff --git a/docs/html/guide/topics/media/mediarouteprovider.jd b/docs/html/guide/topics/media/mediarouteprovider.jd new file mode 100644 index 000000000000..389fbfb7794f --- /dev/null +++ b/docs/html/guide/topics/media/mediarouteprovider.jd @@ -0,0 +1,453 @@ +page.title=Media Route Provider +page.tags="mediarouteprovider","mediacontrolintent" +@jd:body + +<div id="qv-wrapper"> +  <div id="qv"> +    <h2>In this document</h2> +    <ol> +      <li><a href="#overview">Overview</a> +        <ol> +          <li><a href="#dist">Distribution of route providers</a></li> +          <li><a href="#playback-types">Types of playback</a></li> +          <li><a href="#mr-packages">Media router packages</a></li> +        </ol> +      </li> +      <li><a href="#provider-service">Creating a Provider Service</a></li> +      <li><a href="#route-caps">Specifying Route Capabilities</a> +        <ol> +          <li><a href="#route-cat">Route categories</a></li> +          <li><a href="#media-types">Media types and protocols</a></li> +          <li><a href="#playback-ctrls">Playback controls</a></li> +          <li><a href="#mrpd">MediaRouteProviderDescriptor</a></li> +        </ol> +      </li> +      <li><a href="#ctrl-routes">Controlling Routes</a></li> +    </ol> +    <h2>Key Classes</h2> +    <ol> +      <li>{@link android.support.v7.media.MediaRouteProvider}</li> +      <li>{@link android.support.v7.media.MediaRouteProviderDescriptor}</li> +      <li>{@link android.support.v7.media.MediaRouteProvider.RouteController RouteController}</li> +    </ol> +    <h2>Related Samples</h2> +    <ol> +      <li><a href="{@docRoot}samples/MediaRouter/index.html">MediaRouter</a></li> +    </ol> +  </div> +</div> + +<p>Users want to play media content from their Android devices bigger, brighter, and louder on +  connected playback devices such as televisions, stereos, +  and home theater equipment. As a manufacturer of these devices, allowing Android users to +  instantly show a picture, play a song, or share a video for friends and family using your product +  can make it much more compelling and engaging.</p> + +<p>The Android media router framework allows manufacturers to enable playback on their devices +  through a standardized interface called a {@link android.support.v7.media.MediaRouteProvider}. +  A route provider defines a common interface for playing media on a receiver device, making it +  possible to play media on your equipment from any Android application that supports media +  routes.</p> + +<p>This guide discusses how to create a media route provider for a receiver device and make it +  available to other media playback applications that run on Android.</p> + +<h2 id="overview">Overview</h2> + +<p>The Android media router framework enables media app developers and media playback device +  manufacturers to connect through a common API and common user interface. App developers that +  implement a {@link android.support.v7.media.MediaRouter} interface can then connect to the +  framework and play content to devices that participate in the media router framework. Media +  playback device manufacturers can participate in the framework by publishing a {@link +  android.support.v7.media.MediaRouteProvider} that allows other applications to connect to and +  play media on the receiver devices. Figure 1 illustrates how an app connects to a receiving +  device through the media router framework.</p> + +<img src="{@docRoot}images/mediarouter/media-route-provider-framework.png" alt="" id="figure1"/> +<p class="img-caption"> +  <strong>Figure 1.</strong> Overview of how media route provider classes provide communication +  from a media app to a receiver device. +</p> + +<p>When you build a media route provider for your receiver device, the provider serves the +following purposes:</p> + +<ul> +  <li>Describe and publish the capabilities of the receiver device so other apps can discover it +    and use its playback features.</li> +  <li>Wrap the programming interface of the receiver device and its communication +    transport mechanisms to make the device compatible with the media router framework.</li> +</ul> + + +<h3 id="dist">Distribution of route providers</h3> + +<p>A media route provider is distributed as part of an Android app. Your route provider can be +  made available to other apps by extending +  {@link android.support.v7.media.MediaRouteProviderService} or wrapping your implementation of +  {@link android.support.v7.media.MediaRouteProvider} with your own service and declaring an intent +  filter for the media route provider. These steps allow other apps to discover and make use of +  your media route.</p> + +<p> +  <strong>Note:</strong> The app containing the media route provider can also include a +  <a href="{@docRoot}guide/topics/media/mediarouter.html">MediaRouter</a> interface to the +  route provider, but this is not required. +</p> + + +<h3 id="playback-types">Types of playback</h3> + +<p>There are two main types of playback supported by the media router framework. A media route +  provider can support one or both types of playback, depending on the capabilities of your playback +  equipment and the functionality you want to support:</p> + +<ul> +  <li><strong>Remote Playback</strong> — This approach uses the receiver device to handle the +    content data retrieval, decoding, and playback, while an Android device in the user's hand is +    used as a remote control. This approach is used by Android apps that support +    <a href="https://developers.google.com/cast/">Google Cast</a>.</li> +  <li><strong>Secondary Output</strong> — With this approach, the Android media application +    retrieves, renders and streams video or music directly to the receiver device. This approach is +    used to support Wireless Display output on Android.</li> +</ul> + + +<h3 id="mr-packages">Media router packages</h3> + +<p> +  The media router APIs are provided as part of the Android Support Library version 18 and higher, +  in the <a href="{@docRoot}tools/support-library/features.html#v7-mediarouter">v7-mediarouter</a> +  support library. You should use the classes in the +  {@link android.support.v7.media} package for media route provider functions. +  These APIs are compatible with devices running Android 2.1 (API level 7) and higher. +</p> + +<p class="caution"> +  <strong>Caution:</strong> There is another set of media router APIs provided in the +  {@link android.media} class package that have been superseded by the +  <a href="{@docRoot}tools/support-library/features.html#v7-mediarouter">v7-mediarouter</a> +  support library. You <em>should not</em> use the {@link android.media} classes for +  implementing media route provider functions. +</p> + +<p>In order to use the {@link android.support.v7.media} media router classes, you +  must add the <a href="{@docRoot}tools/support-library/features.html#v7-mediarouter" +  >v7-mediarouter support library package</a> to your app development project. For more +  information on adding support libraries to your app development project, see +  <a href="{@docRoot}tools/support-library/setup.html">Support Library Setup</a>. +</p> + + +<h2 id="provider-service">Creating a Provider Service</h2> + +<p>The media router framework must be able to discover and connect to your media route provider +  to allow other applications to use your route. In order to do this, the media router framework +  looks for apps that declare a media route provider intent action. When another app wants to +  connect to your provider, the framework must be able to invoke and connect to it, so your provider +  must be encapsulated in a {@link android.app.Service}.</p> + +<p>The following example code shows the declaration of a media route provider service and the +  intent filter in a manifest, which allows it to be discovered and used by the media router +  framework:</p> + +<pre> +<service android:name=".provider.SampleMediaRouteProviderService" +    android:label="@string/sample_media_route_provider_service" +    android:process=":mrp"> +    <intent-filter> +        <action android:name="android.media.MediaRouteProviderService" /> +    </intent-filter> +</service> +</pre> + +<p>This manifest example declares a service that wraps the actual media route provider classes. +  The Android media router framework provides the +  {@link android.support.v7.media.MediaRouteProviderService} class for use as a service wrapper for +  media route providers. The following example code demonstrates how to use this wrapper +  class:</p> + +<pre> +public class SampleMediaRouteProviderService extends MediaRouteProviderService { + +    @Override +    public MediaRouteProvider onCreateMediaRouteProvider() { +        return new SampleMediaRouteProvider(this); +    } +} +</pre> + + +<h2 id="route-caps">Specifying Route Capabilities</h2> + +<p>Apps connecting to the media router framework can discover your media route through your +  app's manifest declarations, but they also need to know the capabilities of the media routes you +  are providing. Media routes can be of different types and have different features, and other apps +  need to be able to discover these details to determine if they are compatible with your route.</p> + +<p>The media router framework allows you to define and publish the capabilities of your media +  route through {@link android.content.IntentFilter} objects, {@link +  android.support.v7.media.MediaRouteDescriptor} objects and a {@link +  android.support.v7.media.MediaRouteProviderDescriptor}. This section explains how to use these +  classes to publish the details of your media route for other apps.</p> + + +<h3 id="route-cat">Route categories</h3> + +<p>As part of the programmatic description of your media route provider, you must specify +  whether your provider supports remote playback, secondary output, or both. These are the route +  categories provided by the media router framework:</p> + +<ul> +  <li>{@link android.support.v7.media.MediaControlIntent#CATEGORY_LIVE_AUDIO CATEGORY_LIVE_AUDIO} +    — Output of audio to a secondary output device, such as a wireless-enabled music system. +    </li> +  <li>{@link android.support.v7.media.MediaControlIntent#CATEGORY_LIVE_VIDEO CATEGORY_LIVE_VIDEO} +    — Output of video to a secondary output device, such as Wireless Display devices.</li> +  <li>{@link android.support.v7.media.MediaControlIntent#CATEGORY_REMOTE_PLAYBACK +    CATEGORY_REMOTE_PLAYBACK} — Play video or audio on a separate device which handles media +    retrieval, decoding, and playback, such as +    <a href="https://www.google.com/url?q=http://www.google.com/chromecast">Chromecast</a> devices. +    </li> +</ul> + +<p>In order to include these settings in a description of your media route, you insert them into +  an {@link android.content.IntentFilter} object, which you later add to a +  {@link android.support.v7.media.MediaRouteDescriptor} object:</p> + +<pre> +public final class SampleMediaRouteProvider extends MediaRouteProvider { +    private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC; +    static { +        IntentFilter videoPlayback = new IntentFilter(); +        <strong>videoPlayback.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);</strong> +        CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>(); +        CONTROL_FILTERS_BASIC.add(videoPlayback); +    } +} + +</pre> + +<p>If you specify the {@link android.support.v7.media.MediaControlIntent#CATEGORY_REMOTE_PLAYBACK +  CATEGORY_REMOTE_PLAYBACK} intent, you must also define what media types and +  playback controls are supported by your media route provider. The next section describes how to +  specify these settings for your device.</p> + + +<h3 id="media-types">Media types and protocols</h3> + +<p>A media route provider for a remote playback device must specify the media types and transfer +  protocols it supports. You specify these settings using the {@link android.content.IntentFilter} +  class and the {@link android.content.IntentFilter#addDataScheme addDataScheme()} and +  {@link android.content.IntentFilter#addDataType addDataType()} methods of that object. The +  following code snippet demonstrates how to define an intent filter for supporting remote video +  playback using http, https, and Real Time Streaming Protocol (RTSP):</p> + +<pre> +public final class SampleMediaRouteProvider extends MediaRouteProvider { + +    private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC; + +    static { +        IntentFilter videoPlayback = new IntentFilter(); +        videoPlayback.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); +        videoPlayback.addAction(MediaControlIntent.ACTION_PLAY); +        videoPlayback.addDataScheme("http"); +        videoPlayback.addDataScheme("https"); +        videoPlayback.addDataScheme("rtsp"); +        addDataTypeUnchecked(videoPlayback, "video/*"); +        CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>(); +        CONTROL_FILTERS_BASIC.add(videoPlayback); +    } +    ... + +    private static void addDataTypeUnchecked(IntentFilter filter, String type) { +        try { +            filter.addDataType(type); +        } catch (MalformedMimeTypeException ex) { +            throw new RuntimeException(ex); +        } +    } +} + +</pre> + + +<h3 id="playback-ctrls">Playback controls</h3> + +<p>A media route provider that offers remote playback must specify the types of media controls +  it supports. These are the general types of control that media routes can provide:</p> + +<ul> +  <li><strong>Playback controls</strong>, such as play, pause, rewind, and fast-forward.</li> +  <li><strong>Queuing features</strong>, which allow the sending app to add and remove items +    from a playlist which is maintained by the receiver device.</li> +  <li><strong>Session features</strong>, which prevent sending apps from interfering with each +    other by having the receiver device provide a session id to the requesting app and then checking +    that id with each subsequent playback control request.</li> +</ul> + +<p>The following code example demonstrates how to construct an intent filter for supporting +  basic media route playback controls:</p> + +<pre> +public final class SampleMediaRouteProvider extends MediaRouteProvider { +    private static final ArrayList<IntentFilter> CONTROL_FILTERS_BASIC; +    static { +        ... +        IntentFilter playControls = new IntentFilter(); +        playControls.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); +        playControls.addAction(MediaControlIntent.ACTION_SEEK); +        playControls.addAction(MediaControlIntent.ACTION_GET_STATUS); +        playControls.addAction(MediaControlIntent.ACTION_PAUSE); +        playControls.addAction(MediaControlIntent.ACTION_RESUME); +        playControls.addAction(MediaControlIntent.ACTION_STOP); +        CONTROL_FILTERS_BASIC = new ArrayList<IntentFilter>(); +        CONTROL_FILTERS_BASIC.add(videoPlayback); +        CONTROL_FILTERS_BASIC.add(playControls); +    } +    ... +} +</pre> + +<p>For more information about the available playback control intents, see the +  {@link android.support.v7.media.MediaControlIntent} class.</p> + + +<h3 id="mrpd">MediaRouteProviderDescriptor</h3> + +<p>After defining the capabilities of your media route using {@link +  android.content.IntentFilter} objects, you can then create a descriptor object for publishing to +  the Android media router framework. This descriptor object contains the specifics of your media +  route's capabilities so that other applications can determine how to interact with your media +  route.</p> + +<p>The following example code demonstrates how to add the previously created intent filters to a +  {@link android.support.v7.media.MediaRouteProviderDescriptor} and set the descriptor for use by +  the media router framework:</p> + +<pre> +public SampleMediaRouteProvider(Context context) { +    super(context); +    publishRoutes(); +} + +private void publishRoutes() { +    Resources r = getContext().getResources(); +    // Create a route descriptor using previously created IntentFilters +    MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor.Builder( +            VARIABLE_VOLUME_BASIC_ROUTE_ID, +            r.getString(R.string.variable_volume_basic_route_name)) +            .setDescription(r.getString(R.string.sample_route_description)) +            .addControlFilters(CONTROL_FILTERS_BASIC) +            .setPlaybackStream(AudioManager.STREAM_MUSIC) +            .setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE) +            .setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE) +            .setVolumeMax(VOLUME_MAX) +            .setVolume(mVolume) +            .build(); +    // Add the route descriptor to the provider descriptor +    MediaRouteProviderDescriptor providerDescriptor = +            new MediaRouteProviderDescriptor.Builder() +            .addRoute(routeDescriptor) +            .build(); + +    // Publish the descriptor to the framework +    setDescriptor(providerDescriptor); +} +</pre> + +<p>For more information on the available descriptor settings, see the reference documentation +  for {@link android.support.v7.media.MediaRouteDescriptor} and {@link +  android.support.v7.media.MediaRouteProviderDescriptor}.</p> + + +<h2 id="ctrl-routes">Controlling Routes</h2> + +<p>When an application connects to your media route provider, the provider receives playback +  commands through the media router framework sent to your route by other apps. To handle these +  requests, you must provide an implementation of a {@link +  android.support.v7.media.MediaRouteProvider.RouteController} class, which processes the commands +  and handles the actual communication to your receiver device.</p> + +<p>The media router framework calls the {@link +  android.support.v7.media.MediaRouteProvider#onCreateRouteController onCreateRouteController()} +  method of your route provider to obtain an instance of this class and then routes requests to it. +  These are the key methods of the {@link +  android.support.v7.media.MediaRouteProvider.RouteController} class, which you must implement for +  your media route provider:</p> + +<ul> +  <li>{@link android.support.v7.media.MediaRouteProvider.RouteController#onSelect onSelect()} +    — Called when an application selects your route for playback. You use this method to do +    any preparation work that may be required before media playback begins.</li> +  <li>{@link android.support.v7.media.MediaRouteProvider.RouteController#onControlRequest +    onControlRequest()} — Sends specific playback commands to the receiving device.</li> +  <li>{@link android.support.v7.media.MediaRouteProvider.RouteController#onSetVolume +    onSetVolume()} — Sends a request to the receiving device to set the playback volume to a +    specific value.</li> +  <li>{@link android.support.v7.media.MediaRouteProvider.RouteController#onUpdateVolume +    onUpdateVolume()} — Sends a request to the receiving device to modify the playback +    volume by a specified amount.</li> +  <li>{@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect +    onUnselect()} — Called when an application unselects a route.</li> +  <li>{@link android.support.v7.media.MediaRouteProvider.RouteController#onRelease onRelease()} +    — Called when the route is no longer needed by the framework, allowing it to free its +    resources.</li> +</ul> + +<p>All playback control requests, except for volume changes, are directed to the {@link +  android.support.v7.media.MediaRouteProvider.RouteController#onControlRequest onControlRequest()} +  method. Your implementation of this method must parse the control requests and respond to them +  appropriately. Here is an example implementation of this method which processes commands for a +  remote playback media route:</p> + +<pre> +private final class SampleRouteController extends +        MediaRouteProvider.RouteController { +    ... + +    @Override +    public boolean onControlRequest(Intent intent, ControlRequestCallback callback) { + +        String action = intent.getAction(); + +        if (intent.hasCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { +            boolean success = false; +            if (action.equals(MediaControlIntent.ACTION_PLAY)) { +                success = handlePlay(intent, callback); +            } else if (action.equals(MediaControlIntent.ACTION_ENQUEUE)) { +                success = handleEnqueue(intent, callback); +            } else if (action.equals(MediaControlIntent.ACTION_REMOVE)) { +                success = handleRemove(intent, callback); +            } else if (action.equals(MediaControlIntent.ACTION_SEEK)) { +                success = handleSeek(intent, callback); +            } else if (action.equals(MediaControlIntent.ACTION_GET_STATUS)) { +                success = handleGetStatus(intent, callback); +            } else if (action.equals(MediaControlIntent.ACTION_PAUSE)) { +                success = handlePause(intent, callback); +            } else if (action.equals(MediaControlIntent.ACTION_RESUME)) { +                success = handleResume(intent, callback); +            } else if (action.equals(MediaControlIntent.ACTION_STOP)) { +                success = handleStop(intent, callback); +            } else if (action.equals(MediaControlIntent.ACTION_START_SESSION)) { +                success = handleStartSession(intent, callback); +            } else if (action.equals(MediaControlIntent.ACTION_GET_SESSION_STATUS)) { +                success = handleGetSessionStatus(intent, callback); +            } else if (action.equals(MediaControlIntent.ACTION_END_SESSION)) { +                success = handleEndSession(intent, callback); +            } + +            Log.d(TAG, mSessionManager.toString()); +            return success; +        } +        return false; +    } +    ... +} +</pre> + +<p>It is important to understand that the {@link +  android.support.v7.media.MediaRouteProvider.RouteController} class is intended to act as a wrapper +  for the API to your media playback equipment. The implementation of the methods in this class is +  entirely dependent on the programmatic interface provided by your receiving device.</p> diff --git a/docs/html/guide/topics/media/mediarouter.jd b/docs/html/guide/topics/media/mediarouter.jd index 1b102652b423..e0bf88914899 100644 --- a/docs/html/guide/topics/media/mediarouter.jd +++ b/docs/html/guide/topics/media/mediarouter.jd @@ -1,5 +1,5 @@ -page.title=MediaRouter -page.tags="cast","chromecast","wireless display","miracast" +page.title=Media Router +page.tags="mediarouter","cast","chromecast","wireless display","miracast"  @jd:body  <div id="qv-wrapper"> @@ -36,6 +36,10 @@ page.tags="cast","chromecast","wireless display","miracast"        <li>{@link android.support.v7.media.MediaRouter.Callback}</li>        <li>{@link android.support.v7.media.MediaRouteProvider}</li>      </ol> +    <h2>Related Samples</h2> +    <ol> +      <li><a href="{@docRoot}guide/topics/media/mediarouter.html">MediaRouter</a></li> +    </ol>    </div>  </div> @@ -105,15 +109,17 @@ page.tags="cast","chromecast","wireless display","miracast"    (API level 7) and higher.  </p> -<p class="note"> -  <strong>Note:</strong> There is another set of media router APIs provided in the +<p class="caution"> +  <strong>Caution:</strong> There is another set of media router APIs provided in the    {@link android.media} that have been superseded by the v7-mediarouter support library.    You <em>should not</em> use the {@link android.media} classes for media router functions.  </p>  <p>In order to use the {@link android.support.v7.media} media router classes, you must add    the <a href="{@docRoot}tools/support-library/features.html#v7-mediarouter">v7-mediarouter -  support library package</a> to your app development project. +  support library package</a> to your app development project.  For more +  information on adding support libraries to your app development project, see +  <a href="{@docRoot}tools/support-library/setup.html">Support Library Setup</a>.  </p> @@ -211,9 +217,9 @@ page.tags="cast","chromecast","wireless display","miracast"      CATEGORY_LIVE_VIDEO} — Output of video to a secondary output device, such as Wireless      Display devices.</li>    <li>{@link android.support.v7.media.MediaControlIntent#CATEGORY_REMOTE_PLAYBACK -    CATEGORY_REMOTE_PLAYBACK} — Play video or audio on a separate device that supports the -    <a href="https://developers.google.com/cast/">Google Cast</a> remote control protocol, such -    as <a href="https://www.google.com/url?q=http://www.google.com/chromecast">Chromecast</a>. +    CATEGORY_REMOTE_PLAYBACK} — Play video or audio on a separate device that handles media +    retrieval, decoding, and playback, such as +    <a href="https://www.google.com/url?q=http://www.google.com/chromecast">Chromecast</a> devices.      </li>  </ul> @@ -279,7 +285,7 @@ public boolean onCreateOptionsMenu(Menu menu) {  <p>In order to connect to a media route selected by the user, your app must obtain the {@link    android.support.v7.media.MediaRouter} framework object and then attach a {@link    android.support.v7.media.MediaRouter.Callback} object. The callback object receives messages -  from the media router framework when a route selected, changed or disconnected by the user.</p> +  from the media router framework when a route is selected, changed, or disconnected by the user.</p>  <p>To obtain an instance of the {@link android.support.v7.media.MediaRouter} framework object,    call {@link android.support.v7.media.MediaRouter#getInstance MediaRouter.getInstance()} @@ -299,11 +305,11 @@ public boolean onCreateOptionsMenu(Menu menu) {  <p>The media router framework communicates with an app through a callback object that    you attach to the {@link android.support.v7.media.MediaRouter} framework object. An app    that uses the media router framework must extend the {@link -  android.support.v7.media.MediaRouter.Callback} object to receive messages when a media route is -  connected and provide content to the connected device through that route.</p> +  android.support.v7.media.MediaRouter.Callback} object in order to receive messages when a +  media route is connected.</p> -<p>There are several methods in the callback that can be overwritten to receive messages about -  media router events. At the minimum, your implementation of the {@link +<p>There are several methods in the callback that you can override to receive information about +  media router events. At minimum, your implementation of the {@link    android.support.v7.media.MediaRouter.Callback} class should override the following    methods:</p> @@ -440,12 +446,12 @@ public class MediaRouterPlaybackActivity extends ActionBarActivity {  <p class="note">    <strong>Note:</strong> The media route framework also provides a -  {@link android.support.v7.app.MediaRouteDiscoveryFragment} class which takes care of adding and -  removing the call back for an activity. +  {@link android.support.v7.app.MediaRouteDiscoveryFragment} class, which takes care of adding and +  removing the callback for an activity.  </p>  <p>Now when you run your application, you should see a Cast button appear in your activity. -  When you press the button the media router framework, a route selection dialog appears as shown +  When you touch the button, a route selection dialog appears as shown    in figure 3, allowing your user to select an available media route. Make sure you have a    supported device available on your local network when testing this interface.</p> diff --git a/docs/html/images/mediarouter/media-route-provider-framework.png b/docs/html/images/mediarouter/media-route-provider-framework.png Binary files differnew file mode 100644 index 000000000000..60cc29a35325 --- /dev/null +++ b/docs/html/images/mediarouter/media-route-provider-framework.png diff --git a/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._data.plist b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._data.plist Binary files differnew file mode 100644 index 000000000000..d82ea050f0c0 --- /dev/null +++ b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._data.plist diff --git a/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._image1.png b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._image1.png Binary files differnew file mode 100644 index 000000000000..3435e35bbff4 --- /dev/null +++ b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/._image1.png diff --git a/docs/image_sources/mediarouter/media-route-provider-framework.graffle/data.plist b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/data.plist Binary files differnew file mode 100644 index 000000000000..07791df4a0ed --- /dev/null +++ b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/data.plist diff --git a/docs/image_sources/mediarouter/media-route-provider-framework.graffle/image1.png b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/image1.png Binary files differnew file mode 100644 index 000000000000..d6e3e9591212 --- /dev/null +++ b/docs/image_sources/mediarouter/media-route-provider-framework.graffle/image1.png diff --git a/docs/image_sources/mediarouter/media-router-framework.graffle/data.plist b/docs/image_sources/mediarouter/media-router-framework.graffle/data.plist Binary files differnew file mode 100644 index 000000000000..ffd82121845b --- /dev/null +++ b/docs/image_sources/mediarouter/media-router-framework.graffle/data.plist diff --git a/docs/image_sources/mediarouter/media-router-framework.graffle/image1.png b/docs/image_sources/mediarouter/media-router-framework.graffle/image1.png Binary files differnew file mode 100644 index 000000000000..d6e3e9591212 --- /dev/null +++ b/docs/image_sources/mediarouter/media-router-framework.graffle/image1.png diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index e320c675bae2..1760458ea86e 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -121,20 +121,6 @@ import java.util.Arrays;   * document.</p></div>   */  public abstract class Drawable { -    /** -     * Hotspot identifier mask for tracking touch points. -     * -     * @hide until hotspot APIs are finalized -     */ -    public static final int HOTSPOT_TOUCH_MASK = 0xFF; - -    /** -     * Hotspot identifier for tracking keyboard focus. -     * -     * @hide until hotspot APIs are finalized -     */ -    public static final int HOTSPOT_FOCUS = 0x100; -      private static final Rect ZERO_BOUNDS_RECT = new Rect();      private int[] mStateSet = StateSet.WILD_CARD; diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index f3dd2fc946da..33683ab9f82c 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -60,9 +60,11 @@ import java.util.HashSet;   * The vector drawable has 6 elements:   * <p/>   * <dl> - * <dt><code><vector></code></dt><dd> - * The attribute <code>android:trigger</code> which defines a state change that + * <dt><code><vector></code></dt> + * <dd>The attribute <code>android:trigger</code> defines a state change that   * will drive the animation </dd> + * <dd>The attribute <code>android:versionCode</code> defines the version of + * VectorDrawable </dd>   * <dt><code><size></code></dt>   * <dd>Used to defined the intrinsic Width Height size of the drawable using   * <code>android:width</code> and <code>android:height</code> </dd> @@ -494,6 +496,16 @@ public class VectorDrawable extends Drawable {                  }  else if (SHAPE_VECTOR.equals(tagName)) {                      TypedArray a = res.obtainAttributes(attrs, R.styleable.VectorDrawable);                      animatedPath.setTrigger(a.getInteger(R.styleable.VectorDrawable_trigger, 0)); + +                    // Parsing the version information. +                    // Right now, we only support version "1". +                    // If the xml didn't specify the version number, the default version is "1". +                    int versionCode = a.getInt(R.styleable.VectorDrawable_versionCode, 1); +                    if (versionCode != 1) { +                        throw new IllegalArgumentException( +                                "So far, VectorDrawable only support version 1"); +                    } +                      a.recycle();                  }              } diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h index 649f4c344d64..6f2af908f70d 100644 --- a/include/android_runtime/AndroidRuntime.h +++ b/include/android_runtime/AndroidRuntime.h @@ -34,7 +34,7 @@ namespace android {  class AndroidRuntime  {  public: -    AndroidRuntime(); +    AndroidRuntime(char* argBlockStart, size_t argBlockSize);      virtual ~AndroidRuntime();      enum StartMode { @@ -44,6 +44,8 @@ public:          Tool,      }; +    void setArgv0(const char* argv0); +      /**       * Register a set of methods in the specified class.       */ @@ -120,6 +122,8 @@ private:      Vector<JavaVMOption> mOptions;      bool mExitWithoutCleanup; +    char* const mArgBlockStart; +    const size_t mArgBlockLength;      /* JNI JavaVM pointer */      static JavaVM* mJavaVM; diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 34d98a105f33..663b67ef053c 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -61,8 +61,12 @@ RenderNode::~RenderNode() {  void RenderNode::destroyDisplayListDeferred(RenderNode* displayList) {      if (displayList) { -        DISPLAY_LIST_LOGD("Deferring display list destruction"); -        Caches::getInstance().deleteDisplayListDeferred(displayList); +        if (Caches::hasInstance()) { +            DISPLAY_LIST_LOGD("Deferring display list destruction"); +            Caches::getInstance().deleteDisplayListDeferred(displayList); +        } else { +            delete displayList; +        }      }  } diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp index 3975a766a8e5..e7e7768ffe91 100644 --- a/libs/hwui/RenderProperties.cpp +++ b/libs/hwui/RenderProperties.cpp @@ -45,28 +45,24 @@ RenderProperties::PrimitiveFields::PrimitiveFields()          , mPrevWidth(-1), mPrevHeight(-1)          , mPivotExplicitlySet(false)          , mMatrixDirty(false) -        , mMatrixIsIdentity(true)          , mMatrixFlags(0)          , mCaching(false) {  }  RenderProperties::ComputedFields::ComputedFields()          : mTransformMatrix(NULL) -        , mTransformCamera(NULL)          , mTransformMatrix3D(NULL)          , mClipPath(NULL) {  }  RenderProperties::ComputedFields::~ComputedFields() {      delete mTransformMatrix; -    delete mTransformCamera;      delete mTransformMatrix3D;      delete mClipPath;  }  RenderProperties::RenderProperties() -        : mCameraDistance(0) -        , mStaticMatrix(NULL) +        : mStaticMatrix(NULL)          , mAnimationMatrix(NULL) {  } @@ -82,9 +78,12 @@ RenderProperties& RenderProperties::operator=(const RenderProperties& other) {          setAnimationMatrix(other.getAnimationMatrix());          setCameraDistance(other.getCameraDistance()); -        // Update the computed fields -        updateMatrix(); +        // Update the computed clip path          updateClipPath(); + +        // Force recalculation of the matrix, since other's dirty bit may be clear +        mPrimitiveFields.mMatrixDirty = true; +        updateMatrix();      }      return *this;  } @@ -106,8 +105,8 @@ void RenderProperties::debugOutputProperties(const int level) const {              ALOGD("%*sTranslate %.2f, %.2f, %.2f",                      level * 2, "", mPrimitiveFields.mTranslationX, mPrimitiveFields.mTranslationY, mPrimitiveFields.mTranslationZ);          } else { -            ALOGD("%*sConcatMatrix %p: " MATRIX_4_STRING, -                    level * 2, "", mComputedFields.mTransformMatrix, MATRIX_4_ARGS(mComputedFields.mTransformMatrix)); +            ALOGD("%*sConcatMatrix %p: " SK_MATRIX_STRING, +                    level * 2, "", mComputedFields.mTransformMatrix, SK_MATRIX_ARGS(mComputedFields.mTransformMatrix));          }      } @@ -141,7 +140,7 @@ void RenderProperties::updateMatrix() {          if (mPrimitiveFields.mMatrixFlags && mPrimitiveFields.mMatrixFlags != TRANSLATION) {              if (!mComputedFields.mTransformMatrix) {                  // only allocate a mPrimitiveFields.matrix if we have a complex transform -                mComputedFields.mTransformMatrix = new Matrix4(); +                mComputedFields.mTransformMatrix = new SkMatrix();              }              if (!mPrimitiveFields.mPivotExplicitlySet) {                  if (mPrimitiveFields.mWidth != mPrimitiveFields.mPrevWidth || mPrimitiveFields.mHeight != mPrimitiveFields.mPrevHeight) { @@ -153,33 +152,31 @@ void RenderProperties::updateMatrix() {              }              if ((mPrimitiveFields.mMatrixFlags & ROTATION_3D) == 0) { -                mComputedFields.mTransformMatrix->loadTranslate( -                        mPrimitiveFields.mPivotX + mPrimitiveFields.mTranslationX, -                        mPrimitiveFields.mPivotY + mPrimitiveFields.mTranslationY, -                        0); -                mComputedFields.mTransformMatrix->rotate(mPrimitiveFields.mRotation, 0, 0, 1); -                mComputedFields.mTransformMatrix->scale(mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY, 1); -                mComputedFields.mTransformMatrix->translate(-mPrimitiveFields.mPivotX, -mPrimitiveFields.mPivotY); +                mComputedFields.mTransformMatrix->setTranslate( +                        mPrimitiveFields.mTranslationX, mPrimitiveFields.mTranslationY); +                mComputedFields.mTransformMatrix->preRotate(mPrimitiveFields.mRotation, +                        mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY); +                mComputedFields.mTransformMatrix->preScale( +                        mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY, +                        mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY);              } else { -                if (!mComputedFields.mTransformCamera) { -                    mComputedFields.mTransformCamera = new Sk3DView(); +                if (!mComputedFields.mTransformMatrix3D) {                      mComputedFields.mTransformMatrix3D = new SkMatrix();                  } -                SkMatrix transformMatrix; -                transformMatrix.reset(); -                mComputedFields.mTransformCamera->save(); -                transformMatrix.preScale(mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY, mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY); -                mComputedFields.mTransformCamera->rotateX(mPrimitiveFields.mRotationX); -                mComputedFields.mTransformCamera->rotateY(mPrimitiveFields.mRotationY); -                mComputedFields.mTransformCamera->rotateZ(-mPrimitiveFields.mRotation); -                mComputedFields.mTransformCamera->getMatrix(mComputedFields.mTransformMatrix3D); +                mComputedFields.mTransformMatrix->reset(); +                mComputedFields.mTransformCamera.save(); +                mComputedFields.mTransformMatrix->preScale( +                        mPrimitiveFields.mScaleX, mPrimitiveFields.mScaleY, +                        mPrimitiveFields.mPivotX, mPrimitiveFields.mPivotY); +                mComputedFields.mTransformCamera.rotateX(mPrimitiveFields.mRotationX); +                mComputedFields.mTransformCamera.rotateY(mPrimitiveFields.mRotationY); +                mComputedFields.mTransformCamera.rotateZ(-mPrimitiveFields.mRotation); +                mComputedFields.mTransformCamera.getMatrix(mComputedFields.mTransformMatrix3D);                  mComputedFields.mTransformMatrix3D->preTranslate(-mPrimitiveFields.mPivotX, -mPrimitiveFields.mPivotY);                  mComputedFields.mTransformMatrix3D->postTranslate(mPrimitiveFields.mPivotX + mPrimitiveFields.mTranslationX,                          mPrimitiveFields.mPivotY + mPrimitiveFields.mTranslationY); -                transformMatrix.postConcat(*mComputedFields.mTransformMatrix3D); -                mComputedFields.mTransformCamera->restore(); - -                mComputedFields.mTransformMatrix->load(transformMatrix); +                mComputedFields.mTransformMatrix->postConcat(*mComputedFields.mTransformMatrix3D); +                mComputedFields.mTransformCamera.restore();              }          }          mPrimitiveFields.mMatrixDirty = false; diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h index 061e469abe3b..dd6821059490 100644 --- a/libs/hwui/RenderProperties.h +++ b/libs/hwui/RenderProperties.h @@ -258,20 +258,20 @@ public:          return mPrimitiveFields.mPivotY;      } +    bool isPivotExplicitlySet() const { +        return mPrimitiveFields.mPivotExplicitlySet; +    } +      void setCameraDistance(float distance) { -        if (distance != mCameraDistance) { -            mCameraDistance = distance; +        if (distance != getCameraDistance()) {              mPrimitiveFields.mMatrixDirty = true; -            if (!mComputedFields.mTransformCamera) { -                mComputedFields.mTransformCamera = new Sk3DView(); -                mComputedFields.mTransformMatrix3D = new SkMatrix(); -            } -            mComputedFields.mTransformCamera->setCameraLocation(0, 0, distance); +            mComputedFields.mTransformCamera.setCameraLocation(0, 0, distance);          }      }      float getCameraDistance() const { -        return mCameraDistance; +        // TODO: update getCameraLocationZ() to be const +        return const_cast<Sk3DView*>(&mComputedFields.mTransformCamera)->getCameraLocationZ();      }      void setLeft(int left) { @@ -396,7 +396,7 @@ public:          return mPrimitiveFields.mMatrixFlags;      } -    const Matrix4* getTransformMatrix() const { +    const SkMatrix* getTransformMatrix() const {          return mComputedFields.mTransformMatrix;      } @@ -481,13 +481,11 @@ private:          int mPrevWidth, mPrevHeight;          bool mPivotExplicitlySet;          bool mMatrixDirty; -        bool mMatrixIsIdentity;          uint32_t mMatrixFlags;          bool mCaching;      } mPrimitiveFields;      // mCameraDistance isn't in mPrimitiveFields as it has a complex setter -    float mCameraDistance;      SkMatrix* mStaticMatrix;      SkMatrix* mAnimationMatrix; @@ -502,11 +500,12 @@ private:           * Stores the total transformation of the DisplayList based upon its scalar           * translate/rotate/scale properties.           * -         * In the common translation-only case, the matrix isn't allocated and the mTranslation -         * properties are used directly. +         * In the common translation-only case, the matrix isn't necessarily allocated, +         * and the mTranslation properties are used directly.           */ -        Matrix4* mTransformMatrix; -        Sk3DView* mTransformCamera; +        SkMatrix* mTransformMatrix; + +        Sk3DView mTransformCamera;          SkMatrix* mTransformMatrix3D;          SkPath* mClipPath; // TODO: remove this, create new ops for efficient/special case clipping          SkRegion::Op mClipPathOp; diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h index cc6d0cda003e..5bdb18abf873 100644 --- a/libs/hwui/Snapshot.h +++ b/libs/hwui/Snapshot.h @@ -108,7 +108,7 @@ public:       * Returns the current clip in local coordinates. The clip rect is       * transformed by the inverse transform matrix.       */ -    const Rect& getLocalClip(); +    ANDROID_API const Rect& getLocalClip();      /**       * Resets the clip to the specified rect. diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index c016d085709b..440653a39fa3 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -1,4 +1,4 @@ - /* +/*   * Copyright (C) 2013 The Android Open Source Project   *   * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,7 +27,6 @@ import android.os.Looper;  import android.os.Message;  import android.os.Parcel;  import android.util.Log; -import android.content.Context;  /**   * MediaDrm can be used to obtain keys for decrypting protected media streams, in @@ -98,6 +97,8 @@ public final class MediaDrm {      private final static String TAG = "MediaDrm"; +    private static final String PERMISSION = android.Manifest.permission.ACCESS_DRM_CERTIFICATES; +      private EventHandler mEventHandler;      private OnEventListener mOnEventListener; @@ -152,7 +153,7 @@ public final class MediaDrm {      }      private static final native boolean isCryptoSchemeSupportedNative(byte[] uuid, -                                                                      String mimeType); +            String mimeType);      /**       * Instantiate a MediaDrm object @@ -176,7 +177,7 @@ public final class MediaDrm {           * It's easier to create it here than in C++.           */          native_setup(new WeakReference<MediaDrm>(this), -                     getByteArrayFromUUID(uuid)); +                getByteArrayFromUUID(uuid));      }      /** @@ -285,7 +286,7 @@ public final class MediaDrm {       * the cookie passed to native_setup().)       */      private static void postEventFromNative(Object mediadrm_ref, -                                            int eventType, int extra, Object obj) +            int eventType, int extra, Object obj)      {          MediaDrm md = (MediaDrm)((WeakReference)mediadrm_ref).get();          if (md == null) { @@ -385,9 +386,8 @@ public final class MediaDrm {       * problem with the certifcate       */      public native KeyRequest getKeyRequest(byte[] scope, byte[] init, -                                           String mimeType, int keyType, -                                           HashMap<String, String> optionalParameters) -        throws NotProvisionedException; +            String mimeType, int keyType, HashMap<String, String> optionalParameters) +            throws NotProvisionedException;      /** @@ -411,7 +411,7 @@ public final class MediaDrm {       * @throws ResourceBusyException if required resources are in use       */      public native byte[] provideKeyResponse(byte[] scope, byte[] response) -        throws NotProvisionedException, DeniedByServerException; +            throws NotProvisionedException, DeniedByServerException;      /** @@ -478,7 +478,7 @@ public final class MediaDrm {      }      private native ProvisionRequest getProvisionRequestNative(int certType, -                                                              String certAuthority); +            String certAuthority);      /**       * After a provision response is received by the app, it is provided to the DRM @@ -491,12 +491,12 @@ public final class MediaDrm {       * server rejected the request       */      public void provideProvisionResponse(byte[] response) -        throws DeniedByServerException { +            throws DeniedByServerException {          provideProvisionResponseNative(response);      }      private native Certificate provideProvisionResponseNative(byte[] response) -        throws DeniedByServerException; +            throws DeniedByServerException;      /**       * A means of enforcing limits on the number of concurrent streams per subscriber @@ -583,23 +583,22 @@ public final class MediaDrm {      private static final native void setCipherAlgorithmNative(MediaDrm drm, byte[] sessionId, -                                                              String algorithm); +            String algorithm);      private static final native void setMacAlgorithmNative(MediaDrm drm, byte[] sessionId, -                                                           String algorithm); +            String algorithm);      private static final native byte[] encryptNative(MediaDrm drm, byte[] sessionId, -                                                     byte[] keyId, byte[] input, byte[] iv); +            byte[] keyId, byte[] input, byte[] iv);      private static final native byte[] decryptNative(MediaDrm drm, byte[] sessionId, -                                                     byte[] keyId, byte[] input, byte[] iv); +            byte[] keyId, byte[] input, byte[] iv);      private static final native byte[] signNative(MediaDrm drm, byte[] sessionId, -                                                  byte[] keyId, byte[] message); +            byte[] keyId, byte[] message);      private static final native boolean verifyNative(MediaDrm drm, byte[] sessionId, -                                                     byte[] keyId, byte[] message, -                                                     byte[] signature); +            byte[] keyId, byte[] message, byte[] signature);      /**       * In addition to supporting decryption of DASH Common Encrypted Media, the @@ -629,7 +628,7 @@ public final class MediaDrm {          private byte[] mSessionId;          CryptoSession(MediaDrm drm, byte[] sessionId, -                      String cipherAlgorithm, String macAlgorithm) +                String cipherAlgorithm, String macAlgorithm)          {              mSessionId = sessionId;              mDrm = drm; @@ -704,8 +703,7 @@ public final class MediaDrm {       * "algorithms".       */      public CryptoSession getCryptoSession(byte[] sessionId, -                                          String cipherAlgorithm, -                                          String macAlgorithm) +            String cipherAlgorithm, String macAlgorithm)      {          return new CryptoSession(this, sessionId, cipherAlgorithm, macAlgorithm);      } @@ -751,11 +749,11 @@ public final class MediaDrm {       * @hide - not part of the public API at this time       */      public CertificateRequest getCertificateRequest(int certType, -                                                    String certAuthority) +            String certAuthority)      {          ProvisionRequest provisionRequest = getProvisionRequestNative(certType, certAuthority);          return new CertificateRequest(provisionRequest.getData(), -                                      provisionRequest.getDefaultUrl()); +                provisionRequest.getDefaultUrl());      }      /** @@ -800,18 +798,16 @@ public final class MediaDrm {       * @hide - not part of the public API at this time       */      public Certificate provideCertificateResponse(byte[] response) -        throws DeniedByServerException { +            throws DeniedByServerException {          return provideProvisionResponseNative(response);      }      private static final native byte[] signRSANative(MediaDrm drm, byte[] sessionId, -                                                     String algorithm, byte[] wrappedKey, -                                                     byte[] message); +            String algorithm, byte[] wrappedKey, byte[] message);      /**       * Sign data using an RSA key       * -     * @param context the app context       * @param sessionId a sessionId obtained from openSession on the MediaDrm object       * @param algorithm the signing algorithm to use, e.g. "PKCS1-BlockType1"       * @param wrappedKey - the wrapped (encrypted) RSA private key obtained @@ -820,7 +816,8 @@ public final class MediaDrm {       *       * @hide - not part of the public API at this time       */ -    public byte[] signRSA(Context context, byte[] sessionId, String algorithm, byte[] wrappedKey, byte[] message) { +    public byte[] signRSA(byte[] sessionId, String algorithm, +            byte[] wrappedKey, byte[] message) {          return signRSANative(this, sessionId, algorithm, wrappedKey, message);      } diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index 1dbaa3a1ce7f..7c4568241c40 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -570,7 +570,7 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) {      FIND_CLASS(clazz, "android/media/MediaDrm$Certificate");      GET_FIELD_ID(gFields.certificate.wrappedPrivateKey, clazz, "mWrappedKey", "[B");      GET_FIELD_ID(gFields.certificate.certificateData, clazz, "mCertificateData", "[B"); -    gFields.certificateClassId = reinterpret_cast<jclass>(env->NewGlobalRef(clazz)); +    gFields.certificateClassId = static_cast<jclass>(env->NewGlobalRef(clazz));      FIND_CLASS(clazz, "java/util/ArrayList");      GET_METHOD_ID(gFields.arraylist.init, clazz, "<init>", "()V"); @@ -595,13 +595,13 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) {      GET_METHOD_ID(gFields.entry.getValue, clazz, "getValue", "()Ljava/lang/Object;");      FIND_CLASS(clazz, "java/util/HashMap"); -    gFields.hashmapClassId = reinterpret_cast<jclass>(env->NewGlobalRef(clazz)); +    gFields.hashmapClassId = static_cast<jclass>(env->NewGlobalRef(clazz));      FIND_CLASS(clazz, "java/lang/String"); -    gFields.stringClassId = reinterpret_cast<jclass>(env->NewGlobalRef(clazz)); +    gFields.stringClassId = static_cast<jclass>(env->NewGlobalRef(clazz));      FIND_CLASS(clazz, "java/util/ArrayList"); -    gFields.arraylistClassId = reinterpret_cast<jclass>(env->NewGlobalRef(clazz)); +    gFields.arraylistClassId = static_cast<jclass>(env->NewGlobalRef(clazz));  }  static void android_media_MediaDrm_native_setup( diff --git a/media/lib/signer/java/com/android/mediadrm/signer/MediaDrmSigner.java b/media/lib/signer/java/com/android/mediadrm/signer/MediaDrmSigner.java index d971afb9789c..0a2897f9cf44 100644 --- a/media/lib/signer/java/com/android/mediadrm/signer/MediaDrmSigner.java +++ b/media/lib/signer/java/com/android/mediadrm/signer/MediaDrmSigner.java @@ -16,7 +16,6 @@  package com.android.mediadrm.signer; -import android.content.Context;  import android.media.MediaDrm;  import android.media.DeniedByServerException; @@ -37,7 +36,7 @@ public final class MediaDrmSigner {       * server       */      public final static class CertificateRequest { -        private MediaDrm.CertificateRequest mCertRequest; +        private final MediaDrm.CertificateRequest mCertRequest;          CertificateRequest(MediaDrm.CertificateRequest certRequest) {              mCertRequest = certRequest; @@ -65,7 +64,7 @@ public final class MediaDrmSigner {       * with a certificate.       */      public final static class Certificate { -        private MediaDrm.Certificate mCertificate; +        private final MediaDrm.Certificate mCertificate;          Certificate(MediaDrm.Certificate certificate) {              mCertificate = certificate; @@ -97,7 +96,7 @@ public final class MediaDrmSigner {       * the chain of authority.       */      public static CertificateRequest getCertificateRequest(MediaDrm drm, int certType, -                                                           String certAuthority) { +            String certAuthority) {          return new CertificateRequest(drm.getCertificateRequest(certType, certAuthority));      } @@ -117,14 +116,13 @@ public final class MediaDrmSigner {       * server rejected the request       */      public static Certificate provideCertificateResponse(MediaDrm drm, byte[] response) -        throws DeniedByServerException { +            throws DeniedByServerException {          return new Certificate(drm.provideCertificateResponse(response));      }      /**       * Sign data using an RSA key       * -     * @param context the App context       * @param drm the MediaDrm object       * @param sessionId a sessionId obtained from openSession on the MediaDrm object       * @param algorithm the signing algorithm to use, e.g. "PKCS1-BlockType1" @@ -132,8 +130,8 @@ public final class MediaDrmSigner {       * from provideCertificateResponse       * @param message the data for which a signature is to be computed       */ -    public static byte[] signRSA(Context context, MediaDrm drm, byte[] sessionId, -                                 String algorithm, byte[] wrappedKey, byte[] message) { -        return drm.signRSA(context, sessionId, algorithm, wrappedKey, message); +    public static byte[] signRSA(MediaDrm drm, byte[] sessionId, +            String algorithm, byte[] wrappedKey, byte[] message) { +        return drm.signRSA(sessionId, algorithm, wrappedKey, message);      }  } diff --git a/packages/BackupRestoreConfirmation/AndroidManifest.xml b/packages/BackupRestoreConfirmation/AndroidManifest.xml index 4fb26ae447bf..8141fa72e56f 100644 --- a/packages/BackupRestoreConfirmation/AndroidManifest.xml +++ b/packages/BackupRestoreConfirmation/AndroidManifest.xml @@ -1,20 +1,21 @@  <?xml version="1.0" encoding="utf-8"?>  <!-- -** Copyright 2011, 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. +/* + * Copyright (c) 2014 Google Inc. + * + * 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. + */  --> -  <manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.android.backupconfirm" > diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml index 179bcd17d633..6b77a7ca695f 100644 --- a/packages/DocumentsUI/AndroidManifest.xml +++ b/packages/DocumentsUI/AndroidManifest.xml @@ -42,7 +42,7 @@          <activity              android:name=".SettingsActivity"              android:label="@string/menu_settings" -            android:theme="@android:style/Theme.Holo.Light.DialogWhenLarge" +            android:theme="@android:style/Theme.DeviceDefault.Light.DialogWhenLarge"              android:exported="false" />          <provider diff --git a/packages/DocumentsUI/res/values-sw720dp/styles.xml b/packages/DocumentsUI/res/values-sw720dp/styles.xml index 19d2ebebaa97..8d31444e837b 100644 --- a/packages/DocumentsUI/res/values-sw720dp/styles.xml +++ b/packages/DocumentsUI/res/values-sw720dp/styles.xml @@ -15,11 +15,11 @@  -->  <resources xmlns:android="http://schemas.android.com/apk/res/android"> -    <style name="Theme" parent="@android:style/Theme.Holo.Light"> +    <style name="Theme" parent="@android:style/Theme.DeviceDefault.Light">          <item name="android:actionOverflowButtonStyle">@style/DarkerOverflow</item>          <item name="android:windowBackground">@*android:drawable/dialog_full_holo_light</item>          <item name="android:colorBackgroundCacheHint">@null</item>          <item name="android:windowIsTranslucent">true</item> -        <item name="android:windowAnimationStyle">@*android:style/Animation.Holo.Dialog</item> +        <item name="android:windowAnimationStyle">@*android:style/Animation.DeviceDefault.Dialog</item>      </style>  </resources> diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml index 0c8f7127811a..a416eb4ef633 100644 --- a/packages/DocumentsUI/res/values/styles.xml +++ b/packages/DocumentsUI/res/values/styles.xml @@ -29,11 +29,11 @@      <!-- Normally just a redirection, but this is used to make ourselves a           dialog on large tablets --> -    <style name="Theme" parent="@android:style/Theme.Holo.Light"> +    <style name="Theme" parent="@android:style/Theme.DeviceDefault.Light">          <item name="android:actionOverflowButtonStyle">@style/DarkerOverflow</item>      </style> -    <style name="DarkerOverflow" parent="@android:style/Widget.Holo.Light.ActionButton.Overflow"> +    <style name="DarkerOverflow" parent="@android:style/Widget.DeviceDefault.Light.ActionButton.Overflow">          <item name="android:src">@drawable/ic_menu_overflow</item>      </style> diff --git a/packages/Keyguard/res/values/styles.xml b/packages/Keyguard/res/values/styles.xml index d4f98affee90..80fcf7574ebf 100644 --- a/packages/Keyguard/res/values/styles.xml +++ b/packages/Keyguard/res/values/styles.xml @@ -68,7 +68,7 @@          <item name="android:textSize">@dimen/widget_big_font_size</item>      </style> -    <style name="Widget.TransportControl.SeekBar" parent="@android:style/Widget.Holo.SeekBar"> +    <style name="Widget.TransportControl.SeekBar" parent="@android:style/Widget.DeviceDefault.Light.SeekBar">          <item name="android:indeterminateOnly">false</item>          <item name="android:progressDrawable">@drawable/scrubber_progress_horizontal_holo_light</item>          <item name="android:indeterminateDrawable">@drawable/scrubber_progress_horizontal_holo_light</item> diff --git a/packages/Keyguard/test/AndroidManifest.xml b/packages/Keyguard/test/AndroidManifest.xml index b801e4be809a..163812741a01 100644 --- a/packages/Keyguard/test/AndroidManifest.xml +++ b/packages/Keyguard/test/AndroidManifest.xml @@ -23,7 +23,7 @@      <application android:label="@string/app_name" android:icon="@drawable/app_icon">          <activity android:name=".KeyguardTestActivity"                  android:label="@string/app_name" -                android:theme="@android:style/Theme.Holo"> +                android:theme="@android:style/Theme.DeviceDefault.Light">              <intent-filter>                  <action android:name="android.intent.action.MAIN" />                  <category android:name="android.intent.category.LAUNCHER" /> diff --git a/packages/PrintSpooler/res/layout/select_printer_activity.xml b/packages/PrintSpooler/res/layout/select_printer_activity.xml index 6fc77df16f28..4488b6ac5403 100644 --- a/packages/PrintSpooler/res/layout/select_printer_activity.xml +++ b/packages/PrintSpooler/res/layout/select_printer_activity.xml @@ -61,7 +61,7 @@                  android:layout_width="fill_parent"                  android:layout_height="wrap_content"                  android:indeterminate="true" -                style="@android:style/Widget.Holo.ProgressBar.Horizontal"> +                style="@android:style/Widget.DeviceDefault.Light.ProgressBar.Horizontal">              </ProgressBar>          </LinearLayout> diff --git a/packages/PrintSpooler/res/values/themes.xml b/packages/PrintSpooler/res/values/themes.xml index 86f4a3716110..94ab8958284b 100644 --- a/packages/PrintSpooler/res/values/themes.xml +++ b/packages/PrintSpooler/res/values/themes.xml @@ -16,7 +16,7 @@  <resources> -    <style name="PrintJobConfigActivityTheme" parent="@android:style/Theme.Holo.Light.NoActionBar"> +    <style name="PrintJobConfigActivityTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">          <item name="android:windowBackground">@android:color/transparent</item>          <item name="android:windowSoftInputMode">stateAlwaysHidden|adjustResize</item>          <item name="android:windowIsTranslucent">true</item> @@ -25,11 +25,11 @@          <item name="android:windowIsFloating">true</item>      </style> -    <style name="SelectPrinterActivityTheme" parent="@android:style/Theme.Holo.Light"> +    <style name="SelectPrinterActivityTheme" parent="@android:style/Theme.DeviceDefault.Light">          <item name="android:actionBarStyle">@style/SelectPrinterActivityActionBarStyle</item>      </style> -    <style name="SelectPrinterActivityActionBarStyle" parent="@android:style/Widget.Holo.ActionBar"> +    <style name="SelectPrinterActivityActionBarStyle" parent="@android:style/Widget.DeviceDefault.Light.ActionBar">          <item name="android:displayOptions">showTitle</item>      </style> diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 29e8d1dad952..19286c89d84b 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -1,3 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright (c) 2014 Google Inc. + * + * 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. + */ +-->  <manifest xmlns:android="http://schemas.android.com/apk/res/android"          package="com.android.shell"          coreApp="true" @@ -83,7 +101,7 @@          <activity              android:name=".BugreportWarningActivity" -            android:theme="@*android:style/Theme.Holo.Dialog.Alert" +            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"              android:finishOnCloseSystemDialogs="true"              android:excludeFromRecents="true"              android:exported="false" /> diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index b09cc1d97383..3424eed796f4 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -1,3 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright (c) 2014 Google Inc. + * + * 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. + */ +-->  <manifest xmlns:android="http://schemas.android.com/apk/res/android"          xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"          package="com.android.systemui" @@ -157,7 +175,7 @@          <activity android:name=".usb.UsbConfirmActivity"              android:exported="true"              android:permission="android.permission.MANAGE_USB" -            android:theme="@*android:style/Theme.Holo.Dialog.Alert" +            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"              android:finishOnCloseSystemDialogs="true"              android:excludeFromRecents="true">          </activity> @@ -166,7 +184,7 @@          <activity android:name=".usb.UsbPermissionActivity"              android:exported="true"              android:permission="android.permission.MANAGE_USB" -            android:theme="@*android:style/Theme.Holo.Dialog.Alert" +            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"              android:finishOnCloseSystemDialogs="true"              android:excludeFromRecents="true">          </activity> @@ -175,7 +193,7 @@          <activity android:name=".usb.UsbResolverActivity"              android:exported="true"              android:permission="android.permission.MANAGE_USB" -            android:theme="@*android:style/Theme.Holo.Dialog.Alert" +            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"              android:finishOnCloseSystemDialogs="true"              android:excludeFromRecents="true">          </activity> @@ -184,7 +202,7 @@          <activity android:name=".usb.UsbAccessoryUriActivity"              android:exported="true"              android:permission="android.permission.MANAGE_USB" -            android:theme="@*android:style/Theme.Holo.Dialog.Alert" +            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"              android:finishOnCloseSystemDialogs="true"              android:excludeFromRecents="true">          </activity> @@ -192,7 +210,7 @@          <!-- started from UsbDebuggingManager -->          <activity android:name=".usb.UsbDebuggingActivity"              android:permission="android.permission.MANAGE_USB" -            android:theme="@*android:style/Theme.Holo.Dialog.Alert" +            android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"              android:finishOnCloseSystemDialogs="true"              android:excludeFromRecents="true">          </activity> @@ -202,7 +220,7 @@              android:name=".net.NetworkOverLimitActivity"              android:exported="true"              android:permission="android.permission.MANAGE_NETWORK_POLICY" -            android:theme="@android:style/Theme.Holo.Panel" +            android:theme="@android:style/Theme.DeviceDefault.Light.Panel"              android:finishOnCloseSystemDialogs="true"              android:launchMode="singleTop"              android:taskAffinity="com.android.systemui.net" diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml index f5ce22227c03..96da21fe41ba 100644 --- a/packages/SystemUI/res/layout/recents_task_view.xml +++ b/packages/SystemUI/res/layout/recents_task_view.xml @@ -28,21 +28,29 @@          android:layout_gravity="top|center_horizontal"          android:background="#e6444444">          <ImageView -            android:id="@+id/activity_icon" -            android:layout_width="@dimen/recents_task_view_icon_size" -            android:layout_height="@dimen/recents_task_view_icon_size" -            android:layout_gravity="top|left" +            android:id="@+id/application_icon" +            android:layout_width="@dimen/recents_task_view_application_icon_size" +            android:layout_height="@dimen/recents_task_view_application_icon_size" +            android:layout_gravity="center_vertical|left"              android:padding="8dp" />          <TextView              android:id="@+id/activity_description"              android:layout_width="match_parent"              android:layout_height="wrap_content"              android:layout_gravity="center_vertical|left" -            android:layout_marginLeft="@dimen/recents_task_view_icon_size" +            android:layout_marginLeft="@dimen/recents_task_view_application_icon_size" +            android:layout_marginRight="@dimen/recents_task_view_activity_icon_size"              android:textSize="24sp"              android:textColor="#ffffffff"              android:text="@string/recents_empty_message"              android:fontFamily="sans-serif-thin" /> +        <ImageView +            android:id="@+id/activity_icon" +            android:layout_width="@dimen/recents_task_view_activity_icon_size" +            android:layout_height="@dimen/recents_task_view_activity_icon_size" +            android:layout_gravity="center_vertical|right" +            android:padding="12dp" +            android:visibility="invisible" />      </com.android.systemui.recents.views.TaskBarView>  </com.android.systemui.recents.views.TaskView> diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 1da66bbc446d..a7ec064f0d54 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -24,19 +24,10 @@      android:id="@+id/notification_panel"      android:layout_width="0dp"      android:layout_height="wrap_content" -    android:background="@drawable/notification_panel_bg"      android:paddingTop="@dimen/notification_panel_padding_top"      android:layout_marginStart="@dimen/notification_panel_margin_left"      > -    <View -        android:id="@+id/handle" -        android:layout_width="match_parent" -        android:layout_height="@dimen/close_handle_height" -        android:background="@drawable/status_bar_close" -        android:visibility="invisible" -        /> -      <include          layout="@layout/carrier_label"          android:layout_height="@dimen/carrier_label_height" @@ -69,6 +60,7 @@              />          <FrameLayout +            android:id="@+id/notification_container_parent"              android:layout_width="match_parent"              android:layout_height="wrap_content"              > @@ -77,21 +69,6 @@                  android:layout_width="match_parent"                  android:layout_height="wrap_content"                  /> -     -            <ScrollView -                android:id="@+id/scroll" -                android:layout_width="match_parent" -                android:layout_height="wrap_content" -                android:fadingEdge="none" -                android:overScrollMode="ifContentScrolls" -                > -                <com.android.systemui.statusbar.policy.NotificationRowLayout -                    android:id="@+id/latestItems" -                    android:layout_width="match_parent" -                    android:layout_height="wrap_content" -                    systemui:rowHeight="@dimen/notification_row_min_height" -                    /> -            </ScrollView>              <com.android.systemui.statusbar.stack.NotificationStackScrollLayout                      android:id="@+id/notification_stack_scroller" diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 38e108344797..1c6d5ad0b98c 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -230,8 +230,11 @@      <!-- Default distance from each snap target that GlowPadView considers a "hit" -->      <dimen name="glowpadview_inner_radius">15dip</dimen> -    <!-- The size of the icon in the recents task view. --> -    <dimen name="recents_task_view_icon_size">60dp</dimen> +    <!-- The size of the application icon in the recents task view. --> +    <dimen name="recents_task_view_application_icon_size">60dp</dimen> + +    <!-- The size of the activity icon in the recents task view. --> +    <dimen name="recents_task_view_activity_icon_size">60dp</dimen>      <!-- Space below the notification stack -->      <dimen name="notification_stack_margin_bottom">0dp</dimen> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 14af02096c54..76cadd79bfa5 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -16,12 +16,12 @@  <resources xmlns:android="http://schemas.android.com/apk/res/android"> -    <style name="RecentsStyle" parent="@android:style/Theme.Holo.Wallpaper.NoTitleBar"> +    <style name="RecentsStyle" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">          <item name="android:windowAnimationStyle">@style/Animation.RecentsActivity</item>      </style>      <!-- Alternate Recents theme --> -    <style name="RecentsTheme" parent="@android:style/Theme.Holo.Wallpaper.NoTitleBar"> +    <style name="RecentsTheme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">          <item name="android:windowTranslucentStatus">true</item>          <item name="android:windowTranslucentNavigation">true</item>          <item name="android:windowAnimationStyle">@style/Animation.RecentsActivity</item> diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java index 90b0c490f86e..1832d37f7c55 100644 --- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java +++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java @@ -34,6 +34,8 @@ import android.view.View.OnClickListener;  import android.view.ViewConfiguration;  import android.view.ViewGroup; +import com.android.systemui.statusbar.policy.ScrollAdapter; +  public class ExpandHelper implements Gefingerpoken, OnClickListener {      public interface Callback {          View getChildAtRawPosition(float x, float y); @@ -609,19 +611,5 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {          }          mVibrator.vibrate(duration, AudioManager.STREAM_SYSTEM);      } - -    public interface ScrollAdapter { - -        /** -         * @return Whether the view returned by {@link #getHostView()} is scrolled to the top -         * and can therefore be expanded by a single finger drag -         */ -        public boolean isScrolledToTop(); - -        /** -         * @return The view in which the scrolling is performed -         */ -        public View getHostView(); -    }  } diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java index 227e19dd58d4..8543b97f864d 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java @@ -23,35 +23,26 @@ import android.content.ComponentName;  import android.content.Context;  import android.content.Intent;  import android.content.ServiceConnection; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager;  import android.content.res.Configuration;  import android.content.res.Resources;  import android.graphics.Bitmap;  import android.graphics.Canvas;  import android.graphics.Matrix; -import android.graphics.Paint;  import android.graphics.Rect; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable;  import android.os.Bundle;  import android.os.Handler;  import android.os.IBinder;  import android.os.Message;  import android.os.Messenger;  import android.os.RemoteException; -import android.os.SystemProperties;  import android.os.UserHandle;  import android.util.DisplayMetrics; -import android.util.Log;  import android.view.Display;  import android.view.Surface;  import android.view.SurfaceControl;  import android.view.View;  import android.view.WindowManager;  import com.android.systemui.R; -import com.android.systemui.RecentsComponent; -import com.android.systemui.SystemUI;  import java.util.List; @@ -113,6 +104,7 @@ public class AlternateRecentsComponent {      final static String sRecentsService = "com.android.systemui.recents.RecentsService";      Context mContext; +    SystemServicesProxy mSystemServicesProxy;      // Recents service binding      Messenger mService = null; @@ -127,6 +119,7 @@ public class AlternateRecentsComponent {      public AlternateRecentsComponent(Context context) {          mContext = context; +        mSystemServicesProxy = new SystemServicesProxy(context);          mMessenger = new Messenger(new RecentsMessageHandler());      } @@ -219,17 +212,16 @@ public class AlternateRecentsComponent {      /** Loads the first task thumbnail */      Bitmap loadFirstTaskThumbnail() { -        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); -        List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1, -                ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_PROFILES, +        SystemServicesProxy ssp = mSystemServicesProxy; +        List<ActivityManager.RecentTaskInfo> tasks = ssp.getRecentTasks(1,                  UserHandle.CURRENT.getIdentifier());          for (ActivityManager.RecentTaskInfo t : tasks) {              // Skip tasks in the home stack -            if (am.isInHomeStack(t.persistentId)) { +            if (ssp.isInHomeStack(t.persistentId)) {                  return null;              } -            Bitmap thumbnail = am.getTaskTopThumbnail(t.persistentId); +            Bitmap thumbnail = ssp.getTaskThumbnail(t.persistentId);              return thumbnail;          }          return null; @@ -237,13 +229,12 @@ public class AlternateRecentsComponent {      /** Returns whether there is a first task */      boolean hasFirstTask() { -        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); -        List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1, -                ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_PROFILES, +        SystemServicesProxy ssp = mSystemServicesProxy; +        List<ActivityManager.RecentTaskInfo> tasks = ssp.getRecentTasks(1,                  UserHandle.CURRENT.getIdentifier());          for (ActivityManager.RecentTaskInfo t : tasks) {              // Skip tasks in the home stack -            if (am.isInHomeStack(t.persistentId)) { +            if (ssp.isInHomeStack(t.persistentId)) {                  continue;              } @@ -294,8 +285,8 @@ public class AlternateRecentsComponent {          // If Recents is the front most activity, then we should just communicate with it directly          // to launch the first task or dismiss itself -        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); -        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1); +        SystemServicesProxy ssp = mSystemServicesProxy; +        List<ActivityManager.RunningTaskInfo> tasks = ssp.getRunningTasks(1);          if (!tasks.isEmpty()) {              ComponentName topActivity = tasks.get(0).topActivity; diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java index 2b08141fef16..8c5c8fa15f84 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java @@ -31,6 +31,12 @@ public class Constants {              public static final boolean EnableToggleNewRecentsActivity = false;              // This disables the bitmap and icon caches to              public static final boolean DisableBackgroundCache = false; +            // For debugging, this enables us to create mock recents tasks +            public static final boolean EnableSystemServicesProxy = false; +            // For debugging, this defines the number of mock recents packages to create +            public static final int SystemServicesProxyMockPackageCount = 12; +            // For debugging, this defines the number of mock recents tasks to create +            public static final int SystemServicesProxyMockTaskCount = 75;              // Timing certain paths              public static final String TimeRecentsStartupKey = "startup"; @@ -73,8 +79,6 @@ public class Constants {          public static class RecentsTaskLoader {              // XXX: This should be calculated on the first load              public static final int PreloadFirstTasksCount = 5; -            // For debugging, this allows us to multiply the number of cards for each task -            public static final int TaskEntryMultiplier = 1;          }          public static class TaskStackView { diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java index 928c7324c323..e193a95420f8 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java @@ -20,7 +20,6 @@ import android.app.ActivityManager;  import android.content.ComponentCallbacks2;  import android.content.Context;  import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager;  import android.content.res.Resources;  import android.graphics.Bitmap;  import android.graphics.Canvas; @@ -109,18 +108,20 @@ class TaskResourceLoader implements Runnable {      Handler mLoadThreadHandler;      Handler mMainThreadHandler; +    SystemServicesProxy mSystemServicesProxy;      TaskResourceLoadQueue mLoadQueue; -    DrawableLruCache mIconCache; +    DrawableLruCache mApplicationIconCache;      BitmapLruCache mThumbnailCache;      boolean mCancelled;      boolean mWaitingOnLoadQueue;      /** Constructor, creates a new loading thread that loads task resources in the background */ -    public TaskResourceLoader(TaskResourceLoadQueue loadQueue, DrawableLruCache iconCache, +    public TaskResourceLoader(TaskResourceLoadQueue loadQueue, +                              DrawableLruCache applicationIconCache,                                BitmapLruCache thumbnailCache) {          mLoadQueue = loadQueue; -        mIconCache = iconCache; +        mApplicationIconCache = applicationIconCache;          mThumbnailCache = thumbnailCache;          mMainThreadHandler = new Handler();          mLoadThread = new HandlerThread("Recents-TaskResourceLoader"); @@ -135,6 +136,7 @@ class TaskResourceLoader implements Runnable {          Console.log(Constants.DebugFlags.App.TaskDataLoader, "[TaskResourceLoader|start]");          mContext = context;          mCancelled = false; +        mSystemServicesProxy = new SystemServicesProxy(context);          // Notify the load thread to start loading          synchronized(mLoadThread) {              mLoadThread.notifyAll(); @@ -146,6 +148,7 @@ class TaskResourceLoader implements Runnable {          Console.log(Constants.DebugFlags.App.TaskDataLoader, "[TaskResourceLoader|stop]");          // Mark as cancelled for the thread to pick up          mCancelled = true; +        mSystemServicesProxy = null;          // If we are waiting for the load queue for more tasks, then we can just reset the          // Context now, since nothing is using it          if (mWaitingOnLoadQueue) { @@ -175,66 +178,60 @@ class TaskResourceLoader implements Runnable {                      }                  }              } else { +                SystemServicesProxy ssp = mSystemServicesProxy; +                  // Load the next item from the queue                  Pair<Task, Boolean> nextTaskData = mLoadQueue.nextTask();                  final Task t = nextTaskData.first;                  final boolean forceLoadTask = nextTaskData.second;                  if (t != null) { -                    try { -                        Drawable loadIcon = mIconCache.get(t.key); -                        Bitmap loadThumbnail = mThumbnailCache.get(t.key); -                        Console.log(Constants.DebugFlags.App.TaskDataLoader, -                                "  [TaskResourceLoader|load]", -                                t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail + -                                        " forceLoad: " + forceLoadTask); -                        // Load the icon -                        if (loadIcon == null || forceLoadTask) { -                            PackageManager pm = mContext.getPackageManager(); -                            ActivityInfo info = pm.getActivityInfo(t.key.baseIntent.getComponent(), -                                    PackageManager.GET_META_DATA); -                            Drawable icon = info.loadIcon(pm); -                            if (!mCancelled) { -                                if (icon != null) { -                                    Console.log(Constants.DebugFlags.App.TaskDataLoader, -                                            "    [TaskResourceLoader|loadIcon]", -                                            icon); -                                    loadIcon = icon; -                                    mIconCache.put(t.key, icon); -                                } -                            } -                        } -                        // Load the thumbnail -                        if (loadThumbnail == null || forceLoadTask) { -                            ActivityManager am = (ActivityManager) -                                    mContext.getSystemService(Context.ACTIVITY_SERVICE); -                            Bitmap thumbnail = am.getTaskTopThumbnail(t.key.id); -                            if (!mCancelled) { -                                if (thumbnail != null) { -                                    Console.log(Constants.DebugFlags.App.TaskDataLoader, -                                            "    [TaskResourceLoader|loadThumbnail]", -                                            thumbnail); -                                    loadThumbnail = thumbnail; -                                    mThumbnailCache.put(t.key, thumbnail); -                                } else { -                                    Console.logError(mContext, -                                            "Failed to load task top thumbnail for: " + -                                                    t.key.baseIntent.getComponent().getPackageName()); -                                } +                    Drawable loadIcon = mApplicationIconCache.get(t.key); +                    Bitmap loadThumbnail = mThumbnailCache.get(t.key); +                    Console.log(Constants.DebugFlags.App.TaskDataLoader, +                            "  [TaskResourceLoader|load]", +                            t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail + +                                    " forceLoad: " + forceLoadTask); +                    // Load the application icon +                    if (loadIcon == null || forceLoadTask) { +                        ActivityInfo info = ssp.getActivityInfo(t.key.baseIntent.getComponent()); +                        Drawable icon = ssp.getActivityIcon(info); +                        if (!mCancelled) { +                            if (icon != null) { +                                Console.log(Constants.DebugFlags.App.TaskDataLoader, +                                        "    [TaskResourceLoader|loadIcon]", +                                        icon); +                                loadIcon = icon; +                                mApplicationIconCache.put(t.key, icon);                              }                          } +                    } +                    // Load the thumbnail +                    if (loadThumbnail == null || forceLoadTask) { +                        Bitmap thumbnail = ssp.getTaskThumbnail(t.key.id);                          if (!mCancelled) { -                            // Notify that the task data has changed -                            final Drawable newIcon = loadIcon; -                            final Bitmap newThumbnail = loadThumbnail; -                            mMainThreadHandler.post(new Runnable() { -                                @Override -                                public void run() { -                                    t.notifyTaskDataLoaded(newThumbnail, newIcon, forceLoadTask); -                                } -                            }); +                            if (thumbnail != null) { +                                Console.log(Constants.DebugFlags.App.TaskDataLoader, +                                        "    [TaskResourceLoader|loadThumbnail]", +                                        thumbnail); +                                loadThumbnail = thumbnail; +                                mThumbnailCache.put(t.key, thumbnail); +                            } else { +                                Console.logError(mContext, +                                        "Failed to load task top thumbnail for: " + +                                                t.key.baseIntent.getComponent().getPackageName()); +                            }                          } -                    } catch (PackageManager.NameNotFoundException ne) { -                        ne.printStackTrace(); +                    } +                    if (!mCancelled) { +                        // Notify that the task data has changed +                        final Drawable newIcon = loadIcon; +                        final Bitmap newThumbnail = loadThumbnail; +                        mMainThreadHandler.post(new Runnable() { +                            @Override +                            public void run() { +                                t.notifyTaskDataLoaded(newThumbnail, newIcon, forceLoadTask); +                            } +                        });                      }                  } @@ -296,7 +293,8 @@ class BitmapLruCache extends LruCache<Task.TaskKey, Bitmap> {  public class RecentsTaskLoader {      static RecentsTaskLoader sInstance; -    DrawableLruCache mIconCache; +    SystemServicesProxy mSystemServicesProxy; +    DrawableLruCache mApplicationIconCache;      BitmapLruCache mThumbnailCache;      TaskResourceLoadQueue mLoadQueue;      TaskResourceLoader mLoader; @@ -304,7 +302,7 @@ public class RecentsTaskLoader {      int mMaxThumbnailCacheSize;      int mMaxIconCacheSize; -    BitmapDrawable mDefaultIcon; +    BitmapDrawable mDefaultApplicationIcon;      Bitmap mDefaultThumbnail;      /** Private Constructor */ @@ -324,11 +322,12 @@ public class RecentsTaskLoader {                  "[RecentsTaskLoader|init]", "thumbnailCache: " + thumbnailCacheSize +                  " iconCache: " + iconCacheSize); -        // Initialize the cache and loaders +        // Initialize the proxy, cache and loaders +        mSystemServicesProxy = new SystemServicesProxy(context);          mLoadQueue = new TaskResourceLoadQueue(); -        mIconCache = new DrawableLruCache(iconCacheSize); +        mApplicationIconCache = new DrawableLruCache(iconCacheSize);          mThumbnailCache = new BitmapLruCache(thumbnailCacheSize); -        mLoader = new TaskResourceLoader(mLoadQueue, mIconCache, mThumbnailCache); +        mLoader = new TaskResourceLoader(mLoadQueue, mApplicationIconCache, mThumbnailCache);          // Create the default assets          Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); @@ -339,10 +338,10 @@ public class RecentsTaskLoader {          c.setBitmap(mDefaultThumbnail);          c.drawColor(0x00000000);          c.setBitmap(null); -        mDefaultIcon = new BitmapDrawable(context.getResources(), icon); +        mDefaultApplicationIcon = new BitmapDrawable(context.getResources(), icon);          Console.log(Constants.DebugFlags.App.TaskDataLoader,                  "[RecentsTaskLoader|defaultBitmaps]", -                "icon: " + mDefaultIcon + " thumbnail: " + mDefaultThumbnail, Console.AnsiRed); +                "icon: " + mDefaultApplicationIcon + " thumbnail: " + mDefaultThumbnail, Console.AnsiRed);      }      /** Initializes the recents task loader */ @@ -358,6 +357,11 @@ public class RecentsTaskLoader {          return sInstance;      } +    /** Returns the system services proxy */ +    public SystemServicesProxy getSystemServicesProxy() { +        return mSystemServicesProxy; +    } +      /** Reload the set of recent tasks */      SpaceNode reload(Context context, int preloadCount) {          Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]"); @@ -367,141 +371,118 @@ public class RecentsTaskLoader {          SpaceNode root = new SpaceNode(context);          root.setStack(stack); -        try { -            long t1 = System.currentTimeMillis(); - -            PackageManager pm = context.getPackageManager(); -            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); +        long t1 = System.currentTimeMillis(); -            // Get the recent tasks -            List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(25, -                    ActivityManager.RECENT_IGNORE_UNAVAILABLE | -                    ActivityManager.RECENT_INCLUDE_PROFILES, UserHandle.CURRENT.getIdentifier()); -            Collections.reverse(tasks); -            Console.log(Constants.DebugFlags.App.TimeSystemCalls, -                    "[RecentsTaskLoader|getRecentTasks]", -                    "" + (System.currentTimeMillis() - t1) + "ms"); -            Console.log(Constants.DebugFlags.App.TaskDataLoader, -                    "[RecentsTaskLoader|tasks]", "" + tasks.size()); +        // Get the recent tasks +        SystemServicesProxy ssp = mSystemServicesProxy; +        List<ActivityManager.RecentTaskInfo> tasks = +                ssp.getRecentTasks(25, UserHandle.CURRENT.getIdentifier()); +        Collections.reverse(tasks); +        Console.log(Constants.DebugFlags.App.TimeSystemCalls, +                "[RecentsTaskLoader|getRecentTasks]", +                "" + (System.currentTimeMillis() - t1) + "ms"); +        Console.log(Constants.DebugFlags.App.TaskDataLoader, +                "[RecentsTaskLoader|tasks]", "" + tasks.size()); -            // Remove home/recents tasks -            Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator(); -            while (iter.hasNext()) { -                ActivityManager.RecentTaskInfo t = iter.next(); +        // Remove home/recents tasks +        Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator(); +        while (iter.hasNext()) { +            ActivityManager.RecentTaskInfo t = iter.next(); -                // Skip tasks in the home stack -                if (am.isInHomeStack(t.persistentId)) { -                    iter.remove(); -                    continue; -                } -                // Skip tasks from this Recents package -                if (t.baseIntent.getComponent().getPackageName().equals(context.getPackageName())) { -                    iter.remove(); -                    continue; -                } +            // Skip tasks in the home stack +            if (ssp.isInHomeStack(t.persistentId)) { +                iter.remove(); +                continue;              } +            // Skip tasks from this Recents package +            if (t.baseIntent.getComponent().getPackageName().equals(context.getPackageName())) { +                iter.remove(); +                continue; +            } +        } -            // Add each task to the task stack -            t1 = System.currentTimeMillis(); -            int taskCount = tasks.size(); -            for (int i = 0; i < taskCount; i++) { -                ActivityManager.RecentTaskInfo t = tasks.get(i); -                ActivityInfo info = pm.getActivityInfo(t.baseIntent.getComponent(), -                        PackageManager.GET_META_DATA); -                String title = info.loadLabel(pm).toString(); -                boolean isForemostTask = (i == (taskCount - 1)); - -                // Preload the specified number of apps -                if (i >= (taskCount - preloadCount)) { -                    Console.log(Constants.DebugFlags.App.TaskDataLoader, -                            "[RecentsTaskLoader|preloadTask]", -                            "i: " + i + " task: " + t.baseIntent.getComponent().getPackageName()); - -                    String label = (t.activityLabel == null ? title : t.activityLabel.toString()); -                    BitmapDrawable bd = null; -                    if (t.activityIcon != null) { -                        bd = new BitmapDrawable(res, t.activityIcon); +        // Add each task to the task stack +        t1 = System.currentTimeMillis(); +        int taskCount = tasks.size(); +        for (int i = 0; i < taskCount; i++) { +            ActivityManager.RecentTaskInfo t = tasks.get(i); +            ActivityInfo info = ssp.getActivityInfo(t.baseIntent.getComponent()); +            String activityLabel = (t.activityLabel == null ? ssp.getActivityLabel(info) : +                    t.activityLabel.toString()); +            Bitmap activityIcon = t.activityIcon; +            boolean isForemostTask = (i == (taskCount - 1)); + +            // Create a new task +            Task task = new Task(t.persistentId, (t.id > -1), t.baseIntent, activityLabel, +                    activityIcon); + +            // Preload the specified number of apps +            if (i >= (taskCount - preloadCount)) { +                Console.log(Constants.DebugFlags.App.TaskDataLoader, +                        "[RecentsTaskLoader|preloadTask]", +                        "i: " + i + " task: " + t.baseIntent.getComponent().getPackageName()); + +                // Load the icon (if possible and not the foremost task, from the cache) +                if (!isForemostTask) { +                    task.applicationIcon = mApplicationIconCache.get(task.key); +                    if (task.applicationIcon != null) { +                        // Even though we get things from the cache, we should update them +                        // if they've changed in the bg +                        tasksToForceLoad.add(task);                      } -                    Task task = new Task(t.persistentId, (t.id > -1), t.baseIntent, label, bd); - -                    // Load the icon (if possible and not the foremost task, from the cache) -                    if (task.icon != null) { -                        mIconCache.put(task.key, task.icon); +                } +                if (task.applicationIcon == null) { +                    task.applicationIcon = ssp.getActivityIcon(info); +                    if (task.applicationIcon != null) { +                        mApplicationIconCache.put(task.key, task.applicationIcon);                      } else { -                        if (!isForemostTask) { -                            task.icon = mIconCache.get(task.key); -                            if (task.icon != null) { -                                // Even though we get things from the cache, we should update them -                                // if they've changed in the bg -                                tasksToForceLoad.add(task); -                            } -                        } -                        if (task.icon == null) { -                            task.icon = info.loadIcon(pm); -                            if (task.icon != null) { -                                mIconCache.put(task.key, task.icon); -                            } else { -                                task.icon = mDefaultIcon; -                            } -                        } -                    } - -                    // Load the thumbnail (if possible and not the foremost task, from the cache) -                    if (!isForemostTask) { -                        task.thumbnail = mThumbnailCache.get(task.key); -                        if (task.thumbnail != null) { -                            // Even though we get things from the cache, we should update them if -                            // they've changed in the bg -                            tasksToForceLoad.add(task); -                        } -                    } -                    if (task.thumbnail == null) { -                        Console.log(Constants.DebugFlags.App.TaskDataLoader, -                                "[RecentsTaskLoader|loadingTaskThumbnail]"); -                        task.thumbnail = am.getTaskTopThumbnail(t.id); -                        if (task.thumbnail != null) { -                            mThumbnailCache.put(task.key, task.thumbnail); -                        } else { -                            task.thumbnail = mDefaultThumbnail; -                        } +                        task.applicationIcon = mDefaultApplicationIcon;                      } +                } -                    // Create as many tasks a we want to multiply by -                    for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) { -                        Console.log(Constants.DebugFlags.App.TaskDataLoader, -                                "  [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName()); -                        stack.addTask(task); +                // Load the thumbnail (if possible and not the foremost task, from the cache) +                if (!isForemostTask) { +                    task.thumbnail = mThumbnailCache.get(task.key); +                    if (task.thumbnail != null) { +                        // Even though we get things from the cache, we should update them if +                        // they've changed in the bg +                        tasksToForceLoad.add(task);                      } -                } else { -                    // Create as many tasks a we want to multiply by -                    for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) { -                        Console.log(Constants.DebugFlags.App.TaskDataLoader, -                                "  [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName()); -                        stack.addTask(new Task(t.persistentId, (t.id > -1), t.baseIntent, title, -                                null, null)); +                } +                if (task.thumbnail == null) { +                    Console.log(Constants.DebugFlags.App.TaskDataLoader, +                            "[RecentsTaskLoader|loadingTaskThumbnail]"); +                    task.thumbnail = ssp.getTaskThumbnail(task.key.id); +                    if (task.thumbnail != null) { +                        mThumbnailCache.put(task.key, task.thumbnail); +                    } else { +                        task.thumbnail = mDefaultThumbnail;                      }                  }              } -            Console.log(Constants.DebugFlags.App.TimeSystemCalls, -                    "[RecentsTaskLoader|getAllTaskTopThumbnail]", -                    "" + (System.currentTimeMillis() - t1) + "ms"); - -            /* -            // Get all the stacks -            t1 = System.currentTimeMillis(); -            List<ActivityManager.StackInfo> stackInfos = ams.getAllStackInfos(); -            Console.log(Constants.DebugFlags.App.TimeSystemCalls, "[RecentsTaskLoader|getAllStackInfos]", "" + (System.currentTimeMillis() - t1) + "ms"); -            Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|stacks]", "" + tasks.size()); -            for (ActivityManager.StackInfo s : stackInfos) { -                Console.log(Constants.DebugFlags.App.TaskDataLoader, "  [RecentsTaskLoader|stack]", s.toString()); -                if (stacks.containsKey(s.stackId)) { -                    stacks.get(s.stackId).setRect(s.bounds); -                } + +            // Add the task to the stack +            Console.log(Constants.DebugFlags.App.TaskDataLoader, +                "  [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName()); +            stack.addTask(task); +        } +        Console.log(Constants.DebugFlags.App.TimeSystemCalls, +                "[RecentsTaskLoader|getAllTaskTopThumbnail]", +                "" + (System.currentTimeMillis() - t1) + "ms"); + +        /* +        // Get all the stacks +        t1 = System.currentTimeMillis(); +        List<ActivityManager.StackInfo> stackInfos = ams.getAllStackInfos(); +        Console.log(Constants.DebugFlags.App.TimeSystemCalls, "[RecentsTaskLoader|getAllStackInfos]", "" + (System.currentTimeMillis() - t1) + "ms"); +        Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|stacks]", "" + tasks.size()); +        for (ActivityManager.StackInfo s : stackInfos) { +            Console.log(Constants.DebugFlags.App.TaskDataLoader, "  [RecentsTaskLoader|stack]", s.toString()); +            if (stacks.containsKey(s.stackId)) { +                stacks.get(s.stackId).setRect(s.bounds);              } -            */ -        } catch (Exception e) { -            e.printStackTrace();          } +        */          // Start the task loader          mLoader.start(context); @@ -516,16 +497,16 @@ public class RecentsTaskLoader {      /** Acquires the task resource data from the pool. */      public void loadTaskData(Task t) { -        Drawable icon = mIconCache.get(t.key); +        Drawable applicationIcon = mApplicationIconCache.get(t.key);          Bitmap thumbnail = mThumbnailCache.get(t.key);          Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|loadTask]", -                t + " icon: " + icon + " thumbnail: " + thumbnail + +                t + " applicationIcon: " + applicationIcon + " thumbnail: " + thumbnail +                          " thumbnailCacheSize: " + mThumbnailCache.size());          boolean requiresLoad = false; -        if (icon == null) { -            icon = mDefaultIcon; +        if (applicationIcon == null) { +            applicationIcon = mDefaultApplicationIcon;              requiresLoad = true;          }          if (thumbnail == null) { @@ -535,7 +516,7 @@ public class RecentsTaskLoader {          if (requiresLoad) {              mLoadQueue.addTask(t, false);          } -        t.notifyTaskDataLoaded(thumbnail, icon, false); +        t.notifyTaskDataLoaded(thumbnail, applicationIcon, false);      }      /** Releases the task resource data back into the pool. */ @@ -545,7 +526,7 @@ public class RecentsTaskLoader {                  " thumbnailCacheSize: " + mThumbnailCache.size());          mLoadQueue.removeTask(t); -        t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultIcon); +        t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultApplicationIcon);      }      /** Completely removes the resource data from the pool. */ @@ -555,8 +536,8 @@ public class RecentsTaskLoader {          mLoadQueue.removeTask(t);          mThumbnailCache.remove(t.key); -        mIconCache.remove(t.key); -        t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultIcon); +        mApplicationIconCache.remove(t.key); +        t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultApplicationIcon);      }      /** Stops the task loader and clears all pending tasks */ @@ -579,19 +560,19 @@ public class RecentsTaskLoader {              case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:                  // We are leaving recents, so trim the data a bit                  mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 2); -                mIconCache.trimToSize(mMaxIconCacheSize / 2); +                mApplicationIconCache.trimToSize(mMaxIconCacheSize / 2);                  break;              case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:              case ComponentCallbacks2.TRIM_MEMORY_MODERATE:                  // We are going to be low on memory                  mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 4); -                mIconCache.trimToSize(mMaxIconCacheSize / 4); +                mApplicationIconCache.trimToSize(mMaxIconCacheSize / 4);                  break;              case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:              case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:                  // We are low on memory, so release everything                  mThumbnailCache.evictAll(); -                mIconCache.evictAll(); +                mApplicationIconCache.evictAll();                  break;              default:                  break; diff --git a/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java new file mode 100644 index 000000000000..f147fbc6f265 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/SystemServicesProxy.java @@ -0,0 +1,186 @@ +/* + * 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.systemui.recents; + +import android.app.ActivityManager; +import android.app.ActivityOptions; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Acts as a shim around the real system services that we need to access data from, and provides + * a point of injection when testing UI. + */ +public class SystemServicesProxy { +    ActivityManager mAm; +    PackageManager mPm; +    String mPackage; + +    Bitmap mDummyIcon; + +    /** Private constructor */ +    public SystemServicesProxy(Context context) { +        mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); +        mPm = context.getPackageManager(); +        mPackage = context.getPackageName(); + +        if (Constants.DebugFlags.App.EnableSystemServicesProxy) { +            // Create a dummy icon +            mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8); +            Canvas c = new Canvas(mDummyIcon); +            c.drawColor(0xFFFF0000); +            c.setBitmap(null); +        } +    } + +    /** Returns a list of the recents tasks */ +    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numTasks, int userId) { +        if (mAm == null) return null; + +        // If we are mocking, then create some recent tasks +        if (Constants.DebugFlags.App.EnableSystemServicesProxy) { +            ArrayList<ActivityManager.RecentTaskInfo> tasks = +                    new ArrayList<ActivityManager.RecentTaskInfo>(); +            int count = Math.min(numTasks, Constants.DebugFlags.App.SystemServicesProxyMockTaskCount); +            for (int i = 0; i < count; i++) { +                // Create a dummy component name +                int packageIndex = i % Constants.DebugFlags.App.SystemServicesProxyMockPackageCount; +                ComponentName cn = new ComponentName("com.android.test" + packageIndex, +                        "com.android.test" + i + ".Activity"); +                // Create the recent task info +                ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); +                rti.id = rti.persistentId = i; +                rti.baseIntent = new Intent(); +                rti.baseIntent.setComponent(cn); +                rti.description = rti.activityLabel = +                        Long.toString(Math.abs(new Random().nextLong()), 36); +                if (i % 2 == 0) { +                    rti.activityIcon = Bitmap.createBitmap(mDummyIcon); +                } +                tasks.add(rti); +            } +            return tasks; +        } + +        return mAm.getRecentTasksForUser(numTasks, +                ActivityManager.RECENT_IGNORE_UNAVAILABLE | +                ActivityManager.RECENT_INCLUDE_PROFILES, userId); +    } + +    /** Returns a list of the running tasks */ +    public List<ActivityManager.RunningTaskInfo> getRunningTasks(int numTasks) { +        if (mAm == null) return null; +        return mAm.getRunningTasks(numTasks); +    } + +    /** Returns whether the specified task is in the home stack */ +    public boolean isInHomeStack(int taskId) { +        if (mAm == null) return false; + +        // If we are mocking, then just return false +        if (Constants.DebugFlags.App.EnableSystemServicesProxy) { +            return false; +        } + +        return mAm.isInHomeStack(taskId); +    } + +    /** Returns the top task thumbnail for the given task id */ +    public Bitmap getTaskThumbnail(int taskId) { +        if (mAm == null) return null; + +        // If we are mocking, then just return a dummy thumbnail +        if (Constants.DebugFlags.App.EnableSystemServicesProxy) { +            Bitmap thumbnail = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); +            Canvas c = new Canvas(thumbnail); +            c.drawColor(0xFF00ff00); +            c.setBitmap(null); +            return thumbnail; +        } + +        return mAm.getTaskTopThumbnail(taskId); +    } + +    /** Moves a task to the front with the specified activity options */ +    public void moveTaskToFront(int taskId, ActivityOptions opts) { +        if (mAm == null) return; +        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return; + +        if (opts != null) { +            mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME, +                    opts.toBundle()); +        } else { +            mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME); +        } +    } + +    /** Removes the task and kills the process */ +    public void removeTask(int taskId) { +        if (mAm == null) return; +        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return; + +        mAm.removeTask(taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); +    } + +    /** Returns the activity info for a given component name */ +    public ActivityInfo getActivityInfo(ComponentName cn) { +        if (mPm == null) return null; +        if (Constants.DebugFlags.App.EnableSystemServicesProxy) return null; + +        try { +            return mPm.getActivityInfo(cn, PackageManager.GET_META_DATA); +        } catch (PackageManager.NameNotFoundException e) { +            e.printStackTrace(); +            return null; +        } +    } + +    /** Returns the activity label */ +    public String getActivityLabel(ActivityInfo info) { +        if (mPm == null) return null; + +        // If we are mocking, then return a mock label +        if (Constants.DebugFlags.App.EnableSystemServicesProxy) { +            return "Recent Task"; +        } + +        return info.loadLabel(mPm).toString(); +    } + +    /** Returns the activity icon */ +    public Drawable getActivityIcon(ActivityInfo info) { +        if (mPm == null) return null; + +        // If we are mocking, then return a mock label +        if (Constants.DebugFlags.App.EnableSystemServicesProxy) { +            return new ColorDrawable(0xFFff0000); +        } + +        return info.loadIcon(mPm); +    } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java index 677334d7297b..ed2ab2a5b91f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java @@ -19,7 +19,6 @@ package com.android.systemui.recents.model;  import android.content.Intent;  import android.graphics.Bitmap;  import android.graphics.drawable.Drawable; -import com.android.systemui.recents.Constants;  /** @@ -61,23 +60,19 @@ public class Task {      }      public TaskKey key; -    public String title; -    public Drawable icon; +    public Drawable applicationIcon; +    public String activityLabel; +    public Bitmap activityIcon;      public Bitmap thumbnail;      public boolean isActive;      TaskCallbacks mCb; -    public Task(int id, boolean isActive, Intent intent, String activityTitle, Drawable icon) { -        this(id, isActive, intent, activityTitle, icon, null); -    } - -    public Task(int id, boolean isActive, Intent intent, String activityTitle, Drawable icon, -                Bitmap thumbnail) { +    public Task(int id, boolean isActive, Intent intent, String activityTitle, +                Bitmap activityIcon) {          this.key = new TaskKey(id, intent); -        this.title = activityTitle; -        this.icon = icon; -        this.thumbnail = thumbnail; +        this.activityLabel = activityTitle; +        this.activityIcon = activityIcon;          this.isActive = isActive;      } @@ -87,8 +82,9 @@ public class Task {      }      /** Notifies the callback listeners that this task has been loaded */ -    public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable icon, boolean reloadingTaskData) { -        this.icon = icon; +    public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable applicationIcon, +                                     boolean reloadingTaskData) { +        this.applicationIcon = applicationIcon;          this.thumbnail = thumbnail;          if (mCb != null) {              mCb.onTaskDataLoaded(reloadingTaskData); @@ -96,8 +92,8 @@ public class Task {      }      /** Notifies the callback listeners that this task has been unloaded */ -    public void notifyTaskDataUnloaded(Bitmap defaultThumbnail, Drawable defaultIcon) { -        icon = defaultIcon; +    public void notifyTaskDataUnloaded(Bitmap defaultThumbnail, Drawable defaultApplicationIcon) { +        applicationIcon = defaultApplicationIcon;          thumbnail = defaultThumbnail;          if (mCb != null) {              mCb.onTaskDataUnloaded(); @@ -106,14 +102,7 @@ public class Task {      @Override      public boolean equals(Object o) { -        // If we have multiple task entries for the same task, then we do the simple object -        // equality check -        if (Constants.Values.RecentsTaskLoader.TaskEntryMultiplier > 1) { -            return super.equals(o); -        } - -        // Otherwise, check that the id and intent match (the other fields can be asynchronously -        // loaded and is unsuitable to testing the identity of this Task) +        // Check that the id matches          Task t = (Task) o;          return key.equals(t.key);      } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index e89bde5927f4..cb5279490ff0 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -16,7 +16,6 @@  package com.android.systemui.recents.views; -import android.app.ActivityManager;  import android.app.ActivityOptions;  import android.content.ActivityNotFoundException;  import android.content.Context; @@ -30,6 +29,7 @@ import android.widget.FrameLayout;  import com.android.systemui.recents.Console;  import com.android.systemui.recents.Constants;  import com.android.systemui.recents.RecentsConfiguration; +import com.android.systemui.recents.RecentsTaskLoader;  import com.android.systemui.recents.model.SpaceNode;  import com.android.systemui.recents.model.Task;  import com.android.systemui.recents.model.TaskStack; @@ -246,14 +246,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV                  if (task.isActive) {                      // Bring an active task to the foreground -                    ActivityManager am = (ActivityManager) -                            stackView.getContext().getSystemService(Context.ACTIVITY_SERVICE); -                    if (opts != null) { -                        am.moveTaskToFront(task.key.id, ActivityManager.MOVE_TASK_WITH_HOME, -                                opts.toBundle()); -                    } else { -                        am.moveTaskToFront(task.key.id, ActivityManager.MOVE_TASK_WITH_HOME); -                    } +                    RecentsTaskLoader.getInstance().getSystemServicesProxy() +                            .moveTaskToFront(task.key.id, opts);                  } else {                      // Launch the activity with the desired animation                      Intent i = new Intent(task.key.baseIntent); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java index 235c6cc5fa3a..c9a6d67eb561 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java @@ -17,21 +17,12 @@  package com.android.systemui.recents.views;  import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Typeface;  import android.util.AttributeSet;  import android.view.View; -import android.view.animation.AccelerateDecelerateInterpolator;  import android.widget.FrameLayout;  import android.widget.ImageView;  import android.widget.TextView;  import com.android.systemui.R; -import com.android.systemui.recents.Constants; -import com.android.systemui.recents.RecentsConfiguration;  import com.android.systemui.recents.model.Task; @@ -39,6 +30,7 @@ import com.android.systemui.recents.model.Task;  class TaskBarView extends FrameLayout {      Task mTask; +    ImageView mApplicationIcon;      ImageView mActivityIcon;      TextView mActivityDescription; @@ -61,6 +53,7 @@ class TaskBarView extends FrameLayout {      @Override      protected void onFinishInflate() {          // Initialize the icon and description views +        mApplicationIcon = (ImageView) findViewById(R.id.application_icon);          mActivityIcon = (ImageView) findViewById(R.id.activity_icon);          mActivityDescription = (TextView) findViewById(R.id.activity_description);      } @@ -68,9 +61,13 @@ class TaskBarView extends FrameLayout {      /** Binds the bar view to the task */      void rebindToTask(Task t, boolean animate) {          mTask = t; -        if (t.icon != null) { -            mActivityIcon.setImageDrawable(t.icon); -            mActivityDescription.setText(t.title); +        if (t.applicationIcon != null) { +            mApplicationIcon.setImageDrawable(t.applicationIcon); +            mActivityDescription.setText(t.activityLabel); +            if (t.activityIcon != null) { +                mActivityIcon.setImageBitmap(t.activityIcon); +                mActivityIcon.setVisibility(View.VISIBLE); +            }              if (animate) {                  // XXX: Investigate how expensive it will be to create a second bitmap and crossfade              } @@ -80,7 +77,9 @@ class TaskBarView extends FrameLayout {      /** Unbinds the bar view from the task */      void unbindFromTask() {          mTask = null; -        mActivityIcon.setImageDrawable(null); +        mApplicationIcon.setImageDrawable(null); +        mActivityIcon.setImageBitmap(null); +        mActivityIcon.setVisibility(View.INVISIBLE);          mActivityDescription.setText("");      }  } 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 aeb571d6c56a..dfd608cb4342 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -22,7 +22,6 @@ import android.animation.AnimatorSet;  import android.animation.ObjectAnimator;  import android.animation.ValueAnimator;  import android.app.Activity; -import android.app.ActivityManager;  import android.content.Context;  import android.graphics.Canvas;  import android.graphics.Rect; @@ -40,6 +39,7 @@ import com.android.systemui.recents.Console;  import com.android.systemui.recents.Constants;  import com.android.systemui.recents.RecentsConfiguration;  import com.android.systemui.recents.RecentsTaskLoader; +import com.android.systemui.recents.SystemServicesProxy;  import com.android.systemui.recents.Utilities;  import com.android.systemui.recents.model.Task;  import com.android.systemui.recents.model.TaskStack; @@ -234,7 +234,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal                          // When we are picking up a new view from the view pool, prepare it for any                          // following animation by putting it in a reasonable place                          if (mStackViewsAnimationDuration > 0 && i != 0) { -                            int fromIndex = (transform.t < 0) ? (i - 1) : (i + 1); +                            int fromIndex = (transform.t < 0) ? (visibleRange[0] - 1) : +                                    (visibleRange[1] + 1);                              tv.updateViewPropertiesToTaskTransform(null,                                      getStackTransform(fromIndex, stackScroll), 0);                          } @@ -1268,12 +1269,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {          loader.deleteTaskData(task);          // Remove the task from activity manager -        final ActivityManager am = (ActivityManager) -                activity.getSystemService(Context.ACTIVITY_SERVICE); -        if (am != null) { -            am.removeTask(tv.getTask().key.id, -                    ActivityManager.REMOVE_TASK_KILL_PROCESS); -        } +        RecentsTaskLoader.getInstance().getSystemServicesProxy().removeTask(tv.getTask().key.id);          // If there are no remaining tasks, then either unfilter the current stack, or just close          // the activity if there are no filtered stacks 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 e04a1b26ef34..2c27d440f33c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -75,7 +75,7 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task.          // Bind the views          mThumbnailView = (TaskThumbnailView) findViewById(R.id.task_view_thumbnail);          mBarView = (TaskBarView) findViewById(R.id.task_view_bar); -        mBarView.mActivityIcon.setOnClickListener(this); +        mBarView.mApplicationIcon.setOnClickListener(this);          if (mTaskDataLoaded) {              onTaskDataLoaded(false);          } diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java index d584043eb7cb..c99f691dedf9 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java +++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java @@ -83,22 +83,7 @@ public class ToggleSlider extends RelativeLayout      }      public void onCheckedChanged(CompoundButton toggle, boolean checked) { -        Drawable thumb; -        Drawable slider; -        final Resources res = getContext().getResources(); -        if (checked) { -            thumb = res.getDrawable( -                    com.android.internal.R.drawable.scrubber_control_disabled_holo); -            slider = res.getDrawable( -                    R.drawable.status_bar_settings_slider_disabled); -        } else { -            thumb = res.getDrawable( -                    com.android.internal.R.drawable.scrubber_control_selector_holo); -            slider = res.getDrawable( -                    com.android.internal.R.drawable.scrubber_progress_horizontal_holo_dark); -        } -        mSlider.setThumb(thumb); -        mSlider.setProgressDrawable(slider); +        mSlider.setEnabled(checked);          if (mListener != null) {              mListener.onChanged(this, mTracking, checked, mSlider.getProgress()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index e5e287dce8a1..f34903696982 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -41,7 +41,6 @@ import android.os.Message;  import android.os.PowerManager;  import android.os.RemoteException;  import android.os.ServiceManager; -import android.os.SystemProperties;  import android.os.UserHandle;  import android.os.UserManager;  import android.provider.Settings; @@ -78,6 +77,7 @@ import com.android.systemui.RecentsComponent;  import com.android.systemui.SearchPanelView;  import com.android.systemui.SystemUI;  import com.android.systemui.statusbar.phone.KeyguardTouchDelegate; +import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;  import java.util.ArrayList;  import java.util.Locale; @@ -98,8 +98,6 @@ public abstract class BaseStatusBar extends SystemUI implements      protected static final int MSG_HIDE_HEADS_UP = 1027;      protected static final int MSG_ESCALATE_HEADS_UP = 1028; -    public static final boolean ENABLE_NOTIFICATION_STACK = SystemProperties -            .getBoolean("persist.notifications.use_stack", false);      protected static final boolean ENABLE_HEADS_UP = true;      // scores above this threshold should be displayed in heads up mode.      protected static final int INTERRUPTION_THRESHOLD = 10; @@ -120,7 +118,7 @@ public abstract class BaseStatusBar extends SystemUI implements      // all notifications      protected NotificationData mNotificationData = new NotificationData(); -    protected ViewGroup mPile; +    protected NotificationStackScrollLayout mStackScroller;      protected NotificationData.Entry mInterruptingNotificationEntry;      protected long mInterruptingNotificationTime; @@ -1033,7 +1031,7 @@ public abstract class BaseStatusBar extends SystemUI implements          }          // Construct the expanded view.          NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView); -        if (!inflateViews(entry, mPile)) { +        if (!inflateViews(entry, mStackScroller)) {              handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "                      + notification);              return null; 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 6be6d4d43a19..2d2f2f121e4e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -17,45 +17,51 @@  package com.android.systemui.statusbar.phone;  import android.content.Context; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.drawable.Drawable;  import android.util.AttributeSet; -import android.util.EventLog;  import android.view.MotionEvent;  import android.view.View;  import android.view.accessibility.AccessibilityEvent; -import com.android.systemui.EventLogTags;  import com.android.systemui.R;  import com.android.systemui.statusbar.GestureRecorder; +import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;  public class NotificationPanelView extends PanelView {      public static final boolean DEBUG_GESTURES = true; -    Drawable mHandleBar; -    int mHandleBarHeight; -    View mHandleView; -    int mFingers;      PhoneStatusBar mStatusBar; -    boolean mOkToFlip; +    private NotificationStackScrollLayout mNotificationStackScroller; +    private int[] mTempLocation = new int[2]; +    private int[] mTempChildLocation = new int[2]; +    private View mNotificationParent; +      public NotificationPanelView(Context context, AttributeSet attrs) {          super(context, attrs);      }      public void setStatusBar(PhoneStatusBar bar) { +        if (mStatusBar != null) { +            mStatusBar.setOnFlipRunnable(null); +        }          mStatusBar = bar; +        if (bar != null) { +            mStatusBar.setOnFlipRunnable(new Runnable() { +                @Override +                public void run() { +                    requestPanelHeightUpdate(); +                } +            }); +        }      }      @Override      protected void onFinishInflate() {          super.onFinishInflate(); -        Resources resources = getContext().getResources(); -        mHandleBar = resources.getDrawable(R.drawable.status_bar_close); -        mHandleBarHeight = resources.getDimensionPixelSize(R.dimen.close_handle_height); -        mHandleView = findViewById(R.id.handle); +        mNotificationStackScroller = (NotificationStackScrollLayout) +                findViewById(R.id.notification_stack_scroller); +        mNotificationParent = findViewById(R.id.notification_container_parent);      }      @Override @@ -80,61 +86,86 @@ public class NotificationPanelView extends PanelView {          return super.dispatchPopulateAccessibilityEvent(event);      } -    // We draw the handle ourselves so that it's always glued to the bottom of the window. +    /** +     * Gets the relative position of a view on the screen in regard to this view. +     * +     * @param requestedView the view we want to find the relative position for +     * @return +     */ +    private int getRelativeTop(View requestedView) { +        getLocationOnScreen(mTempLocation); +        requestedView.getLocationOnScreen(mTempChildLocation); +        return mTempChildLocation[1] - mTempLocation[1]; +    } +      @Override -    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { -        super.onLayout(changed, left, top, right, bottom); -        if (changed) { -            final int pl = getPaddingLeft(); -            final int pr = getPaddingRight(); -            mHandleBar.setBounds(pl, 0, getWidth() - pr, (int) mHandleBarHeight); -        } +    public boolean onTouchEvent(MotionEvent event) { +        // TODO: Handle doublefinger swipe to notifications again. Look at history for a reference +        // implementation. +        return super.onTouchEvent(event);      }      @Override -    public void draw(Canvas canvas) { -        super.draw(canvas); -        final int off = (int) (getHeight() - mHandleBarHeight - getPaddingBottom()); -        canvas.translate(0, off); -        mHandleBar.setState(mHandleView.getDrawableState()); -        mHandleBar.draw(canvas); -        canvas.translate(0, -off); +    protected boolean isScrolledToBottom() { +        if (!isInSettings()) { +            return mNotificationStackScroller.isScrolledToBottom(); +        } +        return super.isScrolledToBottom();      }      @Override -    public boolean onTouchEvent(MotionEvent event) { -        if (DEBUG_GESTURES) { -            if (event.getActionMasked() != MotionEvent.ACTION_MOVE) { -                EventLog.writeEvent(EventLogTags.SYSUI_NOTIFICATIONPANEL_TOUCH, -                       event.getActionMasked(), (int) event.getX(), (int) event.getY()); -            } +    protected int getMaxPanelHeight() { +        if (!isInSettings()) { +            int maxPanelHeight = super.getMaxPanelHeight(); +            int emptyBottomMargin = mNotificationStackScroller.getEmptyBottomMargin(); +            return maxPanelHeight - emptyBottomMargin;          } -        if (PhoneStatusBar.SETTINGS_DRAG_SHORTCUT && mStatusBar.mHasFlipSettings) { -            switch (event.getActionMasked()) { -                case MotionEvent.ACTION_DOWN: -                    mOkToFlip = getExpandedHeight() == 0; -                    break; -                case MotionEvent.ACTION_POINTER_DOWN: -                    if (mOkToFlip) { -                        float miny = event.getY(0); -                        float maxy = miny; -                        for (int i=1; i<event.getPointerCount(); i++) { -                            final float y = event.getY(i); -                            if (y < miny) miny = y; -                            if (y > maxy) maxy = y; -                        } -                        if (maxy - miny < mHandleBarHeight) { -                            if (getMeasuredHeight() < mHandleBarHeight) { -                                mStatusBar.switchToSettings(); -                            } else { -                                mStatusBar.flipToSettings(); -                            } -                            mOkToFlip = false; -                        } -                    } -                    break; -            } +        return super.getMaxPanelHeight(); +    } + +    private boolean isInSettings() { +        return mStatusBar != null && mStatusBar.isFlippedToSettings(); +    } + +    @Override +    protected void onHeightUpdated(float expandedHeight) { +        updateNotificationStackHeight(expandedHeight); +    } + +    /** +     * Update the height of the {@link #mNotificationStackScroller} to the new expanded height. +     * This is much more efficient than doing it over the layout pass. +     * +     * @param expandedHeight the new expanded height +     */ +    private void updateNotificationStackHeight(float expandedHeight) { +        float childOffset = getRelativeTop(mNotificationStackScroller) +                - mNotificationParent.getTranslationY(); +        int newStackHeight = (int) (expandedHeight - childOffset); +        int itemHeight = mNotificationStackScroller.getItemHeight(); +        int bottomStackPeekSize = mNotificationStackScroller.getBottomStackPeekSize(); +        int minStackHeight = itemHeight + bottomStackPeekSize; +        if (newStackHeight >= minStackHeight) { +            mNotificationParent.setTranslationY(0); +            mNotificationStackScroller.setCurrentStackHeight(newStackHeight); +        } else { + +            // We did not reach the position yet where we actually start growing, +            // so we translate the stack upwards. +            int translationY = (newStackHeight - minStackHeight); +            // A slight parallax effect is introduced in order for the stack to catch up with +            // the top card. +            float partiallyThere = (float) newStackHeight / minStackHeight; +            partiallyThere = Math.max(0, partiallyThere); +            translationY += (1 - partiallyThere) * bottomStackPeekSize; +            mNotificationParent.setTranslationY(translationY); +            mNotificationStackScroller.setCurrentStackHeight( +                    (int) (expandedHeight - (childOffset + translationY)));          } -        return mHandleView.dispatchTouchEvent(event); +    } + +    @Override +    protected int getDesiredMeasureHeight() { +        return mMaxPanelHeight;      }  } 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 4b2c3e15543c..3c8af3007b00 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -25,6 +25,7 @@ import android.util.AttributeSet;  import android.util.Log;  import android.view.MotionEvent;  import android.view.View; +import android.view.ViewConfiguration;  import android.widget.FrameLayout;  import com.android.systemui.R; @@ -69,7 +70,7 @@ public class PanelView extends FrameLayout {      private View mHandleView;      private float mPeekHeight; -    private float mTouchOffset; +    private float mInitialOffsetOnTouch;      private float mExpandedFraction = 0;      private float mExpandedHeight = 0;      private boolean mJustPeeked; @@ -77,6 +78,7 @@ public class PanelView extends FrameLayout {      private boolean mRubberbanding;      private boolean mTracking;      private int mTrackingPointer; +    private int mTouchSlop;      private TimeAnimator mTimeAnimator;      private ObjectAnimator mPeekAnimator; @@ -198,7 +200,6 @@ public class PanelView extends FrameLayout {          }      } -    private int[] mAbsPos = new int[2];      PanelBar mBar;      private final TimeListener mAnimationCallback = new TimeListener() { @@ -220,7 +221,7 @@ public class PanelView extends FrameLayout {      };      private float mVel, mAccel; -    private int mFullHeight = 0; +    protected int mMaxPanelHeight = 0;      private String mViewName;      protected float mInitialTouchY;      protected float mFinalTouchY; @@ -253,13 +254,13 @@ public class PanelView extends FrameLayout {              mTimeAnimator.start();              mRubberbanding = mRubberbandingEnabled // is it enabled at all? -                    && mExpandedHeight > getFullHeight() // are we past the end? +                    && mExpandedHeight > getMaxPanelHeight() // are we past the end?                      && mVel >= -mFlingGestureMinDistPx; // was this not possibly a "close" gesture?              if (mRubberbanding) {                  mClosing = true;              } else if (mVel == 0) {                  // if the panel is less than halfway open, close it -                mClosing = (mFinalTouchY / getFullHeight()) < 0.5f; +                mClosing = (mFinalTouchY / getMaxPanelHeight()) < 0.5f;              } else {                  mClosing = mExpandedHeight > 0 && mVel < 0;              } @@ -268,7 +269,7 @@ public class PanelView extends FrameLayout {              if (DEBUG) logf("tick: v=%.2fpx/s dt=%.4fs", mVel, dt);              if (DEBUG) logf("tick: before: h=%d", (int) mExpandedHeight); -            final float fh = getFullHeight(); +            final float fh = getMaxPanelHeight();              boolean braking = false;              if (BRAKES) {                  if (mClosing) { @@ -351,6 +352,9 @@ public class PanelView extends FrameLayout {          mPeekHeight = res.getDimension(R.dimen.peek_height)              + getPaddingBottom() // our window might have a dropshadow              - (mHandleView == null ? 0 : mHandleView.getPaddingTop()); // the handle might have a topshadow + +        final ViewConfiguration configuration = ViewConfiguration.get(getContext()); +        mTouchSlop = configuration.getScaledTouchSlop();      }      private void trackMovement(MotionEvent event) { @@ -363,10 +367,221 @@ public class PanelView extends FrameLayout {          event.offsetLocation(-deltaX, -deltaY);      } -    // Pass all touches along to the handle, allowing the user to drag the panel closed from its interior      @Override      public boolean onTouchEvent(MotionEvent event) { -        return mHandleView.dispatchTouchEvent(event); + +        /* +         * We capture touch events here and update the expand height here in case according to +         * the users fingers. This also handles multi-touch. +         * +         * If the user just clicks shortly, we give him a quick peek of the shade. +         * +         * Flinging is also enabled in order to open or close the shade. +         */ + +        int pointerIndex = event.findPointerIndex(mTrackingPointer); +        if (pointerIndex < 0) { +            pointerIndex = 0; +            mTrackingPointer = event.getPointerId(pointerIndex); +        } +        final float y = event.getY(pointerIndex); + +        switch (event.getActionMasked()) { +            case MotionEvent.ACTION_DOWN: +                mTracking = true; +                if (mHandleView != null) { +                    mHandleView.setPressed(true); +                    postInvalidate(); // catch the press state change +                } + +                mInitialTouchY = y; +                initVelocityTracker(); +                trackMovement(event); +                mTimeAnimator.cancel(); // end any outstanding animations +                mBar.onTrackingStarted(PanelView.this); +                mInitialOffsetOnTouch = mExpandedHeight; +                if (mExpandedHeight == 0) { +                    mJustPeeked = true; +                    runPeekAnimation(); +                } +                break; + +            case MotionEvent.ACTION_POINTER_UP: +                final int upPointer = event.getPointerId(event.getActionIndex()); +                if (mTrackingPointer == upPointer) { +                    // gesture is ongoing, find a new pointer to track +                    final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1; +                    final float newY = event.getY(newIndex); +                    mTrackingPointer = event.getPointerId(newIndex); +                    mInitialOffsetOnTouch = mExpandedHeight; +                    mInitialTouchY = newY; +                } +                break; + +            case MotionEvent.ACTION_MOVE: +                final float h = y - mInitialTouchY + mInitialOffsetOnTouch; +                if (h > mPeekHeight) { +                    if (mPeekAnimator != null && mPeekAnimator.isStarted()) { +                        mPeekAnimator.cancel(); +                    } +                    mJustPeeked = false; +                } +                if (!mJustPeeked) { +                    setExpandedHeightInternal(h); +                    mBar.panelExpansionChanged(PanelView.this, mExpandedFraction); +                } + +                trackMovement(event); +                break; + +            case MotionEvent.ACTION_UP: +            case MotionEvent.ACTION_CANCEL: +                mFinalTouchY = y; +                mTracking = false; +                mTrackingPointer = -1; +                if (mHandleView != null) { +                    mHandleView.setPressed(false); +                    postInvalidate(); // catch the press state change +                } +                mBar.onTrackingStopped(PanelView.this); +                trackMovement(event); + +                float vel = getCurrentVelocity(); +                fling(vel, true); + +                if (mVelocityTracker != null) { +                    mVelocityTracker.recycle(); +                    mVelocityTracker = null; +                } +                break; +        } +        return true; +    } + +    private float getCurrentVelocity() { +        float vel = 0; +        float yVel = 0, xVel = 0; +        boolean negative = false; + +        // the velocitytracker might be null if we got a bad input stream +        if (mVelocityTracker == null) { +            return 0; +        } + +        mVelocityTracker.computeCurrentVelocity(1000); + +        yVel = mVelocityTracker.getYVelocity(); +        negative = yVel < 0; + +        xVel = mVelocityTracker.getXVelocity(); +        if (xVel < 0) { +            xVel = -xVel; +        } +        if (xVel > mFlingGestureMaxXVelocityPx) { +            xVel = mFlingGestureMaxXVelocityPx; // limit how much we care about the x axis +        } + +        vel = (float) Math.hypot(yVel, xVel); +        if (vel > mFlingGestureMaxOutputVelocityPx) { +            vel = mFlingGestureMaxOutputVelocityPx; +        } + +        // if you've barely moved your finger, we treat the velocity as 0 +        // preventing spurious flings due to touch screen jitter +        final float deltaY = Math.abs(mFinalTouchY - mInitialTouchY); +        if (deltaY < mFlingGestureMinDistPx +                || vel < mFlingExpandMinVelocityPx +                ) { +            vel = 0; +        } + +        if (negative) { +            vel = -vel; +        } + +        if (DEBUG) { +            logf("gesture: dy=%f vel=(%f,%f) vlinear=%f", +                    deltaY, +                    xVel, yVel, +                    vel); +        } +        return vel; +    } + +    @Override +    public boolean onInterceptTouchEvent(MotionEvent event) { + +        /* +         * If the user drags anywhere inside the panel we intercept it if he moves his finger +         * upwards. This allows closing the shade from anywhere inside the panel. +         * +         * We only do this if the current content is scrolled to the bottom, +         * i.e isScrolledToBottom() is true and therefore there is no conflicting scrolling gesture +         * possible. +         */ +        int pointerIndex = event.findPointerIndex(mTrackingPointer); +        if (pointerIndex < 0) { +            pointerIndex = 0; +            mTrackingPointer = event.getPointerId(pointerIndex); +        } +        final float y = event.getY(pointerIndex); +        boolean scrolledToBottom = isScrolledToBottom(); + +        switch (event.getActionMasked()) { +            case MotionEvent.ACTION_DOWN: +                mTracking = true; +                if (mHandleView != null) { +                    mHandleView.setPressed(true); +                    // catch the press state change +                    postInvalidate(); +                } +                mInitialTouchY = y; +                initVelocityTracker(); +                trackMovement(event); +                mTimeAnimator.cancel(); // end any outstanding animations +                if (mExpandedHeight == 0 || y > getContentHeight()) { +                    return true; +                } +                break; +            case MotionEvent.ACTION_POINTER_UP: +                final int upPointer = event.getPointerId(event.getActionIndex()); +                if (mTrackingPointer == upPointer) { +                    // gesture is ongoing, find a new pointer to track +                    final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1; +                    mTrackingPointer = event.getPointerId(newIndex); +                    final float newY = event.getY(newIndex); +                    mInitialTouchY = newY; +                } +                break; + +            case MotionEvent.ACTION_MOVE: +                final float h = y - mInitialTouchY; +                trackMovement(event); +                if (scrolledToBottom) { +                    if (h < -mTouchSlop) { +                        mInitialOffsetOnTouch = mExpandedHeight; +                        mInitialTouchY = y; +                        return true; +                    } +                } +                break; +        } +        return false; +    } + +    private void initVelocityTracker() { +        if (mVelocityTracker != null) { +            mVelocityTracker.recycle(); +        } +        mVelocityTracker = FlingTracker.obtain(); +    } + +    protected boolean isScrolledToBottom() { +        return false; +    } + +    protected float getContentHeight() { +        return mExpandedHeight;      }      @Override @@ -375,134 +590,6 @@ public class PanelView extends FrameLayout {          mHandleView = findViewById(R.id.handle);          loadDimens(); - -        if (DEBUG) logf("handle view: " + mHandleView); -        if (mHandleView != null) { -            mHandleView.setOnTouchListener(new View.OnTouchListener() { -                @Override -                public boolean onTouch(View v, MotionEvent event) { -                    int pointerIndex = event.findPointerIndex(mTrackingPointer); -                    if (pointerIndex < 0) { -                        pointerIndex = 0; -                        mTrackingPointer = event.getPointerId(pointerIndex); -                    } -                    final float y = event.getY(pointerIndex); -                    final float rawDelta = event.getRawY() - event.getY(); -                    final float rawY = y + rawDelta; -                    if (DEBUG) logf("handle.onTouch: a=%s p=[%d,%d] y=%.1f rawY=%.1f off=%.1f", -                            MotionEvent.actionToString(event.getAction()), -                            mTrackingPointer, pointerIndex, -                            y, rawY, mTouchOffset); -                    PanelView.this.getLocationOnScreen(mAbsPos); - -                    switch (event.getActionMasked()) { -                        case MotionEvent.ACTION_DOWN: -                            mTracking = true; -                            mHandleView.setPressed(true); -                            postInvalidate(); // catch the press state change -                            mInitialTouchY = y; -                            mVelocityTracker = FlingTracker.obtain(); -                            trackMovement(event); -                            mTimeAnimator.cancel(); // end any outstanding animations -                            mBar.onTrackingStarted(PanelView.this); -                            mTouchOffset = (rawY - mAbsPos[1]) - mExpandedHeight; -                            if (mExpandedHeight == 0) { -                                mJustPeeked = true; -                                runPeekAnimation(); -                            } -                            break; - -                        case MotionEvent.ACTION_POINTER_UP: -                            final int upPointer = event.getPointerId(event.getActionIndex()); -                            if (mTrackingPointer == upPointer) { -                                // gesture is ongoing, find a new pointer to track -                                final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1; -                                final float newY = event.getY(newIndex); -                                final float newRawY = newY + rawDelta; -                                mTrackingPointer = event.getPointerId(newIndex); -                                mTouchOffset = (newRawY - mAbsPos[1]) - mExpandedHeight; -                                mInitialTouchY = newY; -                            } -                            break; - -                        case MotionEvent.ACTION_MOVE: -                            final float h = rawY - mAbsPos[1] - mTouchOffset; -                            if (h > mPeekHeight) { -                                if (mPeekAnimator != null && mPeekAnimator.isStarted()) { -                                    mPeekAnimator.cancel(); -                                } -                                mJustPeeked = false; -                            } -                            if (!mJustPeeked) { -                                PanelView.this.setExpandedHeightInternal(h); -                                mBar.panelExpansionChanged(PanelView.this, mExpandedFraction); -                            } - -                            trackMovement(event); -                            break; - -                        case MotionEvent.ACTION_UP: -                        case MotionEvent.ACTION_CANCEL: -                            mFinalTouchY = y; -                            mTracking = false; -                            mTrackingPointer = -1; -                            mHandleView.setPressed(false); -                            postInvalidate(); // catch the press state change -                            mBar.onTrackingStopped(PanelView.this); -                            trackMovement(event); - -                            float vel = 0, yVel = 0, xVel = 0; -                            boolean negative = false; - -                            if (mVelocityTracker != null) { -                                // the velocitytracker might be null if we got a bad input stream -                                mVelocityTracker.computeCurrentVelocity(1000); - -                                yVel = mVelocityTracker.getYVelocity(); -                                negative = yVel < 0; - -                                xVel = mVelocityTracker.getXVelocity(); -                                if (xVel < 0) { -                                    xVel = -xVel; -                                } -                                if (xVel > mFlingGestureMaxXVelocityPx) { -                                    xVel = mFlingGestureMaxXVelocityPx; // limit how much we care about the x axis -                                } - -                                vel = (float)Math.hypot(yVel, xVel); -                                if (vel > mFlingGestureMaxOutputVelocityPx) { -                                    vel = mFlingGestureMaxOutputVelocityPx; -                                } - -                                mVelocityTracker.recycle(); -                                mVelocityTracker = null; -                            } - -                            // if you've barely moved your finger, we treat the velocity as 0 -                            // preventing spurious flings due to touch screen jitter -                            final float deltaY = Math.abs(mFinalTouchY - mInitialTouchY); -                            if (deltaY < mFlingGestureMinDistPx -                                    || vel < mFlingExpandMinVelocityPx -                                    ) { -                                vel = 0; -                            } - -                            if (negative) { -                                vel = -vel; -                            } - -                            if (DEBUG) logf("gesture: dy=%f vel=(%f,%f) vlinear=%f", -                                    deltaY, -                                    xVel, yVel, -                                    vel); - -                            fling(vel, true); - -                            break; -                    } -                    return true; -                }}); -        }      }      public void fling(float vel, boolean always) { @@ -543,19 +630,18 @@ public class PanelView extends FrameLayout {          // Did one of our children change size?          int newHeight = getMeasuredHeight(); -        if (newHeight != mFullHeight) { -            mFullHeight = newHeight; -            // If the user isn't actively poking us, let's rubberband to the content -            if (!mTracking && !mRubberbanding && !mTimeAnimator.isStarted() -                    && mExpandedHeight > 0 && mExpandedHeight != mFullHeight) { -                mExpandedHeight = mFullHeight; -            } +        if (newHeight != mMaxPanelHeight) { +            mMaxPanelHeight = newHeight;          }          heightMeasureSpec = MeasureSpec.makeMeasureSpec( -                    (int) mExpandedHeight, MeasureSpec.AT_MOST); // MeasureSpec.getMode(heightMeasureSpec)); +                    getDesiredMeasureHeight(), MeasureSpec.AT_MOST);          setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);      } +    protected int getDesiredMeasureHeight() { +        return (int) mExpandedHeight; +    } +      public void setExpandedHeight(float height) {          if (DEBUG) logf("setExpandedHeight(%.1f)", height); @@ -569,8 +655,20 @@ public class PanelView extends FrameLayout {      @Override      protected void onLayout (boolean changed, int left, int top, int right, int bottom) { -        if (DEBUG) logf("onLayout: changed=%s, bottom=%d eh=%d fh=%d", changed?"T":"f", bottom, (int)mExpandedHeight, mFullHeight); +        if (DEBUG) logf("onLayout: changed=%s, bottom=%d eh=%d fh=%d", changed?"T":"f", bottom, +                (int)mExpandedHeight, mMaxPanelHeight);          super.onLayout(changed, left, top, right, bottom); +        requestPanelHeightUpdate(); +    } + +    protected void requestPanelHeightUpdate() { +        float currentMaxPanelHeight = getMaxPanelHeight(); + +        // If the user isn't actively poking us, let's update the height +        if (!mTracking && !mRubberbanding && !mTimeAnimator.isStarted() +                && mExpandedHeight > 0 && currentMaxPanelHeight != mExpandedHeight) { +            setExpandedHeightInternal(currentMaxPanelHeight); +        }      }      public void setExpandedHeightInternal(float h) { @@ -583,7 +681,7 @@ public class PanelView extends FrameLayout {              h = 0;          } -        float fh = getFullHeight(); +        float fh = getMaxPanelHeight();          if (fh == 0) {              // Hmm, full height hasn't been computed yet          } @@ -593,9 +691,13 @@ public class PanelView extends FrameLayout {          mExpandedHeight = h; -        if (DEBUG) logf("setExpansion: height=%.1f fh=%.1f tracking=%s rubber=%s", h, fh, mTracking?"T":"f", mRubberbanding?"T":"f"); +        if (DEBUG) { +            logf("setExpansion: height=%.1f fh=%.1f tracking=%s rubber=%s", h, fh, +                    mTracking ? "T" : "f", mRubberbanding ? "T" : "f"); +        } + +        onHeightUpdated(mExpandedHeight); -        requestLayout();  //        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();  //        lp.height = (int) mExpandedHeight;  //        setLayoutParams(lp); @@ -603,13 +705,23 @@ public class PanelView extends FrameLayout {          mExpandedFraction = Math.min(1f, (fh == 0) ? 0 : h / fh);      } -    private float getFullHeight() { -        if (mFullHeight <= 0) { -            if (DEBUG) logf("Forcing measure() since fullHeight=" + mFullHeight); +    protected void onHeightUpdated(float expandedHeight) { +        requestLayout(); +    } + +    /** +     * This returns the maximum height of the panel. Children should override this if their +     * desired height is not the full height. +     * +     * @return the default implementation simply returns the maximum height. +     */ +    protected int getMaxPanelHeight() { +        if (mMaxPanelHeight <= 0) { +            if (DEBUG) logf("Forcing measure() since mMaxPanelHeight=" + mMaxPanelHeight);              measure(MeasureSpec.makeMeasureSpec(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.EXACTLY),                      MeasureSpec.makeMeasureSpec(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.EXACTLY));          } -        return mFullHeight; +        return mMaxPanelHeight;      }      public void setExpandedFraction(float frac) { @@ -621,7 +733,7 @@ public class PanelView extends FrameLayout {              }              frac = 0;          } -        setExpandedHeight(getFullHeight() * frac); +        setExpandedHeight(getMaxPanelHeight() * frac);      }      public float getExpandedHeight() { @@ -633,7 +745,7 @@ public class PanelView extends FrameLayout {      }      public boolean isFullyExpanded() { -        return mExpandedHeight >= getFullHeight(); +        return mExpandedHeight >= getMaxPanelHeight();      }      public boolean isFullyCollapsed() { @@ -681,12 +793,12 @@ public class PanelView extends FrameLayout {      }      public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { -        pw.println(String.format("[PanelView(%s): expandedHeight=%f fullHeight=%f closing=%s" +        pw.println(String.format("[PanelView(%s): expandedHeight=%f maxPanelHeight=%f closing=%s"                  + " tracking=%s rubberbanding=%s justPeeked=%s peekAnim=%s%s timeAnim=%s%s"                  + "]",                  this.getClass().getSimpleName(),                  getExpandedHeight(), -                getFullHeight(), +                getMaxPanelHeight(),                  mClosing?"T":"f",                  mTracking?"T":"f",                  mRubberbanding?"T":"f", 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 2257aaae4ece..4730f2fd0613 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -86,7 +86,6 @@ import com.android.internal.statusbar.StatusBarIcon;  import com.android.systemui.DemoMode;  import com.android.systemui.EventLogTags;  import com.android.systemui.R; -import com.android.systemui.SwipeHelper;  import com.android.systemui.statusbar.BaseStatusBar;  import com.android.systemui.statusbar.CommandQueue;  import com.android.systemui.statusbar.GestureRecorder; @@ -101,8 +100,6 @@ import com.android.systemui.statusbar.policy.DateView;  import com.android.systemui.statusbar.policy.HeadsUpNotificationView;  import com.android.systemui.statusbar.policy.LocationController;  import com.android.systemui.statusbar.policy.NetworkController; -import com.android.systemui.statusbar.policy.NotificationRowLayout; -import com.android.systemui.statusbar.policy.OnSizeChangedListener;  import com.android.systemui.statusbar.policy.RotationLockController;  import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; @@ -172,7 +169,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {      Display mDisplay;      Point mCurrentDisplaySize = new Point();      private float mHeadsUpVerticalOffset; -    private int[] mPilePosition = new int[2]; +    private int[] mStackScrollerPosition = new int[2];      StatusBarWindowView mStatusBarWindow;      PhoneStatusBarView mStatusBarView; @@ -198,7 +195,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {      // expanded notifications      NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window -    View mNotificationScroller;      View mExpandedContents;      int mNotificationPanelGravity;      int mNotificationPanelMarginBottomPx, mNotificationPanelMarginPx; @@ -350,6 +346,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {              }          }}; +    private Runnable mOnFlipRunnable; + +    public void setOnFlipRunnable(Runnable onFlipRunnable) { +        mOnFlipRunnable = onFlipRunnable; +    } +      @Override      public void setZenMode(int mode) {          super.setZenMode(mode); @@ -417,7 +419,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);          mStatusBarView.setPanelHolder(holder); -        mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(R.id.notification_panel); +        mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById( +                R.id.notification_panel);          mNotificationPanel.setStatusBar(this);          mNotificationPanelIsFullScreenWidth =              (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT); @@ -443,7 +446,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {              mHeadsUpNotificationView.setBar(this);          }          if (MULTIUSER_DEBUG) { -            mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(R.id.header_debug_info); +            mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById( +                    R.id.header_debug_info);              mNotificationPanelDebugText.setVisibility(View.VISIBLE);          } @@ -482,33 +486,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);          mTickerView = mStatusBarView.findViewById(R.id.ticker); -        View legacyScrollView = mStatusBarWindow.findViewById(R.id.scroll); -        NotificationStackScrollLayout notificationStack -                = (NotificationStackScrollLayout) mStatusBarWindow -                .findViewById(R.id.notification_stack_scroller); -        if (ENABLE_NOTIFICATION_STACK) { -            notificationStack.setLongPressListener(getNotificationLongClicker()); -            mPile = notificationStack; -            legacyScrollView.setVisibility(View.GONE); - -            // The scrollview and the notification container are unified now! -            // TODO: remove mNotificationScroller entirely once we fully switch to the new Layout -            mNotificationScroller = notificationStack; -        } else { -            mNotificationScroller = legacyScrollView; -            // less drawing during pulldowns -            mNotificationScroller.setVerticalScrollBarEnabled(false); -            NotificationRowLayout rowLayout -                    = (NotificationRowLayout) mStatusBarWindow.findViewById(R.id.latestItems); -            rowLayout.setLayoutTransitionsEnabled(false); -            rowLayout.setLongPressListener(getNotificationLongClicker()); -            mPile = rowLayout; -            notificationStack.setVisibility(View.GONE); -        } - -        mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout); - +        mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById( +                R.id.notification_stack_scroller); +        mStackScroller.setLongPressListener(getNotificationLongClicker()); +        mExpandedContents = mStackScroller;          mNotificationPanelHeader = mStatusBarWindow.findViewById(R.id.header); @@ -551,7 +533,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {              }          }          if (mHasFlipSettings) { -            mNotificationButton = (ImageView) mStatusBarWindow.findViewById(R.id.notification_button); +            mNotificationButton = (ImageView) mStatusBarWindow.findViewById( +                    R.id.notification_button);              if (mNotificationButton != null) {                  mNotificationButton.setOnClickListener(mNotificationButtonListener);              } @@ -593,17 +576,18 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          if (isAPhone) {              mEmergencyCallLabel =                      (TextView) mStatusBarWindow.findViewById(R.id.emergency_calls_only); -            if (mEmergencyCallLabel != null) { -                mNetworkController.addEmergencyLabelView(mEmergencyCallLabel); -                mEmergencyCallLabel.setOnClickListener(new View.OnClickListener() { -                    public void onClick(View v) { }}); -                mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { -                    @Override -                    public void onLayoutChange(View v, int left, int top, int right, int bottom, -                            int oldLeft, int oldTop, int oldRight, int oldBottom) { -                        updateCarrierLabelVisibility(false); -                    }}); -            } +            // TODO: Uncomment when correctly positioned +//            if (mEmergencyCallLabel != null) { +//                mNetworkController.addEmergencyLabelView(mEmergencyCallLabel); +//                mEmergencyCallLabel.setOnClickListener(new View.OnClickListener() { +//                    public void onClick(View v) { }}); +//                mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { +//                    @Override +//                    public void onLayoutChange(View v, int left, int top, int right, int bottom, +//                            int oldLeft, int oldTop, int oldRight, int oldBottom) { +//                        updateCarrierLabelVisibility(false); +//                    }}); +//            }          }          mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label); @@ -621,13 +605,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {              }              // set up the dynamic hide/show of the label -            if (!ENABLE_NOTIFICATION_STACK) -                ((NotificationRowLayout) mPile).setOnSizeChangedListener(new OnSizeChangedListener() { -                @Override -                public void onSizeChanged(View view, int w, int h, int oldw, int oldh) { -                    updateCarrierLabelVisibility(false); -                } -            }); +            // TODO: uncomment, handle this for the Stack scroller aswell +//                ((NotificationRowLayout) mStackScroller) +// .setOnSizeChangedListener(new OnSizeChangedListener() { +//                @Override +//                public void onSizeChanged(View view, int w, int h, int oldw, int oldh) { +//                    updateCarrierLabelVisibility(false);          }          // Quick Settings (where available, some restrictions apply) @@ -1066,7 +1049,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {      }      private void loadNotificationShade() { -        if (mPile == null) return; +        if (mStackScroller == null) return;          int N = mNotificationData.size(); @@ -1092,21 +1075,21 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          }          ArrayList<View> toRemove = new ArrayList<View>(); -        for (int i=0; i<mPile.getChildCount(); i++) { -            View child = mPile.getChildAt(i); +        for (int i=0; i< mStackScroller.getChildCount(); i++) { +            View child = mStackScroller.getChildAt(i);              if (!toShow.contains(child)) {                  toRemove.add(child);              }          }          for (View remove : toRemove) { -            mPile.removeView(remove); +            mStackScroller.removeView(remove);          }          for (int i=0; i<toShow.size(); i++) {              View v = toShow.get(i);              if (v.getParent() == null) { -                mPile.addView(v, i); +                mStackScroller.addView(v, i);              }          } @@ -1178,15 +1161,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          // The idea here is to only show the carrier label when there is enough room to see it,          // i.e. when there aren't enough notifications to fill the panel.          if (SPEW) { -            Log.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d", -                    mPile.getHeight(), mNotificationScroller.getHeight(), mCarrierLabelHeight)); +            Log.d(TAG, String.format("stackScrollerh=%d scrollh=%d carrierh=%d", +                    mStackScroller.getHeight(), mStackScroller.getHeight(), +                    mCarrierLabelHeight));          }          final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null;          final boolean makeVisible =              !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly()) -            && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight) -            && mNotificationScroller.getVisibility() == View.VISIBLE; +            && mStackScroller.getHeight() < (mNotificationPanel.getHeight() +                    - mCarrierLabelHeight - mNotificationHeaderHeight) +            && mStackScroller.getVisibility() == View.VISIBLE;          if (force || mCarrierLabelVisible != makeVisible) {              mCarrierLabelVisible = makeVisible; @@ -1229,7 +1214,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          if (mHasFlipSettings                  && mFlipSettingsView != null                  && mFlipSettingsView.getVisibility() == View.VISIBLE -                && mNotificationScroller.getVisibility() != View.VISIBLE) { +                && mStackScroller.getVisibility() != View.VISIBLE) {              // the flip settings panel is unequivocally showing; we should not be shown              mClearButton.setVisibility(View.INVISIBLE);          } else if (mClearButton.isShown()) { @@ -1483,9 +1468,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          }          mExpandedVisible = true; -        if (!ENABLE_NOTIFICATION_STACK) { -            ((NotificationRowLayout) mPile).setLayoutTransitionsEnabled(true); -        }          if (mNavigationBarView != null)              mNavigationBarView.setSlippery(true); @@ -1600,7 +1582,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          }          mNotificationPanel.expand(); -        if (mHasFlipSettings && mNotificationScroller.getVisibility() != View.VISIBLE) { +        if (mHasFlipSettings && mStackScroller.getVisibility() != View.VISIBLE) {              flipToNotifications();          } @@ -1614,11 +1596,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();          if (mClearButtonAnim != null) mClearButtonAnim.cancel(); -        mNotificationScroller.setVisibility(View.VISIBLE); +        mStackScroller.setVisibility(View.VISIBLE);          mScrollViewAnim = start(              startDelay(FLIP_DURATION_OUT,                  interpolator(mDecelerateInterpolator, -                    ObjectAnimator.ofFloat(mNotificationScroller, View.SCALE_X, 0f, 1f) +                    ObjectAnimator.ofFloat(mStackScroller, View.SCALE_X, 0f, 1f)                          .setDuration(FLIP_DURATION_IN)                      )));          mFlipSettingsViewAnim = start( @@ -1645,6 +1627,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {                  updateCarrierLabelVisibility(false);              }          }, FLIP_DURATION - 150); +        if (mOnFlipRunnable != null) { +            mOnFlipRunnable.run(); +        }      }      @Override @@ -1676,11 +1661,21 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          mFlipSettingsView.setScaleX(1f);          mFlipSettingsView.setVisibility(View.VISIBLE);          mSettingsButton.setVisibility(View.GONE); -        mNotificationScroller.setVisibility(View.GONE); -        mNotificationScroller.setScaleX(0f); +        mStackScroller.setVisibility(View.GONE); +        mStackScroller.setScaleX(0f);          mNotificationButton.setVisibility(View.VISIBLE);          mNotificationButton.setAlpha(1f);          mClearButton.setVisibility(View.GONE); +        if (mOnFlipRunnable != null) { +            mOnFlipRunnable.run(); +        } +    } + +    public boolean isFlippedToSettings() { +        if (mFlipSettingsView != null) { +            return mFlipSettingsView.getVisibility() == View.VISIBLE; +        } +        return false;      }      public void flipToSettings() { @@ -1704,15 +1699,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          mScrollViewAnim = start(              setVisibilityWhenDone(                  interpolator(mAccelerateInterpolator, -                        ObjectAnimator.ofFloat(mNotificationScroller, View.SCALE_X, 1f, 0f) +                        ObjectAnimator.ofFloat(mStackScroller, View.SCALE_X, 1f, 0f)                          )                      .setDuration(FLIP_DURATION_OUT), -                    mNotificationScroller, View.INVISIBLE)); +                    mStackScroller, View.INVISIBLE));          mSettingsButtonAnim = start(              setVisibilityWhenDone(                  ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)                      .setDuration(FLIP_DURATION), -                    mNotificationScroller, View.INVISIBLE)); +                    mStackScroller, View.INVISIBLE));          mNotificationButton.setVisibility(View.VISIBLE);          mNotificationButtonAnim = start(              ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f) @@ -1727,6 +1722,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {                  updateCarrierLabelVisibility(false);              }          }, FLIP_DURATION - 150); +        if (mOnFlipRunnable != null) { +            mOnFlipRunnable.run(); +        }      }      public void flipPanels() { @@ -1766,8 +1764,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {              if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();              if (mClearButtonAnim != null) mClearButtonAnim.cancel(); -            mNotificationScroller.setScaleX(1f); -            mNotificationScroller.setVisibility(View.VISIBLE); +            mStackScroller.setScaleX(1f); +            mStackScroller.setVisibility(View.VISIBLE);              mSettingsButton.setAlpha(1f);              mSettingsButton.setVisibility(View.VISIBLE);              mNotificationPanel.setVisibility(View.GONE); @@ -1777,9 +1775,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          }          mExpandedVisible = false; -        if (!ENABLE_NOTIFICATION_STACK) { -            ((NotificationRowLayout) mPile).setLayoutTransitionsEnabled(false); -        }          if (mNavigationBarView != null)              mNavigationBarView.setSlippery(false);          visibilityChanged(false); @@ -1806,53 +1801,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);      } -    /** -     * Enables or disables layers on the children of the notifications pile. -     * -     * When layers are enabled, this method attempts to enable layers for the minimal -     * number of children. Only children visible when the notification area is fully -     * expanded will receive a layer. The technique used in this method might cause -     * more children than necessary to get a layer (at most one extra child with the -     * current UI.) -     * -     * @param layerType {@link View#LAYER_TYPE_NONE} or {@link View#LAYER_TYPE_HARDWARE} -     */ -    private void setPileLayers(int layerType) { -        final int count = mPile.getChildCount(); - -        switch (layerType) { -            case View.LAYER_TYPE_NONE: -                for (int i = 0; i < count; i++) { -                    mPile.getChildAt(i).setLayerType(layerType, null); -                } -                break; -            case View.LAYER_TYPE_HARDWARE: -                final int[] location = new int[2]; -                mNotificationPanel.getLocationInWindow(location); - -                final int left = location[0]; -                final int top = location[1]; -                final int right = left + mNotificationPanel.getWidth(); -                final int bottom = top + getExpandedViewMaxHeight(); - -                final Rect childBounds = new Rect(); - -                for (int i = 0; i < count; i++) { -                    final View view = mPile.getChildAt(i); -                    view.getLocationInWindow(location); - -                    childBounds.set(location[0], location[1], -                            location[0] + view.getWidth(), location[1] + view.getHeight()); - -                    if (childBounds.intersects(left, top, right, bottom)) { -                        view.setLayerType(layerType, null); -                    } -                } - -                break; -        } -    } -      public boolean interceptTouchEvent(MotionEvent event) {          if (DEBUG_GESTURES) {              if (event.getActionMasked() != MotionEvent.ACTION_MOVE) { @@ -2230,11 +2178,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {              pw.println("  mTicking=" + mTicking);              pw.println("  mTracking=" + mTracking);              pw.println("  mDisplayMetrics=" + mDisplayMetrics); -            pw.println("  mPile: " + viewInfo(mPile)); +            pw.println("  mStackScroller: " + viewInfo(mStackScroller));              pw.println("  mTickerView: " + viewInfo(mTickerView)); -            pw.println("  mNotificationScroller: " + viewInfo(mNotificationScroller) -                    + " scroll " + mNotificationScroller.getScrollX() -                    + "," + mNotificationScroller.getScrollY()); +            pw.println("  mStackScroller: " + viewInfo(mStackScroller) +                    + " scroll " + mStackScroller.getScrollX() +                    + "," + mStackScroller.getScrollY());          }          pw.print("  mInteractingWindows="); pw.println(mInteractingWindows); @@ -2409,8 +2357,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {          if (ENABLE_HEADS_UP && mHeadsUpNotificationView != null) {              mHeadsUpNotificationView.setMargin(mNotificationPanelMarginPx); -            mPile.getLocationOnScreen(mPilePosition); -            mHeadsUpVerticalOffset = mPilePosition[1] - mNaturalBarHeight; +            mStackScroller.getLocationOnScreen(mStackScrollerPosition); +            mHeadsUpVerticalOffset = mStackScrollerPosition[1] - mNaturalBarHeight;          }          updateCarrierLabelVisibility(false); @@ -2428,7 +2376,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {      private View.OnClickListener mClearButtonListener = new View.OnClickListener() {          public void onClick(View v) { -            // TODO: Handle this better with notification stack scroller              synchronized (mNotificationData) {                  mPostCollapseCleanup = new Runnable() {                      @Override @@ -2437,86 +2384,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {                              Log.v(TAG, "running post-collapse cleanup");                          }                          try { -                            if (!ENABLE_NOTIFICATION_STACK) { -                                ((NotificationRowLayout) mPile).setViewRemoval(true); -                            }                              mBarService.onClearAllNotifications(mCurrentUserId);                          } catch (Exception ex) { }                      }                  }; -                if(ENABLE_NOTIFICATION_STACK) { -                    animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); -                    return; -                } - -                // animate-swipe all dismissable notifications, then animate the shade closed -                int numChildren = mPile.getChildCount(); - -                int scrollTop = mNotificationScroller.getScrollY(); -                int scrollBottom = scrollTop + mNotificationScroller.getHeight(); -                final ArrayList<View> snapshot = new ArrayList<View>(numChildren); -                for (int i=0; i<numChildren; i++) { -                    final View child = mPile.getChildAt(i); -                    if (((SwipeHelper.Callback) mPile).canChildBeDismissed(child) -                            && child.getBottom() > scrollTop && child.getTop() < scrollBottom) { -                        snapshot.add(child); -                    } -                } -                if (snapshot.isEmpty()) { -                    animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); -                    return; -                } -                new Thread(new Runnable() { -                    @Override -                    public void run() { -                        // Decrease the delay for every row we animate to give the sense of -                        // accelerating the swipes -                        final int ROW_DELAY_DECREMENT = 10; -                        int currentDelay = 140; -                        int totalDelay = 0; - - -                        if (!ENABLE_NOTIFICATION_STACK) { -                            // Set the shade-animating state to avoid doing other work during -                            // all of these animations. In particular, avoid layout and -                            // redrawing when collapsing the shade. -                            ((NotificationRowLayout) mPile).setViewRemoval(false); -                        } - -                        View sampleView = snapshot.get(0); -                        int width = sampleView.getWidth(); -                        final int dir = sampleView.isLayoutRtl() ? -1 : +1; -                        final int velocity = dir * width * 8; // 1000/8 = 125 ms duration -                        for (final View _v : snapshot) { -                            mHandler.postDelayed(new Runnable() { -                                @Override -                                public void run() { -                                    if (!ENABLE_NOTIFICATION_STACK) { -                                        ((NotificationRowLayout) mPile).dismissRowAnimated( -                                                _v, velocity); -                                    } else { -                                        ((NotificationStackScrollLayout) mPile).dismissRowAnimated( -                                                _v, velocity); -                                    } -                                } -                            }, totalDelay); -                            currentDelay = Math.max(50, currentDelay - ROW_DELAY_DECREMENT); -                            totalDelay += currentDelay; -                        } -                        // Delay the collapse animation until after all swipe animations have -                        // finished. Provide some buffer because there may be some extra delay -                        // before actually starting each swipe animation. Ideally, we'd -                        // synchronize the end of those animations with the start of the collaps -                        // exactly. -                        mHandler.postDelayed(new Runnable() { -                            @Override -                            public void run() { -                                animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); -                            } -                        }, totalDelay + 225); -                    } -                }).start(); +                animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE); +                return; +                // TODO: Handle this better with notification stack scroller              }          }      }; 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 eeae0815ad3e..a7121c4e7d59 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -24,13 +24,13 @@ import android.util.AttributeSet;  import android.view.KeyEvent;  import android.view.MotionEvent;  import android.view.View; -import android.view.ViewGroup;  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.policy.ScrollAdapter;  import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; @@ -40,9 +40,8 @@ public class StatusBarWindowView extends FrameLayout      public static final boolean DEBUG = BaseStatusBar.DEBUG;      private ExpandHelper mExpandHelper; -    private ViewGroup latestItems; +    private NotificationStackScrollLayout mStackScrollLayout;      private NotificationPanelView mNotificationPanel; -    private View mNotificationScroller;      PhoneStatusBar mService; @@ -56,37 +55,15 @@ public class StatusBarWindowView extends FrameLayout      protected void onAttachedToWindow () {          super.onAttachedToWindow(); -        ExpandHelper.ScrollAdapter scrollAdapter; -        if (BaseStatusBar.ENABLE_NOTIFICATION_STACK) { -            NotificationStackScrollLayout stackScrollLayout = -                    (NotificationStackScrollLayout) findViewById(R.id.notification_stack_scroller); - -            // ScrollView and notification container are unified in a single view now. -            latestItems = stackScrollLayout; -            scrollAdapter = stackScrollLayout; -            mNotificationScroller = stackScrollLayout; -        } else { -            latestItems = (ViewGroup) findViewById(R.id.latestItems); -            mNotificationScroller = findViewById(R.id.scroll); -            scrollAdapter = new ExpandHelper.ScrollAdapter() { -                @Override -                public boolean isScrolledToTop() { -                    return mNotificationScroller.getScrollY() == 0; -                } - -                @Override -                public View getHostView() { -                    return mNotificationScroller; -                } -            }; -        } +        mStackScrollLayout = (NotificationStackScrollLayout) findViewById( +                R.id.notification_stack_scroller);          mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);          int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);          int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height); -        mExpandHelper = new ExpandHelper(getContext(), (ExpandHelper.Callback) latestItems, +        mExpandHelper = new ExpandHelper(getContext(), mStackScrollLayout,                  minHeight, maxHeight);          mExpandHelper.setEventSource(this); -        mExpandHelper.setScrollAdapter(scrollAdapter); +        mExpandHelper.setScrollAdapter(mStackScrollLayout);          // We really need to be able to animate while window animations are going on          // so that activities may be started asynchronously from panel animations @@ -113,7 +90,7 @@ public class StatusBarWindowView extends FrameLayout      public boolean onInterceptTouchEvent(MotionEvent ev) {          boolean intercept = false;          if (mNotificationPanel.isFullyExpanded() -                && mNotificationScroller.getVisibility() == View.VISIBLE) { +                && mStackScrollLayout.getVisibility() == View.VISIBLE) {              intercept = mExpandHelper.onInterceptTouchEvent(ev);          }          if (!intercept) { @@ -122,7 +99,7 @@ public class StatusBarWindowView extends FrameLayout          if (intercept) {              MotionEvent cancellation = MotionEvent.obtain(ev);              cancellation.setAction(MotionEvent.ACTION_CANCEL); -            latestItems.onInterceptTouchEvent(cancellation); +            mStackScrollLayout.onInterceptTouchEvent(cancellation);              cancellation.recycle();          }          return intercept; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ScrollAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ScrollAdapter.java new file mode 100644 index 000000000000..f35e22dc38ab --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ScrollAdapter.java @@ -0,0 +1,40 @@ +/* + * 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.systemui.statusbar.policy; + +import android.view.View; + +/** + * A scroll adapter which can be queried for meta information about the scroll state + */ +public interface ScrollAdapter { + +    /** +     * @return Whether the view returned by {@link #getHostView()} is scrolled to the top +     */ +    public boolean isScrolledToTop(); + +    /** +     * @return Whether the view returned by {@link #getHostView()} is scrolled to the bottom +     */ +    public boolean isScrolledToBottom(); + +    /** +     * @return The view in which the scrolling is performed +     */ +    public View getHostView(); +} 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 f6eeb6d56e65..04b7f53c9526 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -39,12 +39,13 @@ import com.android.systemui.R;  import com.android.systemui.SwipeHelper;  import com.android.systemui.statusbar.ExpandableNotificationRow;  import com.android.systemui.statusbar.stack.StackScrollState.ViewState; +import com.android.systemui.statusbar.policy.ScrollAdapter;  /**   * A layout which handles a dynamic amount of notifications and presents them in a scrollable stack.   */  public class NotificationStackScrollLayout extends ViewGroup -        implements SwipeHelper.Callback, ExpandHelper.Callback, ExpandHelper.ScrollAdapter { +        implements SwipeHelper.Callback, ExpandHelper.Callback, ScrollAdapter {      private static final String TAG = "NotificationStackScrollLayout";      private static final boolean DEBUG = false; @@ -55,7 +56,7 @@ public class NotificationStackScrollLayout extends ViewGroup      private static final int INVALID_POINTER = -1;      private SwipeHelper mSwipeHelper; -    private boolean mAllowScrolling = true; +    private boolean mSwipingInProgress = true;      private int mCurrentStackHeight = Integer.MAX_VALUE;      private int mOwnScrollY;      private int mMaxLayoutHeight; @@ -89,7 +90,7 @@ public class NotificationStackScrollLayout extends ViewGroup       * The current State this Layout is in       */      private final StackScrollState mCurrentStackScrollState = new StackScrollState(this); - +          private OnChildLocationsChangedListener mListener;      public NotificationStackScrollLayout(Context context) { @@ -279,7 +280,7 @@ public class NotificationStackScrollLayout extends ViewGroup      }      /** -     * Get the current height of the view. This is at most the size of the view given by a the +     * Get the current height of the view. This is at most the msize of the view given by a the       * layout but it can also be made smaller by setting {@link #mCurrentStackHeight}       *       * @return either the layout height or the externally defined height, whichever is smaller @@ -288,6 +289,14 @@ public class NotificationStackScrollLayout extends ViewGroup          return Math.min(mMaxLayoutHeight, mCurrentStackHeight);      } +    public int getItemHeight() { +        return mCollapsedSize; +    } + +    public int getBottomStackPeekSize() { +        return mBottomStackPeekSize; +    } +      public void setLongPressListener(View.OnLongClickListener listener) {          mSwipeHelper.setLongPressListener(listener);      } @@ -298,15 +307,15 @@ public class NotificationStackScrollLayout extends ViewGroup          if (veto != null && veto.getVisibility() != View.GONE) {              veto.performClick();          } -        allowScrolling(true); +        setSwipingInProgress(false);      }      public void onBeginDrag(View v) { -        allowScrolling(false); +        setSwipingInProgress(true);      }      public void onDragCancelled(View v) { -        allowScrolling(true); +        setSwipingInProgress(false);      }      public View getChildAtPosition(MotionEvent ev) { @@ -365,8 +374,11 @@ public class NotificationStackScrollLayout extends ViewGroup          return (veto != null && veto.getVisibility() != View.GONE);      } -    private void allowScrolling(boolean allow) { -        mAllowScrolling = allow; +    private void setSwipingInProgress(boolean isSwiped) { +        mSwipingInProgress = isSwiped; +        if(isSwiped) { +            requestDisallowInterceptTouchEvent(true); +        }      }      @Override @@ -386,7 +398,7 @@ public class NotificationStackScrollLayout extends ViewGroup      @Override      public boolean onTouchEvent(MotionEvent ev) {          boolean scrollerWantsIt = false; -        if (mAllowScrolling) { +        if (!mSwipingInProgress) {              scrollerWantsIt = onScrollTouch(ev);          }          boolean horizontalSwipeWantsIt = false; @@ -409,12 +421,6 @@ public class NotificationStackScrollLayout extends ViewGroup                  }                  boolean isBeingDragged = !mScroller.isFinished();                  setIsBeingDragged(isBeingDragged); -                if (isBeingDragged) { -                    final ViewParent parent = getParent(); -                    if (parent != null) { -                        parent.requestDisallowInterceptTouchEvent(true); -                    } -                }                  /*                   * If being flinged and user touches, stop the fling. isFinished @@ -439,10 +445,6 @@ public class NotificationStackScrollLayout extends ViewGroup                  final int y = (int) ev.getY(activePointerIndex);                  int deltaY = mLastMotionY - y;                  if (!mIsBeingDragged && Math.abs(deltaY) > mTouchSlop) { -                    final ViewParent parent = getParent(); -                    if (parent != null) { -                        parent.requestDisallowInterceptTouchEvent(true); -                    }                      setIsBeingDragged(true);                      if (deltaY > 0) {                          deltaY -= mTouchSlop; @@ -642,7 +644,7 @@ public class NotificationStackScrollLayout extends ViewGroup          if (getChildCount() > 0) {              int contentHeight = getContentHeight();              scrollRange = Math.max(0, -                    contentHeight - mMaxLayoutHeight + mCollapsedSize); +                    contentHeight - mMaxLayoutHeight + mBottomStackPeekSize);          }          return scrollRange;      } @@ -697,7 +699,7 @@ public class NotificationStackScrollLayout extends ViewGroup      @Override      public boolean onInterceptTouchEvent(MotionEvent ev) {          boolean scrollWantsIt = false; -        if (mAllowScrolling) { +        if (!mSwipingInProgress) {              scrollWantsIt = onInterceptTouchEventScroll(ev);          }          boolean swipeWantsIt = false; @@ -763,10 +765,6 @@ public class NotificationStackScrollLayout extends ViewGroup                      mLastMotionY = y;                      initVelocityTrackerIfNotExists();                      mVelocityTracker.addMovement(ev); -                    final ViewParent parent = getParent(); -                    if (parent != null) { -                        parent.requestDisallowInterceptTouchEvent(true); -                    }                  }                  break;              } @@ -823,6 +821,7 @@ public class NotificationStackScrollLayout extends ViewGroup      private void setIsBeingDragged(boolean isDragged) {          mIsBeingDragged = isDragged;          if (isDragged) { +            requestDisallowInterceptTouchEvent(true);              mSwipeHelper.removeLongPressCallback();          }      } @@ -841,10 +840,19 @@ public class NotificationStackScrollLayout extends ViewGroup      }      @Override +    public boolean isScrolledToBottom() { +        return mOwnScrollY >= getScrollRange(); +    } + +    @Override      public View getHostView() {          return this;      } +    public int getEmptyBottomMargin() { +        return Math.max(getHeight() - mContentHeight, 0); +    } +      /**       * A listener that is notified when some child locations might have changed.       */ 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 6d2ba6a9d3bf..4745f3bd5356 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -86,7 +86,7 @@ public class StackScrollAlgorithm {          // First we reset the view states to their default values.          resultState.resetViewStates(); -        // The first element is always in there so it's initialized with 1.0f. +        // The first element is always in there so it's initialized with 1.0f;          algorithmState.itemsInTopStack = 1.0f;          algorithmState.partialInTop = 0.0f;          algorithmState.lastTopStackIndex = 0; @@ -102,7 +102,7 @@ public class StackScrollAlgorithm {          // Phase 3:          updateZValuesForState(resultState, algorithmState); -        // Write the algorithm state to the result. +        // write the algorithm state to the result          resultState.setScrollY(algorithmState.scrollY);      } @@ -151,7 +151,7 @@ public class StackScrollAlgorithm {                  // Case 2:                  // First element of regular scrollview comes next, so the position is just the                  // scrolling position -                nextYPosition = scrollOffset; +                nextYPosition = Math.min(scrollOffset, transitioningPositionStart);                  childViewState.location = StackScrollState.ViewState.LOCATION_TOP_STACK_PEEKING;              } else if (nextYPosition >= transitioningPositionStart) {                  if (currentYPosition >= transitioningPositionStart) { @@ -180,6 +180,7 @@ public class StackScrollAlgorithm {              if (childViewState.location == StackScrollState.ViewState.LOCATION_UNKNOWN) {                  Log.wtf(LOG_TAG, "Failed to assign location for child " + i);              } +            nextYPosition = Math.max(0, nextYPosition);              currentYPosition = nextYPosition;              yPositionInScrollView = yPositionInScrollViewAfterElement;          } @@ -253,6 +254,8 @@ public class StackScrollAlgorithm {              nextYPosition = mCollapsedSize + mPaddingBetweenElements -                      mTopStackIndentationFunctor.getValue(                              algorithmState.itemsInTopStack - i - 1); +            nextYPosition = Math.min(nextYPosition, mLayoutHeight - mCollapsedSize +                    - mBottomStackPeekSize);              if (paddedIndex == 0) {                  childViewState.alpha = 1.0f - algorithmState.partialInTop;                  childViewState.location = StackScrollState.ViewState.LOCATION_TOP_STACK_HIDDEN; diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml index ef640d5fcedb..03d920a4b71b 100644 --- a/packages/VpnDialogs/AndroidManifest.xml +++ b/packages/VpnDialogs/AndroidManifest.xml @@ -1,10 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright (c) 2014 Google Inc. + * + * 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. + */ +-->  <manifest xmlns:android="http://schemas.android.com/apk/res/android"          package="com.android.vpndialogs">      <application android:label="VpnDialogs"              android:allowBackup="false" >          <activity android:name=".ConfirmDialog" -                android:theme="@*android:style/Theme.Holo.Dialog.Alert"> +                android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert">              <intent-filter>                  <action android:name="android.intent.action.MAIN"/>                  <category android:name="android.intent.category.DEFAULT"/> @@ -12,7 +30,7 @@          </activity>          <activity android:name=".ManageDialog" -                android:theme="@*android:style/Theme.Holo.Dialog.Alert" +                android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"                  android:noHistory="true">              <intent-filter>                  <action android:name="android.intent.action.MAIN"/> diff --git a/packages/WallpaperCropper/AndroidManifest.xml b/packages/WallpaperCropper/AndroidManifest.xml index 27755bd2c7cc..81d108589b46 100644 --- a/packages/WallpaperCropper/AndroidManifest.xml +++ b/packages/WallpaperCropper/AndroidManifest.xml @@ -1,3 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright (c) 2014 Google Inc. + * + * 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. + */ +-->  <manifest xmlns:android="http://schemas.android.com/apk/res/android"          package="com.android.wallpapercropper" >          <uses-permission android:name="android.permission.SET_WALLPAPER" /> diff --git a/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml b/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml index 97d700169be2..cf789890f680 100644 --- a/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml +++ b/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml @@ -28,7 +28,7 @@          android:layout_height="match_parent" />      <ProgressBar          android:id="@+id/loading" -        style="@android:style/Widget.Holo.ProgressBar.Large" +        style="@android:style/Widget.DeviceDefault.Light.ProgressBar.Large"          android:visibility="invisible"          android:layout_width="wrap_content"          android:layout_height="wrap_content" diff --git a/packages/WallpaperCropper/res/values/styles.xml b/packages/WallpaperCropper/res/values/styles.xml index 2b63fe01294d..b27a387e295d 100644 --- a/packages/WallpaperCropper/res/values/styles.xml +++ b/packages/WallpaperCropper/res/values/styles.xml @@ -15,13 +15,13 @@  -->  <resources> -    <style name="Theme.WallpaperCropper" parent="@android:style/Theme.Holo"> +    <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault.Light">          <item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>          <item name="android:windowFullscreen">true</item>          <item name="android:windowActionBarOverlay">true</item>      </style> -    <style name="WallpaperCropperActionBar" parent="android:style/Widget.Holo.ActionBar"> +    <style name="WallpaperCropperActionBar" parent="android:style/Widget.DeviceDefault.Light.ActionBar">          <item name="android:displayOptions">showCustom</item>          <item name="android:background">#88000000</item>      </style> diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index c1d9fbd3f15f..b6e761cb8cf9 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -158,6 +158,7 @@ class MountService extends IMountService.Stub          public static final int VolumeListResult               = 110;          public static final int AsecListResult                 = 111;          public static final int StorageUsersListResult         = 112; +        public static final int CryptfsGetfieldResult          = 113;          /*           * 200 series - Requestion action has been successfully completed. @@ -2251,6 +2252,49 @@ class MountService extends IMountService.Stub          }      } +    /** +     * Set a field in the crypto header. +     * @param field field to set +     * @param contents contents to set in field +     */ +    @Override +    public void setField(String field, String contents) throws RemoteException { + +        waitForReady(); + +        final NativeDaemonEvent event; +        try { +            event = mConnector.execute("cryptfs", "setfield", field, contents); +        } catch (NativeDaemonConnectorException e) { +            throw e.rethrowAsParcelableException(); +        } +    } + +    /** +     * Gets a field from the crypto header. +     * @param field field to get +     * @return contents of field +     */ +    @Override +    public String getField(String field) throws RemoteException { + +        waitForReady(); + +        final NativeDaemonEvent event; +        try { +            final String[] contents = NativeDaemonEvent.filterMessageList( +                    mConnector.executeForList("cryptfs", "getfield", field), +                    VoldResponseCode.CryptfsGetfieldResult); +            String result = new String(); +            for (String content : contents) { +                result += content; +            } +            return result; +        } catch (NativeDaemonConnectorException e) { +            throw e.rethrowAsParcelableException(); +        } +    } +      @Override      public String getPassword() throws RemoteException {          if (!isReady()) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index ac6f684ef1ef..e9be1d7def31 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1019,7 +1019,7 @@ public final class ActivityManagerService extends ActivityManagerNative      final ActivityThread mSystemThread;      int mCurrentUserId = 0; -    int[] mCurrentProfileIds = new int[0]; // Accessed by ActivityStack +    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack      private UserManagerService mUserManager;      private final class AppDeathRecipient implements IBinder.DeathRecipient { @@ -6899,18 +6899,27 @@ public final class ActivityManagerService extends ActivityManagerNative                      rti.stackId = tr.stack.mStackId;                      rti.userId = tr.userId; +                    // Traverse upwards looking for any break between main task activities and +                    // utility activities.                      final ArrayList<ActivityRecord> activities = tr.mActivities; -                    int numSet = 0; -                    for (int activityNdx = activities.size() - 1; activityNdx >= 0 && numSet < 2; -                            --activityNdx) { +                    int activityNdx; +                    final int numActivities = activities.size(); +                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; +                            ++activityNdx) {                          final ActivityRecord r = activities.get(activityNdx); -                        if (rti.activityLabel == null && r.recentsLabel != null) { -                            rti.activityLabel = r.recentsLabel; -                            ++numSet; +                        if (r.intent != null && +                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) +                                        != 0) { +                            break;                          } -                        if (rti.activityIcon == null && r.recentsIcon != null) { -                            rti.activityIcon = r.recentsIcon; -                            ++numSet; +                    } +                    // Traverse downwards starting below break looking for set label and icon. +                    for (--activityNdx; activityNdx >= 0; --activityNdx) { +                        final ActivityRecord r = activities.get(activityNdx); +                        if (r.activityLabel != null || r.activityIcon != null) { +                            rti.activityLabel = r.activityLabel; +                            rti.activityIcon = r.activityIcon; +                            break;                          }                      } @@ -6979,21 +6988,13 @@ public final class ActivityManagerService extends ActivityManagerNative      }      @Override -    public void setRecentsLabel(IBinder token, CharSequence recentsLabel) { -        synchronized (this) { -            ActivityRecord r = ActivityRecord.isInStackLocked(token); -            if (r != null) { -                r.recentsLabel = recentsLabel.toString(); -            } -        } -    } - -    @Override -    public void setRecentsIcon(IBinder token, Bitmap recentsIcon) { +    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, +            Bitmap activityIcon) {          synchronized (this) {              ActivityRecord r = ActivityRecord.isInStackLocked(token);              if (r != null) { -                r.recentsIcon = recentsIcon; +                r.activityLabel = activityLabel.toString(); +                r.activityIcon = activityIcon;              }          }      } diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 77f5c59660cf..33b12c571671 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -148,8 +148,8 @@ final class ActivityRecord {      boolean mStartingWindowShown = false;      ActivityContainer mInitialActivityContainer; -    String recentsLabel; -    Bitmap recentsIcon; +    String activityLabel; +    Bitmap activityIcon;      void dump(PrintWriter pw, String prefix) {          final long now = SystemClock.uptimeMillis(); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index d949ba0d90e3..b89472419020 100755 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -344,6 +344,7 @@ final class ActivityStack {       * Checks whether the userid is a profile of the current user.       */      private boolean isCurrentProfileLocked(int userId) { +        if (userId == mCurrentUser) return true;          for (int i = 0; i < mService.mCurrentProfileIds.length; i++) {              if (mService.mCurrentProfileIds[i] == userId) return true;          } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecDevice.java index 99164358f7dc..64b51c9fa14e 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecDevice.java @@ -27,8 +27,12 @@ import java.util.ArrayList;  import java.util.List;  /** - * CecDevice class represents a CEC logical device characterized - * by its device type. A physical device can contain the functions of + * HdmiCecDevice class represents a CEC logical device characterized + * by its device type. It is a superclass of those serving concrete device type. + * Currently we're interested in playback(one of sources), display(sink) device type + * only. The support for the other types like recorder, audio system will come later. + * + * <p>A physical device can contain the functions of   * more than one logical device, in which case it should create   * as many logical devices as necessary.   * @@ -41,7 +45,7 @@ import java.util.List;   *   * <p>Declared as package-private, accessed by HdmiCecService only.   */ -final class HdmiCecDevice { +abstract class HdmiCecDevice {      private static final String TAG = "HdmiCecDevice";      private final int mType; @@ -49,48 +53,56 @@ final class HdmiCecDevice {      // List of listeners to the message/event coming to the device.      private final List<IHdmiCecListener> mListeners = new ArrayList<IHdmiCecListener>();      private final Binder mBinder = new Binder(); +    private final HdmiCecService mService; -    private String mName;      private boolean mIsActiveSource;      /** +     * Factory method that creates HdmiCecDevice instance to the device type. +     */ +    public static HdmiCecDevice create(HdmiCecService service, int type) { +        if (type == HdmiCec.DEVICE_PLAYBACK) { +            return new HdmiCecDevicePlayback(service, type); +        } else if (type == HdmiCec.DEVICE_TV) { +            return new HdmiCecDeviceTv(service, type); +        } +        return null; +    } + +    /**       * Constructor.       */ -    public HdmiCecDevice(int type) { +    public HdmiCecDevice(HdmiCecService service, int type) { +        mService = service;          mType = type;          mIsActiveSource = false;      }      /** -     * Return the binder token that identifies this instance. +     * Called right after the class is instantiated. This method can be used to +     * implement any initialization tasks for the instance.       */ -    public Binder getToken() { -        return mBinder; -    } +    abstract public void initialize();      /** -     * Return the type of this device. +     * Return the binder token that identifies this instance.       */ -    public int getType() { -        return mType; +    public Binder getToken() { +        return mBinder;      }      /** -     * Set the name of the device. The name will be transferred via the message -     * <Set OSD Name> to other HDMI-CEC devices connected through HDMI -     * cables and shown on TV screen to identify the devicie. -     * -     * @param name name of the device +     * Return the service instance.       */ -    public void setName(String name) { -        mName = name; +    public HdmiCecService getService() { +        return mService;      }      /** -     * Return the name of this device. +     * Return the type of this device.       */ -    public String getName() { -        return mName; +    public int getType() { +        return mType;      }      /** @@ -128,6 +140,7 @@ final class HdmiCecDevice {          if (opcode == HdmiCec.MESSAGE_ACTIVE_SOURCE) {              mIsActiveSource = false;          } +          if (mListeners.size() == 0) {              return;          } @@ -167,4 +180,13 @@ final class HdmiCecDevice {      public void setIsActiveSource(boolean state) {          mIsActiveSource = state;      } + +    /** +     * Check if the connected sink device is in powered-on state. The default implementation +     * simply returns false. Should be overriden by subclass to report the correct state. +     */ +    public boolean isSinkDeviceOn() { +        Log.w(TAG, "Not valid for the device type: " + mType); +        return false; +    }  } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecDevicePlayback.java new file mode 100644 index 000000000000..0310264f0270 --- /dev/null +++ b/services/core/java/com/android/server/hdmi/HdmiCecDevicePlayback.java @@ -0,0 +1,98 @@ +/* + * 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.server.hdmi; + +import android.hardware.hdmi.HdmiCec; + +/** + * Class for the logical device of playback type. Devices such as DVD/Blueray player + * that support 'playback' feature are classified as playback device. It is common + * that they don't have built-in display, therefore need to talk, stream their contents + * to TV/display device which is connected through HDMI cable. + * + * <p>It closely monitors the status of display device (other devices can be of interest + * too, but with much less priority), declares itself as 'active source' to have + * display show its output, switch the source state as ordered by display that may be + * talking to many other devices connected to it. It also receives commands from display + * such as remote control signal, standby, status report, playback mode. + * + * <p>Declared as package-private, accessed by HdmiCecService only. + */ +final class HdmiCecDevicePlayback extends HdmiCecDevice { +    private static final String TAG = "HdmiCecDevicePlayback"; + +    private int mSinkDevicePowerStatus; + +    /** +     * Constructor. +     */ +    public HdmiCecDevicePlayback(HdmiCecService service, int type) { +        super(service, type); +        mSinkDevicePowerStatus = HdmiCec.POWER_STATUS_UNKNOWN; +    } + +    @Override +    public void initialize() { +        // Playback device tries to obtain the power status of TV/display when created, +        // and maintains it all through its lifecycle. CEC spec says there is +        // a maximum 1 second response time. Therefore it should be kept in mind +        // that there can be as much amount of period of time the power status +        // of the display remains unknown after the query is sent out. +        queryTvPowerStatus(); +    } + +    private void queryTvPowerStatus() { +        getService().sendMessage(getType(), HdmiCec.ADDR_TV, +                HdmiCec.MESSAGE_GIVE_DEVICE_POWER_STATUS, HdmiCecService.EMPTY_PARAM); +    } + +    @Override +    public void handleMessage(int srcAddress, int dstAddress, int opcode, byte[] params) { +        // Updates power status of display. The cases are: +        // 1) Response for the queried power status request arrives. Update the status. +        // 2) Broadcast or direct <Standby> command from TV, which is sent as TV itself is going +        //    into standby mode too. +        // 3) Broadcast <Report Physical Address> command from TV, which is sent while it boots up. +        if (opcode == HdmiCec.MESSAGE_REPORT_POWER_STATUS) { +            mSinkDevicePowerStatus = params[0]; +        } else if (srcAddress == HdmiCec.ADDR_TV) { +            if (opcode == HdmiCec.MESSAGE_STANDBY) { +                mSinkDevicePowerStatus = HdmiCec.POWER_STATUS_STANDBY; +            } else if (opcode == HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS) { +                mSinkDevicePowerStatus = HdmiCec.POWER_STATUS_ON; +            } +        } +        super.handleMessage(srcAddress, dstAddress, opcode, params); +    } + +    @Override +    public void handleHotplug(boolean connected) { +        // If cable get disconnected sink device becomes unreachable. Switch the status +        // to unknown, and query the status once the cable gets connected back. +        if (!connected) { +            mSinkDevicePowerStatus = HdmiCec.POWER_STATUS_UNKNOWN; +        } else { +            queryTvPowerStatus(); +        } +        super.handleHotplug(connected); +    } + +    @Override +    public boolean isSinkDeviceOn() { +        return mSinkDevicePowerStatus == HdmiCec.POWER_STATUS_ON; +    } +} diff --git a/services/core/java/com/android/server/hdmi/HdmiCecDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecDeviceTv.java new file mode 100644 index 000000000000..09ff3ca75d6b --- /dev/null +++ b/services/core/java/com/android/server/hdmi/HdmiCecDeviceTv.java @@ -0,0 +1,35 @@ +/* + * 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.server.hdmi; + +/** + * Class for logical device of TV type. + */ +final class HdmiCecDeviceTv extends HdmiCecDevice { +    private static final String TAG = "HdmiCecDeviceTv"; + +    /** +     * Constructor. +     */ +    public HdmiCecDeviceTv(HdmiCecService service, int type) { +        super(service, type); +    } + +    public void initialize() { +        // TODO: Do the initialization task for TV device here. +    } +} diff --git a/services/core/java/com/android/server/hdmi/HdmiCecService.java b/services/core/java/com/android/server/hdmi/HdmiCecService.java index 0a7236c7d7e4..aa496c5db622 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecService.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecService.java @@ -23,6 +23,7 @@ import android.hardware.hdmi.HdmiCecMessage;  import android.hardware.hdmi.IHdmiCecListener;  import android.hardware.hdmi.IHdmiCecService;  import android.os.Binder; +import android.os.Build;  import android.os.IBinder;  import android.os.RemoteException;  import android.text.TextUtils; @@ -30,6 +31,7 @@ import android.util.Log;  import android.util.SparseArray;  import com.android.server.SystemService; +import libcore.util.EmptyArray;  import java.io.FileDescriptor;  import java.io.PrintWriter; @@ -37,8 +39,6 @@ import java.nio.charset.Charset;  import java.util.ArrayList;  import java.util.Locale; -import libcore.util.EmptyArray; -  /**   * Provides a service for sending and processing HDMI-CEC messages, and providing   * the information on HDMI settings in general. @@ -65,7 +65,7 @@ public final class HdmiCecService extends SystemService {      private static final String PERMISSION = "android.permission.HDMI_CEC"; -    private static final byte[] EMPTY_PARAM = EmptyArray.BYTE; +    static final byte[] EMPTY_PARAM = EmptyArray.BYTE;      public HdmiCecService(Context context) {          super(context); @@ -76,7 +76,12 @@ public final class HdmiCecService extends SystemService {      @Override      public void onStart() {          mNativePtr = nativeInit(this); -        publishBinderService(Context.HDMI_CEC_SERVICE, new BinderService()); +        if (mNativePtr != 0) { +            // TODO: Consider using a dedicated, configurable identifier for OSD name, maybe from +            //       Settings. It should be ASCII only, not a very long one (limited to 15 chars). +            setOsdNameLocked(Build.MODEL); +            publishBinderService(Context.HDMI_CEC_SERVICE, new BinderService()); +        }      }      /** @@ -88,7 +93,6 @@ public final class HdmiCecService extends SystemService {          //       but better be handled in service by turning off the screen          //       or putting the device into suspend mode. List up such messages          //       and handle them here. -        int type = HdmiCec.getTypeFromAddress(dstAddress);          synchronized (mLock) {              if (dstAddress == HdmiCec.ADDR_BROADCAST) {                  for (int i = 0; i < mLogicalDevices.size(); ++i) { @@ -96,6 +100,7 @@ public final class HdmiCecService extends SystemService {                              params);                  }              } else { +                int type = HdmiCec.getTypeFromAddress(dstAddress);                  HdmiCecDevice device = mLogicalDevices.get(type);                  if (device == null) {                      Log.w(TAG, "logical device not found. type: " + type); @@ -138,22 +143,6 @@ public final class HdmiCecService extends SystemService {      }      /** -     * Called by native when a request for the device OSD name was received. -     * The native part uses the return value to generate the message -     * <Set Osd Name> in response. -     */ -    private byte[] getOsdName(int type) { -        // TODO: Consider getting the OSD name from device name instead. -        synchronized (mLock) { -            HdmiCecDevice device = mLogicalDevices.get(type); -            if (device != null) { -                return device.getName().getBytes(Charset.forName("US-ASCII")); -            } -        } -        return null; -    } - -    /**       * Called by native when a request for the menu language of the device was       * received. The native part uses the return value to generate the message       * <Set Menu Language> in response. The language should be of @@ -174,8 +163,7 @@ public final class HdmiCecService extends SystemService {          synchronized (mLock) {              for (int i = 0; i < mLogicalDevices.size(); ++i) {                  HdmiCecDevice device = mLogicalDevices.valueAt(i); -                pw.println("Device: name=" + device.getName() + -                           ", type=" + device.getType() + +                pw.println("Device: type=" + device.getType() +                             ", active=" + device.isActiveSource());              }          } @@ -205,6 +193,15 @@ public final class HdmiCecService extends SystemService {          throw new IllegalArgumentException("Device not found");      } +    // package-private. Used by HdmiCecDevice and its subclasses only. +    void sendMessage(int type, int address, int opcode, byte[] params) { +        nativeSendMessage(mNativePtr, type, address, opcode, params); +    } + +    private void setOsdNameLocked(String name) { +        nativeSetOsdName(mNativePtr, name.getBytes(Charset.forName("US-ASCII"))); +    } +      private final class ListenerRecord implements IBinder.DeathRecipient {          private final IHdmiCecListener mListener;          private final int mType; @@ -248,8 +245,12 @@ public final class HdmiCecService extends SystemService {                          Log.e(TAG, "Logical address was not allocated");                          return null;                      } else { -                        device = new HdmiCecDevice(type); -                        device.setName(HdmiCec.getDefaultDeviceName(address)); +                        device = HdmiCecDevice.create(HdmiCecService.this, type); +                        if (device == null) { +                            Log.e(TAG, "Device type not supported yet."); +                            return null; +                        } +                        device.initialize();                          mLogicalDevices.put(type, device);                      }                  } @@ -272,18 +273,6 @@ public final class HdmiCecService extends SystemService {          }          @Override -        public void setOsdName(IBinder b, String name) { -            enforceAccessPermission(); -            if (TextUtils.isEmpty(name)) { -                throw new IllegalArgumentException("name must not be null"); -            } -            synchronized (mLock) { -                HdmiCecDevice device = getLogicalDeviceLocked(b); -                device.setName(name); -            } -        } - -        @Override          public void sendActiveSource(IBinder b) {              enforceAccessPermission();              synchronized (mLock) { @@ -331,12 +320,11 @@ public final class HdmiCecService extends SystemService {          }          @Override -        public void sendGiveDevicePowerStatus(IBinder b, int address) { +        public boolean isTvOn(IBinder b) {              enforceAccessPermission();              synchronized (mLock) {                  HdmiCecDevice device = getLogicalDeviceLocked(b); -                nativeSendMessage(mNativePtr, device.getType(), address, -                        HdmiCec.MESSAGE_GIVE_DEVICE_POWER_STATUS, EMPTY_PARAM); +                return device.isSinkDeviceOn();              }          } @@ -398,4 +386,5 @@ public final class HdmiCecService extends SystemService {      private static native void nativeSendMessage(long handler, int deviceType, int destination,              int opcode, byte[] params);      private static native int nativeGetPhysicalAddress(long handler); +    private static native void nativeSetOsdName(long handler, byte[] name);  } diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java index faa5a432af7d..d9e2b91e27d4 100644 --- a/services/core/java/com/android/server/notification/NotificationUsageStats.java +++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java @@ -20,7 +20,6 @@ import com.android.server.notification.NotificationManagerService.NotificationRe  import android.os.SystemClock;  import android.service.notification.StatusBarNotification; -import android.util.Log;  import java.io.PrintWriter;  import java.util.HashMap; @@ -250,21 +249,28 @@ public class NotificationUsageStats {       */      public static class Aggregate {          long numSamples; -        long sum; -        long avg; +        double avg; +        double sum2; +        double var;          public void addSample(long sample) { +            // Welford's "Method for Calculating Corrected Sums of Squares" +            // http://www.jstor.org/stable/1266577?seq=2              numSamples++; -            sum += sample; -            avg = sum / numSamples; +            final double n = numSamples; +            final double delta = sample - avg; +            avg += (1.0 / n) * delta; +            sum2 += ((n - 1) / n) * delta * delta; +            final double divisor = numSamples == 1 ? 1.0 : n - 1.0; +            var = sum2 / divisor;          }          @Override          public String toString() {              return "Aggregate{" +                      "numSamples=" + numSamples + -                    ", sum=" + sum +                      ", avg=" + avg + +                    ", var=" + var +                      '}';          }      } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 288e8e0b1493..ff90cae821f5 100755 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -9201,7 +9201,7 @@ public class PackageManagerService extends IPackageManager.Stub {          }          // Successfully disabled the old package. Now proceed with re-installation -        mLastScanError = PackageManager.INSTALL_SUCCEEDED; +        res.returnCode = mLastScanError = PackageManager.INSTALL_SUCCEEDED;          pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;          newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user);          if (newPackage == null) { @@ -9214,9 +9214,20 @@ public class PackageManagerService extends IPackageManager.Stub {                  final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras;                  newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;                  newPkgSetting.lastUpdateTime = System.currentTimeMillis(); + +                // is the update attempting to change shared user? that isn't going to work... +                if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) { +                    Slog.w(TAG, "Forbidding shared user change from " + oldPkgSetting.sharedUser +                            + " to " + newPkgSetting.sharedUser); +                    res.returnCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; +                    updatedSettings = true; +                } +            } + +            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { +                updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res); +                updatedSettings = true;              } -            updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res); -            updatedSettings = true;          }          if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index a3883182d599..80c3c8e6483d 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -2541,6 +2541,9 @@ public final class PowerManagerService extends com.android.server.SystemService          @Override // Binder call          public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,                  String packageName, int uid) { +            if (uid < 0) { +                uid = Binder.getCallingUid(); +            }              acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null);          } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 2e5b8ded9e35..b12ae4f2409e 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -86,6 +86,7 @@ import android.os.StrictMode;  import android.os.SystemClock;  import android.os.SystemProperties;  import android.os.Trace; +import android.os.UserHandle;  import android.os.WorkSource;  import android.provider.Settings;  import android.util.DisplayMetrics; @@ -311,7 +312,7 @@ public class WindowManagerService extends IWindowManager.Stub       * Users that are profiles of the current user. These are also allowed to show windows       * on the current user.       */ -    int[] mCurrentProfileIds = new int[0]; +    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER};      final Context mContext; @@ -5255,6 +5256,7 @@ public class WindowManagerService extends IWindowManager.Stub      /* Called by WindowState */      boolean isCurrentProfileLocked(int userId) { +        if (userId == mCurrentUserId) return true;          for (int i = 0; i < mCurrentProfileIds.length; i++) {              if (mCurrentProfileIds[i] == userId) return true;          } diff --git a/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp b/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp index 61edda83bd9b..a00aaa81da63 100644 --- a/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp +++ b/services/core/jni/com_android_server_hdmi_HdmiCecService.cpp @@ -20,7 +20,7 @@  #include "ScopedPrimitiveArray.h" -#include <cstring> +#include <string>  #include <deque>  #include <map> @@ -34,7 +34,6 @@ static struct {      jmethodID handleMessage;      jmethodID handleHotplug;      jmethodID getActiveSource; -    jmethodID getOsdName;      jmethodID getLanguage;  } gHdmiCecServiceClassInfo; @@ -84,6 +83,7 @@ public:      void sendSetMenuLanguage(cec_logical_address_t srcAddr, cec_logical_address_t dstAddr);      void sendCecMessage(const cec_message_t& message); +    void setOsdName(const char* name, size_t len);  private:      enum { @@ -156,6 +156,7 @@ private:      std::deque<MessageEntry> mMessageQueue;      uint16_t mPhysicalAddress; +    std::string mOsdName;  }; @@ -373,6 +374,10 @@ void HdmiCecHandler::sendCecMessage(const cec_message_t& message) {      mDevice->send_message(mDevice, &message);  } +void HdmiCecHandler::setOsdName(const char* name, size_t len) { +    mOsdName.assign(name, min(len, CEC_MESSAGE_BODY_MAX_LENGTH - 1)); +} +  // static  void HdmiCecHandler::onReceived(const hdmi_event_t* event, void* arg) {      HdmiCecHandler* handler = static_cast<HdmiCecHandler*>(arg); @@ -504,18 +509,9 @@ void HdmiCecHandler::handleRequestActiveSource() {  }  void HdmiCecHandler::handleGetOsdName(const cec_message_t& msg) { -    cec_logical_address_t addr = msg.destination; -    JNIEnv* env = AndroidRuntime::getJNIEnv(); -    jbyteArray res = (jbyteArray) env->CallObjectMethod(mCallbacksObj, -            gHdmiCecServiceClassInfo.getOsdName, -            getDeviceType(addr)); -    jbyte *name = env->GetByteArrayElements(res, NULL); -    if (name != NULL) { -        sendSetOsdName(addr, msg.initiator, reinterpret_cast<const char *>(name), -                env->GetArrayLength(res)); -        env->ReleaseByteArrayElements(res, name, JNI_ABORT); +    if (!mOsdName.empty()) { +        sendSetOsdName(msg.destination, msg.initiator, mOsdName.c_str(), mOsdName.length());      } -    checkAndClearExceptionFromCallback(env, __FUNCTION__);  }  void HdmiCecHandler::handleGiveDeviceVendorID(const cec_message_t& msg) { @@ -562,8 +558,6 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj) {              "handleHotplug", "(Z)V");      GET_METHOD_ID(gHdmiCecServiceClassInfo.getActiveSource, clazz,              "getActiveSource", "()I"); -    GET_METHOD_ID(gHdmiCecServiceClassInfo.getOsdName, clazz, -            "getOsdName", "(I)[B");      GET_METHOD_ID(gHdmiCecServiceClassInfo.getLanguage, clazz,              "getLanguage", "(I)Ljava/lang/String;"); @@ -603,6 +597,15 @@ static jint nativeGetPhysicalAddress(JNIEnv* env, jclass clazz, jlong handlerPtr      return handler->getPhysicalAddress();  } +static void nativeSetOsdName(JNIEnv* env, jclass clazz, jlong handlerPtr, jbyteArray name) { +    HdmiCecHandler *handler = reinterpret_cast<HdmiCecHandler *>(handlerPtr); +    jsize len = env->GetArrayLength(name); +    if (len > 0) { +        ScopedByteArrayRO namePtr(env, name); +        handler->setOsdName(reinterpret_cast<const char *>(namePtr.get()), len); +    } +} +  static JNINativeMethod sMethods[] = {      /* name, signature, funcPtr */      { "nativeInit", "(Lcom/android/server/hdmi/HdmiCecService;)J", @@ -615,6 +618,8 @@ static JNINativeMethod sMethods[] = {              (void *)nativeRemoveLogicalAddress },      { "nativeGetPhysicalAddress", "(J)I",              (void *)nativeGetPhysicalAddress }, +    { "nativeSetOsdName", "(J[B)V", +            (void *)nativeSetOsdName },  };  #define CLASS_PATH "com/android/server/hdmi/HdmiCecService" diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index ce205c057b0d..8f2adc8f47b2 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -269,7 +269,7 @@ public final class SystemServer {      private void createSystemContext() {          ActivityThread activityThread = ActivityThread.systemMain();          mSystemContext = activityThread.getSystemContext(); -        mSystemContext.setTheme(android.R.style.Theme_Holo); +        mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);      }      private void startBootstrapServices() { diff --git a/tests/DynamicDrawableTest/lint.xml b/tests/DynamicDrawableTest/lint.xml deleted file mode 100644 index ee0eead5bb7d..000000000000 --- a/tests/DynamicDrawableTest/lint.xml +++ /dev/null @@ -1,3 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<lint> -</lint>
\ No newline at end of file diff --git a/tests/DynamicDrawableTest/Android.mk b/tests/VectorDrawableTest/Android.mk index 5c51301b5532..dd8a4d474ae2 100644 --- a/tests/DynamicDrawableTest/Android.mk +++ b/tests/VectorDrawableTest/Android.mk @@ -19,7 +19,7 @@ include $(CLEAR_VARS)  LOCAL_SRC_FILES := $(call all-subdir-java-files) -LOCAL_PACKAGE_NAME := DynamicDrawableTest +LOCAL_PACKAGE_NAME := VectorDrawableTest  LOCAL_MODULE_TAGS := tests diff --git a/tests/DynamicDrawableTest/AndroidManifest.xml b/tests/VectorDrawableTest/AndroidManifest.xml index 4ca3e3cd3dd5..06effe28a0e1 100644 --- a/tests/DynamicDrawableTest/AndroidManifest.xml +++ b/tests/VectorDrawableTest/AndroidManifest.xml @@ -73,7 +73,7 @@              </intent-filter>          </activity> -         +          <activity              android:name="VectorCheckbox"              android:label="On a Checkbox" > diff --git a/tests/DynamicDrawableTest/res/drawable-hdpi/icon.png b/tests/VectorDrawableTest/res/drawable-hdpi/icon.png Binary files differindex 60fbdf5d0403..60fbdf5d0403 100644 --- a/tests/DynamicDrawableTest/res/drawable-hdpi/icon.png +++ b/tests/VectorDrawableTest/res/drawable-hdpi/icon.png diff --git a/tests/DynamicDrawableTest/res/drawable/icon.png b/tests/VectorDrawableTest/res/drawable/icon.png Binary files differindex cb40a1988b52..cb40a1988b52 100644 --- a/tests/DynamicDrawableTest/res/drawable/icon.png +++ b/tests/VectorDrawableTest/res/drawable/icon.png diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable01.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable01.xml index 4f4b386bcff8..538993f53e97 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable01.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable01.xml @@ -14,7 +14,7 @@       limitations under the License.  -->  <vector xmlns:android="http://schemas.android.com/apk/res/android" -    android:trigger="state_checked" > +    android:trigger="state_checked" android:versionCode="1" >      <size          android:height="64dp" diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable02.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable02.xml index 49906d17ebb7..49906d17ebb7 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable02.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable02.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable03.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml index 137049df2476..137049df2476 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable03.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable04.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml index cffb73f36b89..cffb73f36b89 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable04.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable05.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable05.xml index bcf3ae6ceb67..bcf3ae6ceb67 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable05.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable05.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable06.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable06.xml index 73ff5e2e9837..73ff5e2e9837 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable06.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable06.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable07.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable07.xml index 99d37efe338f..99d37efe338f 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable07.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable07.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable08.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable08.xml index f8a03d761714..f8a03d761714 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable08.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable08.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable09.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable09.xml index 09934de707f7..09934de707f7 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable09.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable09.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable10.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable10.xml index f17f67ac6acc..f17f67ac6acc 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable10.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable10.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable11.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable11.xml index a1a03be9e0ca..8787b342b225 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable11.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable11.xml @@ -29,7 +29,7 @@              android:pathData="M 20.28125,2.0000002 C 17.352748,2.0000002 15,4.3527485 15,7.2812502 L 15,8.0000002 L 13.15625,8.0000002 C 9.7507553,8.0000002 7,10.750759 7,14.15625 L 7,39.84375 C 7,43.24924 9.7507558,46 13.15625,46 L 33.84375,46 C 37.249245,46 39.999999,43.24924 40,39.84375 L 40,14.15625 C 40,10.75076 37.249243,8.0000002 33.84375,8.0000002 L 32,8.0000002 L 32,7.2812502 C 32,4.3527485 29.647252,2.0000002 26.71875,2.0000002 L 20.28125,2.0000002 z"              android:fill="#3388ff"              android:stroke="#ff8833" -            android:strokeWidth="1"  +            android:strokeWidth="1"              android:rotation="0"/>           <path              android:name="spark" diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable12.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable12.xml index 89748d53f44a..89748d53f44a 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable12.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable12.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable13.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable13.xml index 43dda52c5889..43dda52c5889 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable13.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable13.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable14.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable14.xml index 0f1f14993f97..0f1f14993f97 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable14.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable14.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable15.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable15.xml index 6bc946fe7f91..6bc946fe7f91 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable15.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable15.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable16.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable16.xml index c9c8e8a8d4f2..c9c8e8a8d4f2 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable16.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable16.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable17.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable17.xml index 9427652a1950..9427652a1950 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable17.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable17.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable18.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable18.xml index 83dfbd20a1d3..83dfbd20a1d3 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable18.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable18.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable19.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable19.xml index 013254f00b7a..013254f00b7a 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable19.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable19.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable20.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable20.xml index aba7e5f23bcb..aba7e5f23bcb 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_drawable20.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable20.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_create.xml b/tests/VectorDrawableTest/res/drawable/vector_icon_create.xml index 88971817fc3f..88971817fc3f 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_icon_create.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_icon_create.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_delete.xml b/tests/VectorDrawableTest/res/drawable/vector_icon_delete.xml index 2c7ebbd2660c..2c7ebbd2660c 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_icon_delete.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_icon_delete.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_heart.xml b/tests/VectorDrawableTest/res/drawable/vector_icon_heart.xml index e4cf78c90edd..e4cf78c90edd 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_icon_heart.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_icon_heart.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_schedule.xml b/tests/VectorDrawableTest/res/drawable/vector_icon_schedule.xml index cec12bac095d..cec12bac095d 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_icon_schedule.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_icon_schedule.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_settings.xml b/tests/VectorDrawableTest/res/drawable/vector_icon_settings.xml index 5fe1fb6d635f..5fe1fb6d635f 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_icon_settings.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_icon_settings.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_test01.xml b/tests/VectorDrawableTest/res/drawable/vector_test01.xml index 6beb9d847ea9..6beb9d847ea9 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_test01.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_test01.xml diff --git a/tests/DynamicDrawableTest/res/drawable/vector_test02.xml b/tests/VectorDrawableTest/res/drawable/vector_test02.xml index 2c1a28e2bcdb..2c1a28e2bcdb 100644 --- a/tests/DynamicDrawableTest/res/drawable/vector_test02.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_test02.xml diff --git a/tests/DynamicDrawableTest/res/values/strings.xml b/tests/VectorDrawableTest/res/values/strings.xml index 64163c27c5da..64163c27c5da 100644 --- a/tests/DynamicDrawableTest/res/values/strings.xml +++ b/tests/VectorDrawableTest/res/values/strings.xml diff --git a/tests/DynamicDrawableTest/res/values/styles.xml b/tests/VectorDrawableTest/res/values/styles.xml index 460c0dbaf04c..460c0dbaf04c 100644 --- a/tests/DynamicDrawableTest/res/values/styles.xml +++ b/tests/VectorDrawableTest/res/values/styles.xml diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java index 1060d1996b92..0b3ea4d293d2 100644 --- a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java @@ -60,7 +60,6 @@ public class VectorCheckbox extends Activity {              CheckBox checkBox = new CheckBox(this);              bArray[i] = checkBox;              checkBox.setWidth(200); -            checkBox.setWidth(200);              checkBox.setButtonDrawable(icon[i]);              container.addView(checkBox);          } diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java index 0ae4b6de040c..88ae398ad9f6 100644 --- a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java @@ -59,7 +59,6 @@ public class VectorDrawable01 extends Activity implements View.OnClickListener {              Button button = new Button(this);              bArray[i] = button;              button.setWidth(200); -            button.setWidth(200);              button.setBackgroundResource(icon[i]);              container.addView(button);              button.setOnClickListener(this); diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java index a00bc5e35c15..a00bc5e35c15 100644 --- a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java index 9e8ea75c527e..39292980d86c 100644 --- a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java @@ -74,7 +74,6 @@ public class VectorDrawablePerformance extends Activity implements View.OnClickL          for (int i = 0; i < icon.length; i++) {              Button button = new Button(this);              button.setWidth(200); -            button.setWidth(200);              button.setBackgroundResource(icon[i]);              container.addView(button);              button.setOnClickListener(this); diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java index 9d3eded60721..9d3eded60721 100644 --- a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java index 704d3d76bbec..704d3d76bbec 100644 --- a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java index 34301923b0b6..34301923b0b6 100644 --- a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java  |