Merge "Improve unlock motion." into lmp-preview-dev
diff --git a/api/current.txt b/api/current.txt
index 8953d7e..06acbf4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1858,28 +1858,28 @@
field public static final int TextAppearance_Large = 16973890; // 0x1030042
field public static final int TextAppearance_Large_Inverse = 16973891; // 0x1030043
field public static final int TextAppearance_Material = 16974350; // 0x103020e
- field public static final int TextAppearance_Material_Body1 = 16974550; // 0x10302d6
- field public static final int TextAppearance_Material_Body2 = 16974549; // 0x10302d5
- field public static final int TextAppearance_Material_Button = 16974553; // 0x10302d9
- field public static final int TextAppearance_Material_Caption = 16974551; // 0x10302d7
+ field public static final int TextAppearance_Material_Body1 = 16974552; // 0x10302d8
+ field public static final int TextAppearance_Material_Body2 = 16974551; // 0x10302d7
+ field public static final int TextAppearance_Material_Button = 16974555; // 0x10302db
+ field public static final int TextAppearance_Material_Caption = 16974553; // 0x10302d9
field public static final int TextAppearance_Material_DialogWindowTitle = 16974351; // 0x103020f
- field public static final int TextAppearance_Material_Display1 = 16974545; // 0x10302d1
- field public static final int TextAppearance_Material_Display2 = 16974544; // 0x10302d0
- field public static final int TextAppearance_Material_Display3 = 16974543; // 0x10302cf
- field public static final int TextAppearance_Material_Display4 = 16974542; // 0x10302ce
- field public static final int TextAppearance_Material_Headline = 16974546; // 0x10302d2
+ field public static final int TextAppearance_Material_Display1 = 16974547; // 0x10302d3
+ field public static final int TextAppearance_Material_Display2 = 16974546; // 0x10302d2
+ field public static final int TextAppearance_Material_Display3 = 16974545; // 0x10302d1
+ field public static final int TextAppearance_Material_Display4 = 16974544; // 0x10302d0
+ field public static final int TextAppearance_Material_Headline = 16974548; // 0x10302d4
field public static final int TextAppearance_Material_Inverse = 16974352; // 0x1030210
field public static final int TextAppearance_Material_Large = 16974353; // 0x1030211
field public static final int TextAppearance_Material_Large_Inverse = 16974354; // 0x1030212
field public static final int TextAppearance_Material_Medium = 16974355; // 0x1030213
field public static final int TextAppearance_Material_Medium_Inverse = 16974356; // 0x1030214
- field public static final int TextAppearance_Material_Menu = 16974552; // 0x10302d8
+ field public static final int TextAppearance_Material_Menu = 16974554; // 0x10302da
field public static final int TextAppearance_Material_SearchResult_Subtitle = 16974357; // 0x1030215
field public static final int TextAppearance_Material_SearchResult_Title = 16974358; // 0x1030216
field public static final int TextAppearance_Material_Small = 16974359; // 0x1030217
field public static final int TextAppearance_Material_Small_Inverse = 16974360; // 0x1030218
- field public static final int TextAppearance_Material_Subhead = 16974548; // 0x10302d4
- field public static final int TextAppearance_Material_Title = 16974547; // 0x10302d3
+ field public static final int TextAppearance_Material_Subhead = 16974550; // 0x10302d6
+ field public static final int TextAppearance_Material_Title = 16974549; // 0x10302d5
field public static final int TextAppearance_Material_Widget = 16974362; // 0x103021a
field public static final int TextAppearance_Material_Widget_ActionBar_Menu = 16974363; // 0x103021b
field public static final int TextAppearance_Material_Widget_ActionBar_Subtitle = 16974364; // 0x103021c
@@ -1928,12 +1928,12 @@
field public static final int TextAppearance_Widget_TextView_SpinnerItem = 16973906; // 0x1030052
field public static final int TextAppearance_WindowTitle = 16973907; // 0x1030053
field public static final int Theme = 16973829; // 0x1030005
- field public static final int ThemeOverlay = 16974414; // 0x103024e
- field public static final int ThemeOverlay_Material = 16974415; // 0x103024f
- field public static final int ThemeOverlay_Material_ActionBar = 16974416; // 0x1030250
- field public static final int ThemeOverlay_Material_Dark = 16974418; // 0x1030252
- field public static final int ThemeOverlay_Material_Dark_ActionBar = 16974419; // 0x1030253
- field public static final int ThemeOverlay_Material_Light = 16974417; // 0x1030251
+ field public static final int ThemeOverlay = 16974416; // 0x1030250
+ field public static final int ThemeOverlay_Material = 16974417; // 0x1030251
+ field public static final int ThemeOverlay_Material_ActionBar = 16974418; // 0x1030252
+ field public static final int ThemeOverlay_Material_Dark = 16974420; // 0x1030254
+ field public static final int ThemeOverlay_Material_Dark_ActionBar = 16974421; // 0x1030255
+ field public static final int ThemeOverlay_Material_Light = 16974419; // 0x1030253
field public static final int Theme_Black = 16973832; // 0x1030008
field public static final int Theme_Black_NoTitleBar = 16973833; // 0x1030009
field public static final int Theme_Black_NoTitleBar_Fullscreen = 16973834; // 0x103000a
@@ -1963,6 +1963,7 @@
field public static final int Theme_DeviceDefault_NoActionBar_Overscan = 16974303; // 0x10301df
field public static final int Theme_DeviceDefault_NoActionBar_TranslucentDecor = 16974307; // 0x10301e3
field public static final int Theme_DeviceDefault_Panel = 16974138; // 0x103013a
+ field public static final int Theme_DeviceDefault_Settings = 16974384; // 0x1030230
field public static final int Theme_DeviceDefault_Wallpaper = 16974140; // 0x103013c
field public static final int Theme_DeviceDefault_Wallpaper_NoTitleBar = 16974141; // 0x103013d
field public static final int Theme_Dialog = 16973835; // 0x103000b
@@ -2000,36 +2001,37 @@
field public static final int Theme_Light_NoTitleBar_Fullscreen = 16973838; // 0x103000e
field public static final int Theme_Light_Panel = 16973914; // 0x103005a
field public static final int Theme_Light_WallpaperSettings = 16973922; // 0x1030062
- field public static final int Theme_Material = 16974384; // 0x1030230
- field public static final int Theme_Material_Dialog = 16974385; // 0x1030231
- field public static final int Theme_Material_DialogWhenLarge = 16974389; // 0x1030235
- field public static final int Theme_Material_DialogWhenLarge_NoActionBar = 16974390; // 0x1030236
- field public static final int Theme_Material_Dialog_MinWidth = 16974386; // 0x1030232
- field public static final int Theme_Material_Dialog_NoActionBar = 16974387; // 0x1030233
- field public static final int Theme_Material_Dialog_NoActionBar_MinWidth = 16974388; // 0x1030234
- field public static final int Theme_Material_InputMethod = 16974391; // 0x1030237
- field public static final int Theme_Material_Light = 16974400; // 0x1030240
- field public static final int Theme_Material_Light_DarkActionBar = 16974401; // 0x1030241
- field public static final int Theme_Material_Light_Dialog = 16974402; // 0x1030242
- field public static final int Theme_Material_Light_DialogWhenLarge = 16974406; // 0x1030246
- field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974407; // 0x1030247
- field public static final int Theme_Material_Light_Dialog_MinWidth = 16974403; // 0x1030243
- field public static final int Theme_Material_Light_Dialog_NoActionBar = 16974404; // 0x1030244
- field public static final int Theme_Material_Light_Dialog_NoActionBar_MinWidth = 16974405; // 0x1030245
- field public static final int Theme_Material_Light_NoActionBar = 16974408; // 0x1030248
- field public static final int Theme_Material_Light_NoActionBar_Fullscreen = 16974409; // 0x1030249
- field public static final int Theme_Material_Light_NoActionBar_Overscan = 16974410; // 0x103024a
- field public static final int Theme_Material_Light_NoActionBar_TranslucentDecor = 16974411; // 0x103024b
- field public static final int Theme_Material_Light_Panel = 16974412; // 0x103024c
- field public static final int Theme_Material_Light_Voice = 16974413; // 0x103024d
- field public static final int Theme_Material_NoActionBar = 16974392; // 0x1030238
- field public static final int Theme_Material_NoActionBar_Fullscreen = 16974393; // 0x1030239
- field public static final int Theme_Material_NoActionBar_Overscan = 16974394; // 0x103023a
- field public static final int Theme_Material_NoActionBar_TranslucentDecor = 16974395; // 0x103023b
- field public static final int Theme_Material_Panel = 16974396; // 0x103023c
- field public static final int Theme_Material_Voice = 16974397; // 0x103023d
- field public static final int Theme_Material_Wallpaper = 16974398; // 0x103023e
- field public static final int Theme_Material_Wallpaper_NoTitleBar = 16974399; // 0x103023f
+ field public static final int Theme_Material = 16974385; // 0x1030231
+ field public static final int Theme_Material_Dialog = 16974386; // 0x1030232
+ field public static final int Theme_Material_DialogWhenLarge = 16974390; // 0x1030236
+ field public static final int Theme_Material_DialogWhenLarge_NoActionBar = 16974391; // 0x1030237
+ field public static final int Theme_Material_Dialog_MinWidth = 16974387; // 0x1030233
+ field public static final int Theme_Material_Dialog_NoActionBar = 16974388; // 0x1030234
+ field public static final int Theme_Material_Dialog_NoActionBar_MinWidth = 16974389; // 0x1030235
+ field public static final int Theme_Material_InputMethod = 16974392; // 0x1030238
+ field public static final int Theme_Material_Light = 16974402; // 0x1030242
+ field public static final int Theme_Material_Light_DarkActionBar = 16974403; // 0x1030243
+ field public static final int Theme_Material_Light_Dialog = 16974404; // 0x1030244
+ field public static final int Theme_Material_Light_DialogWhenLarge = 16974408; // 0x1030248
+ field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974409; // 0x1030249
+ field public static final int Theme_Material_Light_Dialog_MinWidth = 16974405; // 0x1030245
+ field public static final int Theme_Material_Light_Dialog_NoActionBar = 16974406; // 0x1030246
+ field public static final int Theme_Material_Light_Dialog_NoActionBar_MinWidth = 16974407; // 0x1030247
+ field public static final int Theme_Material_Light_NoActionBar = 16974410; // 0x103024a
+ field public static final int Theme_Material_Light_NoActionBar_Fullscreen = 16974411; // 0x103024b
+ field public static final int Theme_Material_Light_NoActionBar_Overscan = 16974412; // 0x103024c
+ field public static final int Theme_Material_Light_NoActionBar_TranslucentDecor = 16974413; // 0x103024d
+ field public static final int Theme_Material_Light_Panel = 16974414; // 0x103024e
+ field public static final int Theme_Material_Light_Voice = 16974415; // 0x103024f
+ field public static final int Theme_Material_NoActionBar = 16974393; // 0x1030239
+ field public static final int Theme_Material_NoActionBar_Fullscreen = 16974394; // 0x103023a
+ field public static final int Theme_Material_NoActionBar_Overscan = 16974395; // 0x103023b
+ field public static final int Theme_Material_NoActionBar_TranslucentDecor = 16974396; // 0x103023c
+ field public static final int Theme_Material_Panel = 16974397; // 0x103023d
+ field public static final int Theme_Material_Settings = 16974398; // 0x103023e
+ field public static final int Theme_Material_Voice = 16974399; // 0x103023f
+ field public static final int Theme_Material_Wallpaper = 16974400; // 0x1030240
+ field public static final int Theme_Material_Wallpaper_NoTitleBar = 16974401; // 0x1030241
field public static final int Theme_NoDisplay = 16973909; // 0x1030055
field public static final int Theme_NoTitleBar = 16973830; // 0x1030006
field public static final int Theme_NoTitleBar_Fullscreen = 16973831; // 0x1030007
@@ -2314,128 +2316,128 @@
field public static final int Widget_ListView_DropDown = 16973872; // 0x1030030
field public static final int Widget_ListView_Menu = 16973873; // 0x1030031
field public static final int Widget_ListView_White = 16973871; // 0x103002f
- field public static final int Widget_Material = 16974420; // 0x1030254
- field public static final int Widget_Material_ActionBar = 16974421; // 0x1030255
- field public static final int Widget_Material_ActionBar_Solid = 16974422; // 0x1030256
- field public static final int Widget_Material_ActionBar_TabBar = 16974423; // 0x1030257
- field public static final int Widget_Material_ActionBar_TabText = 16974424; // 0x1030258
- field public static final int Widget_Material_ActionBar_TabView = 16974425; // 0x1030259
- field public static final int Widget_Material_ActionButton = 16974426; // 0x103025a
- field public static final int Widget_Material_ActionButton_CloseMode = 16974427; // 0x103025b
- field public static final int Widget_Material_ActionButton_Overflow = 16974428; // 0x103025c
- field public static final int Widget_Material_ActionMode = 16974429; // 0x103025d
- field public static final int Widget_Material_AutoCompleteTextView = 16974430; // 0x103025e
- field public static final int Widget_Material_Button = 16974431; // 0x103025f
- field public static final int Widget_Material_ButtonBar = 16974437; // 0x1030265
- field public static final int Widget_Material_ButtonBar_AlertDialog = 16974438; // 0x1030266
- field public static final int Widget_Material_Button_Borderless = 16974432; // 0x1030260
- field public static final int Widget_Material_Button_Borderless_Small = 16974433; // 0x1030261
- field public static final int Widget_Material_Button_Inset = 16974434; // 0x1030262
- field public static final int Widget_Material_Button_Small = 16974435; // 0x1030263
- field public static final int Widget_Material_Button_Toggle = 16974436; // 0x1030264
- field public static final int Widget_Material_CalendarView = 16974439; // 0x1030267
- field public static final int Widget_Material_CheckedTextView = 16974440; // 0x1030268
- field public static final int Widget_Material_CompoundButton_CheckBox = 16974441; // 0x1030269
- field public static final int Widget_Material_CompoundButton_RadioButton = 16974442; // 0x103026a
- field public static final int Widget_Material_CompoundButton_Star = 16974443; // 0x103026b
- field public static final int Widget_Material_DatePicker = 16974444; // 0x103026c
- field public static final int Widget_Material_DropDownItem = 16974445; // 0x103026d
- field public static final int Widget_Material_DropDownItem_Spinner = 16974446; // 0x103026e
- field public static final int Widget_Material_EditText = 16974447; // 0x103026f
- field public static final int Widget_Material_ExpandableListView = 16974448; // 0x1030270
- field public static final int Widget_Material_FastScroll = 16974449; // 0x1030271
- field public static final int Widget_Material_GridView = 16974450; // 0x1030272
- field public static final int Widget_Material_HorizontalScrollView = 16974451; // 0x1030273
- field public static final int Widget_Material_ImageButton = 16974452; // 0x1030274
- field public static final int Widget_Material_Light = 16974481; // 0x1030291
- field public static final int Widget_Material_Light_ActionBar = 16974482; // 0x1030292
- field public static final int Widget_Material_Light_ActionBar_Solid = 16974483; // 0x1030293
- field public static final int Widget_Material_Light_ActionBar_TabBar = 16974484; // 0x1030294
- field public static final int Widget_Material_Light_ActionBar_TabText = 16974485; // 0x1030295
- field public static final int Widget_Material_Light_ActionBar_TabView = 16974486; // 0x1030296
- field public static final int Widget_Material_Light_ActionButton = 16974487; // 0x1030297
- field public static final int Widget_Material_Light_ActionButton_CloseMode = 16974488; // 0x1030298
- field public static final int Widget_Material_Light_ActionButton_Overflow = 16974489; // 0x1030299
- field public static final int Widget_Material_Light_ActionMode = 16974490; // 0x103029a
- field public static final int Widget_Material_Light_AutoCompleteTextView = 16974491; // 0x103029b
- field public static final int Widget_Material_Light_Button = 16974492; // 0x103029c
- field public static final int Widget_Material_Light_ButtonBar = 16974498; // 0x10302a2
- field public static final int Widget_Material_Light_ButtonBar_AlertDialog = 16974499; // 0x10302a3
- field public static final int Widget_Material_Light_Button_Borderless = 16974493; // 0x103029d
- field public static final int Widget_Material_Light_Button_Borderless_Small = 16974494; // 0x103029e
- field public static final int Widget_Material_Light_Button_Inset = 16974495; // 0x103029f
- field public static final int Widget_Material_Light_Button_Small = 16974496; // 0x10302a0
- field public static final int Widget_Material_Light_Button_Toggle = 16974497; // 0x10302a1
- field public static final int Widget_Material_Light_CalendarView = 16974500; // 0x10302a4
- field public static final int Widget_Material_Light_CheckedTextView = 16974501; // 0x10302a5
- field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974502; // 0x10302a6
- field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974503; // 0x10302a7
- field public static final int Widget_Material_Light_CompoundButton_Star = 16974504; // 0x10302a8
- field public static final int Widget_Material_Light_DropDownItem = 16974505; // 0x10302a9
- field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974506; // 0x10302aa
- field public static final int Widget_Material_Light_EditText = 16974507; // 0x10302ab
- field public static final int Widget_Material_Light_ExpandableListView = 16974508; // 0x10302ac
- field public static final int Widget_Material_Light_FastScroll = 16974509; // 0x10302ad
- field public static final int Widget_Material_Light_GridView = 16974510; // 0x10302ae
- field public static final int Widget_Material_Light_HorizontalScrollView = 16974511; // 0x10302af
- field public static final int Widget_Material_Light_ImageButton = 16974512; // 0x10302b0
- field public static final int Widget_Material_Light_ListPopupWindow = 16974513; // 0x10302b1
- field public static final int Widget_Material_Light_ListView = 16974514; // 0x10302b2
- field public static final int Widget_Material_Light_ListView_DropDown = 16974515; // 0x10302b3
- field public static final int Widget_Material_Light_MediaRouteButton = 16974516; // 0x10302b4
- field public static final int Widget_Material_Light_PopupMenu = 16974517; // 0x10302b5
- field public static final int Widget_Material_Light_PopupMenu_Overflow = 16974518; // 0x10302b6
- field public static final int Widget_Material_Light_PopupWindow = 16974519; // 0x10302b7
- field public static final int Widget_Material_Light_ProgressBar = 16974520; // 0x10302b8
- field public static final int Widget_Material_Light_ProgressBar_Horizontal = 16974521; // 0x10302b9
- field public static final int Widget_Material_Light_ProgressBar_Inverse = 16974522; // 0x10302ba
- field public static final int Widget_Material_Light_ProgressBar_Large = 16974523; // 0x10302bb
- field public static final int Widget_Material_Light_ProgressBar_Large_Inverse = 16974524; // 0x10302bc
- field public static final int Widget_Material_Light_ProgressBar_Small = 16974525; // 0x10302bd
- field public static final int Widget_Material_Light_ProgressBar_Small_Inverse = 16974526; // 0x10302be
- field public static final int Widget_Material_Light_ProgressBar_Small_Title = 16974527; // 0x10302bf
- field public static final int Widget_Material_Light_RatingBar = 16974528; // 0x10302c0
- field public static final int Widget_Material_Light_RatingBar_Indicator = 16974529; // 0x10302c1
- field public static final int Widget_Material_Light_RatingBar_Small = 16974530; // 0x10302c2
- field public static final int Widget_Material_Light_ScrollView = 16974531; // 0x10302c3
- field public static final int Widget_Material_Light_SeekBar = 16974532; // 0x10302c4
- field public static final int Widget_Material_Light_SegmentedButton = 16974533; // 0x10302c5
- field public static final int Widget_Material_Light_Spinner = 16974535; // 0x10302c7
- field public static final int Widget_Material_Light_StackView = 16974534; // 0x10302c6
- field public static final int Widget_Material_Light_Tab = 16974536; // 0x10302c8
- field public static final int Widget_Material_Light_TabWidget = 16974537; // 0x10302c9
- field public static final int Widget_Material_Light_TextView = 16974538; // 0x10302ca
- field public static final int Widget_Material_Light_TextView_SpinnerItem = 16974539; // 0x10302cb
- field public static final int Widget_Material_Light_WebTextView = 16974540; // 0x10302cc
- field public static final int Widget_Material_Light_WebView = 16974541; // 0x10302cd
- field public static final int Widget_Material_ListPopupWindow = 16974453; // 0x1030275
- field public static final int Widget_Material_ListView = 16974454; // 0x1030276
- field public static final int Widget_Material_ListView_DropDown = 16974455; // 0x1030277
- field public static final int Widget_Material_MediaRouteButton = 16974456; // 0x1030278
- field public static final int Widget_Material_PopupMenu = 16974457; // 0x1030279
- field public static final int Widget_Material_PopupMenu_Overflow = 16974458; // 0x103027a
- field public static final int Widget_Material_PopupWindow = 16974459; // 0x103027b
- field public static final int Widget_Material_ProgressBar = 16974460; // 0x103027c
- field public static final int Widget_Material_ProgressBar_Horizontal = 16974461; // 0x103027d
- field public static final int Widget_Material_ProgressBar_Large = 16974462; // 0x103027e
- field public static final int Widget_Material_ProgressBar_Small = 16974463; // 0x103027f
- field public static final int Widget_Material_ProgressBar_Small_Title = 16974464; // 0x1030280
- field public static final int Widget_Material_RatingBar = 16974465; // 0x1030281
- field public static final int Widget_Material_RatingBar_Indicator = 16974466; // 0x1030282
- field public static final int Widget_Material_RatingBar_Small = 16974467; // 0x1030283
- field public static final int Widget_Material_ScrollView = 16974468; // 0x1030284
- field public static final int Widget_Material_SeekBar = 16974469; // 0x1030285
- field public static final int Widget_Material_SegmentedButton = 16974470; // 0x1030286
- field public static final int Widget_Material_Spinner = 16974472; // 0x1030288
- field public static final int Widget_Material_StackView = 16974471; // 0x1030287
- field public static final int Widget_Material_Tab = 16974473; // 0x1030289
- field public static final int Widget_Material_TabWidget = 16974474; // 0x103028a
- field public static final int Widget_Material_TextView = 16974475; // 0x103028b
- field public static final int Widget_Material_TextView_SpinnerItem = 16974476; // 0x103028c
- field public static final int Widget_Material_Toolbar = 16974477; // 0x103028d
- field public static final int Widget_Material_Toolbar_Button_Navigation = 16974478; // 0x103028e
- field public static final int Widget_Material_WebTextView = 16974479; // 0x103028f
- field public static final int Widget_Material_WebView = 16974480; // 0x1030290
+ field public static final int Widget_Material = 16974422; // 0x1030256
+ field public static final int Widget_Material_ActionBar = 16974423; // 0x1030257
+ field public static final int Widget_Material_ActionBar_Solid = 16974424; // 0x1030258
+ field public static final int Widget_Material_ActionBar_TabBar = 16974425; // 0x1030259
+ field public static final int Widget_Material_ActionBar_TabText = 16974426; // 0x103025a
+ field public static final int Widget_Material_ActionBar_TabView = 16974427; // 0x103025b
+ field public static final int Widget_Material_ActionButton = 16974428; // 0x103025c
+ field public static final int Widget_Material_ActionButton_CloseMode = 16974429; // 0x103025d
+ field public static final int Widget_Material_ActionButton_Overflow = 16974430; // 0x103025e
+ field public static final int Widget_Material_ActionMode = 16974431; // 0x103025f
+ field public static final int Widget_Material_AutoCompleteTextView = 16974432; // 0x1030260
+ field public static final int Widget_Material_Button = 16974433; // 0x1030261
+ field public static final int Widget_Material_ButtonBar = 16974439; // 0x1030267
+ field public static final int Widget_Material_ButtonBar_AlertDialog = 16974440; // 0x1030268
+ field public static final int Widget_Material_Button_Borderless = 16974434; // 0x1030262
+ field public static final int Widget_Material_Button_Borderless_Small = 16974435; // 0x1030263
+ field public static final int Widget_Material_Button_Inset = 16974436; // 0x1030264
+ field public static final int Widget_Material_Button_Small = 16974437; // 0x1030265
+ field public static final int Widget_Material_Button_Toggle = 16974438; // 0x1030266
+ field public static final int Widget_Material_CalendarView = 16974441; // 0x1030269
+ field public static final int Widget_Material_CheckedTextView = 16974442; // 0x103026a
+ field public static final int Widget_Material_CompoundButton_CheckBox = 16974443; // 0x103026b
+ field public static final int Widget_Material_CompoundButton_RadioButton = 16974444; // 0x103026c
+ field public static final int Widget_Material_CompoundButton_Star = 16974445; // 0x103026d
+ field public static final int Widget_Material_DatePicker = 16974446; // 0x103026e
+ field public static final int Widget_Material_DropDownItem = 16974447; // 0x103026f
+ field public static final int Widget_Material_DropDownItem_Spinner = 16974448; // 0x1030270
+ field public static final int Widget_Material_EditText = 16974449; // 0x1030271
+ field public static final int Widget_Material_ExpandableListView = 16974450; // 0x1030272
+ field public static final int Widget_Material_FastScroll = 16974451; // 0x1030273
+ field public static final int Widget_Material_GridView = 16974452; // 0x1030274
+ field public static final int Widget_Material_HorizontalScrollView = 16974453; // 0x1030275
+ field public static final int Widget_Material_ImageButton = 16974454; // 0x1030276
+ field public static final int Widget_Material_Light = 16974483; // 0x1030293
+ field public static final int Widget_Material_Light_ActionBar = 16974484; // 0x1030294
+ field public static final int Widget_Material_Light_ActionBar_Solid = 16974485; // 0x1030295
+ field public static final int Widget_Material_Light_ActionBar_TabBar = 16974486; // 0x1030296
+ field public static final int Widget_Material_Light_ActionBar_TabText = 16974487; // 0x1030297
+ field public static final int Widget_Material_Light_ActionBar_TabView = 16974488; // 0x1030298
+ field public static final int Widget_Material_Light_ActionButton = 16974489; // 0x1030299
+ field public static final int Widget_Material_Light_ActionButton_CloseMode = 16974490; // 0x103029a
+ field public static final int Widget_Material_Light_ActionButton_Overflow = 16974491; // 0x103029b
+ field public static final int Widget_Material_Light_ActionMode = 16974492; // 0x103029c
+ field public static final int Widget_Material_Light_AutoCompleteTextView = 16974493; // 0x103029d
+ field public static final int Widget_Material_Light_Button = 16974494; // 0x103029e
+ field public static final int Widget_Material_Light_ButtonBar = 16974500; // 0x10302a4
+ field public static final int Widget_Material_Light_ButtonBar_AlertDialog = 16974501; // 0x10302a5
+ field public static final int Widget_Material_Light_Button_Borderless = 16974495; // 0x103029f
+ field public static final int Widget_Material_Light_Button_Borderless_Small = 16974496; // 0x10302a0
+ field public static final int Widget_Material_Light_Button_Inset = 16974497; // 0x10302a1
+ field public static final int Widget_Material_Light_Button_Small = 16974498; // 0x10302a2
+ field public static final int Widget_Material_Light_Button_Toggle = 16974499; // 0x10302a3
+ field public static final int Widget_Material_Light_CalendarView = 16974502; // 0x10302a6
+ field public static final int Widget_Material_Light_CheckedTextView = 16974503; // 0x10302a7
+ field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974504; // 0x10302a8
+ field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974505; // 0x10302a9
+ field public static final int Widget_Material_Light_CompoundButton_Star = 16974506; // 0x10302aa
+ field public static final int Widget_Material_Light_DropDownItem = 16974507; // 0x10302ab
+ field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974508; // 0x10302ac
+ field public static final int Widget_Material_Light_EditText = 16974509; // 0x10302ad
+ field public static final int Widget_Material_Light_ExpandableListView = 16974510; // 0x10302ae
+ field public static final int Widget_Material_Light_FastScroll = 16974511; // 0x10302af
+ field public static final int Widget_Material_Light_GridView = 16974512; // 0x10302b0
+ field public static final int Widget_Material_Light_HorizontalScrollView = 16974513; // 0x10302b1
+ field public static final int Widget_Material_Light_ImageButton = 16974514; // 0x10302b2
+ field public static final int Widget_Material_Light_ListPopupWindow = 16974515; // 0x10302b3
+ field public static final int Widget_Material_Light_ListView = 16974516; // 0x10302b4
+ field public static final int Widget_Material_Light_ListView_DropDown = 16974517; // 0x10302b5
+ field public static final int Widget_Material_Light_MediaRouteButton = 16974518; // 0x10302b6
+ field public static final int Widget_Material_Light_PopupMenu = 16974519; // 0x10302b7
+ field public static final int Widget_Material_Light_PopupMenu_Overflow = 16974520; // 0x10302b8
+ field public static final int Widget_Material_Light_PopupWindow = 16974521; // 0x10302b9
+ field public static final int Widget_Material_Light_ProgressBar = 16974522; // 0x10302ba
+ field public static final int Widget_Material_Light_ProgressBar_Horizontal = 16974523; // 0x10302bb
+ field public static final int Widget_Material_Light_ProgressBar_Inverse = 16974524; // 0x10302bc
+ field public static final int Widget_Material_Light_ProgressBar_Large = 16974525; // 0x10302bd
+ field public static final int Widget_Material_Light_ProgressBar_Large_Inverse = 16974526; // 0x10302be
+ field public static final int Widget_Material_Light_ProgressBar_Small = 16974527; // 0x10302bf
+ field public static final int Widget_Material_Light_ProgressBar_Small_Inverse = 16974528; // 0x10302c0
+ field public static final int Widget_Material_Light_ProgressBar_Small_Title = 16974529; // 0x10302c1
+ field public static final int Widget_Material_Light_RatingBar = 16974530; // 0x10302c2
+ field public static final int Widget_Material_Light_RatingBar_Indicator = 16974531; // 0x10302c3
+ field public static final int Widget_Material_Light_RatingBar_Small = 16974532; // 0x10302c4
+ field public static final int Widget_Material_Light_ScrollView = 16974533; // 0x10302c5
+ field public static final int Widget_Material_Light_SeekBar = 16974534; // 0x10302c6
+ field public static final int Widget_Material_Light_SegmentedButton = 16974535; // 0x10302c7
+ field public static final int Widget_Material_Light_Spinner = 16974537; // 0x10302c9
+ field public static final int Widget_Material_Light_StackView = 16974536; // 0x10302c8
+ field public static final int Widget_Material_Light_Tab = 16974538; // 0x10302ca
+ field public static final int Widget_Material_Light_TabWidget = 16974539; // 0x10302cb
+ field public static final int Widget_Material_Light_TextView = 16974540; // 0x10302cc
+ field public static final int Widget_Material_Light_TextView_SpinnerItem = 16974541; // 0x10302cd
+ field public static final int Widget_Material_Light_WebTextView = 16974542; // 0x10302ce
+ field public static final int Widget_Material_Light_WebView = 16974543; // 0x10302cf
+ field public static final int Widget_Material_ListPopupWindow = 16974455; // 0x1030277
+ field public static final int Widget_Material_ListView = 16974456; // 0x1030278
+ field public static final int Widget_Material_ListView_DropDown = 16974457; // 0x1030279
+ field public static final int Widget_Material_MediaRouteButton = 16974458; // 0x103027a
+ field public static final int Widget_Material_PopupMenu = 16974459; // 0x103027b
+ field public static final int Widget_Material_PopupMenu_Overflow = 16974460; // 0x103027c
+ field public static final int Widget_Material_PopupWindow = 16974461; // 0x103027d
+ field public static final int Widget_Material_ProgressBar = 16974462; // 0x103027e
+ field public static final int Widget_Material_ProgressBar_Horizontal = 16974463; // 0x103027f
+ field public static final int Widget_Material_ProgressBar_Large = 16974464; // 0x1030280
+ field public static final int Widget_Material_ProgressBar_Small = 16974465; // 0x1030281
+ field public static final int Widget_Material_ProgressBar_Small_Title = 16974466; // 0x1030282
+ field public static final int Widget_Material_RatingBar = 16974467; // 0x1030283
+ field public static final int Widget_Material_RatingBar_Indicator = 16974468; // 0x1030284
+ field public static final int Widget_Material_RatingBar_Small = 16974469; // 0x1030285
+ field public static final int Widget_Material_ScrollView = 16974470; // 0x1030286
+ field public static final int Widget_Material_SeekBar = 16974471; // 0x1030287
+ field public static final int Widget_Material_SegmentedButton = 16974472; // 0x1030288
+ field public static final int Widget_Material_Spinner = 16974474; // 0x103028a
+ field public static final int Widget_Material_StackView = 16974473; // 0x1030289
+ field public static final int Widget_Material_Tab = 16974475; // 0x103028b
+ field public static final int Widget_Material_TabWidget = 16974476; // 0x103028c
+ field public static final int Widget_Material_TextView = 16974477; // 0x103028d
+ field public static final int Widget_Material_TextView_SpinnerItem = 16974478; // 0x103028e
+ field public static final int Widget_Material_Toolbar = 16974479; // 0x103028f
+ field public static final int Widget_Material_Toolbar_Button_Navigation = 16974480; // 0x1030290
+ field public static final int Widget_Material_WebTextView = 16974481; // 0x1030291
+ field public static final int Widget_Material_WebView = 16974482; // 0x1030292
field public static final int Widget_PopupMenu = 16973958; // 0x1030086
field public static final int Widget_PopupWindow = 16973878; // 0x1030036
field public static final int Widget_ProgressBar = 16973852; // 0x103001c
@@ -3335,6 +3337,7 @@
method public void openContextMenu(android.view.View);
method public void openOptionsMenu();
method public void overridePendingTransition(int, int);
+ method public void postponeEnterTransition();
method public void recreate();
method public void registerForContextMenu(android.view.View);
method public final deprecated void removeDialog(int);
@@ -3390,6 +3393,7 @@
method public deprecated void startManagingCursor(android.database.Cursor);
method public boolean startNextMatchingActivity(android.content.Intent);
method public boolean startNextMatchingActivity(android.content.Intent, android.os.Bundle);
+ method public void startPostponedEnterTransition();
method public void startSearch(java.lang.String, boolean, android.os.Bundle, boolean);
method public void stopLockTask();
method public deprecated void stopManagingCursor(android.database.Cursor);
@@ -16015,46 +16019,34 @@
field public int serverAddress;
}
- public class LinkAddress implements android.os.Parcelable {
+ public final class IpPrefix implements android.os.Parcelable {
method public int describeContents();
method public java.net.InetAddress getAddress();
- method public int getFlags();
- method public int getNetworkPrefixLength();
- method public int getScope();
- method public boolean isSameAddressAs(android.net.LinkAddress);
- method public void writeToParcel(android.os.Parcel, int);
- }
-
- public class LinkProperties implements android.os.Parcelable {
- ctor public LinkProperties();
- ctor public LinkProperties(android.net.LinkProperties);
- method public void addDns(java.net.InetAddress);
- method public boolean addLinkAddress(android.net.LinkAddress);
- method public void addRoute(android.net.RouteInfo);
- method public void clear();
- method public int describeContents();
- method public java.util.Collection<java.lang.String> getAllInterfaceNames();
- method public java.util.Collection<java.net.InetAddress> getDnses();
- method public java.lang.String getDomains();
- method public android.net.ProxyInfo getHttpProxy();
- method public java.lang.String getInterfaceName();
- method public java.util.Collection<android.net.LinkAddress> getLinkAddresses();
- method public java.util.Collection<android.net.RouteInfo> getRoutes();
- method public boolean hasIPv4Address();
- method public boolean hasIPv6Address();
- method public boolean removeLinkAddress(android.net.LinkAddress);
- method public void setDomains(java.lang.String);
- method public void setHttpProxy(android.net.ProxyInfo);
- method public void setInterfaceName(java.lang.String);
- method public void setLinkAddresses(java.util.Collection<android.net.LinkAddress>);
+ method public int getPrefixLength();
+ method public byte[] getRawAddress();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
}
- public static class LinkProperties.CompareResult {
- ctor public LinkProperties.CompareResult();
- field public java.util.Collection added;
- field public java.util.Collection removed;
+ public class LinkAddress implements android.os.Parcelable {
+ method public int describeContents();
+ method public java.net.InetAddress getAddress();
+ method public int getFlags();
+ method public int getPrefixLength();
+ method public int getScope();
+ method public void writeToParcel(android.os.Parcel, int);
+ }
+
+ public final class LinkProperties implements android.os.Parcelable {
+ method public int describeContents();
+ method public java.util.List<java.net.InetAddress> getDnsServers();
+ method public java.lang.String getDomains();
+ method public android.net.ProxyInfo getHttpProxy();
+ method public java.lang.String getInterfaceName();
+ method public java.util.List<android.net.LinkAddress> getLinkAddresses();
+ method public java.util.List<android.net.RouteInfo> getRoutes();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
}
public class LocalServerSocket {
@@ -16135,21 +16127,12 @@
}
public final class NetworkCapabilities implements android.os.Parcelable {
- ctor public NetworkCapabilities();
ctor public NetworkCapabilities(android.net.NetworkCapabilities);
- method public void addNetworkCapability(int);
- method public void addTransportType(int);
method public int describeContents();
method public int getLinkDownstreamBandwidthKbps();
method public int getLinkUpstreamBandwidthKbps();
- method public java.util.Collection<java.lang.Integer> getNetworkCapabilities();
- method public java.util.Collection<java.lang.Integer> getTransportTypes();
method public boolean hasCapability(int);
method public boolean hasTransport(int);
- method public void removeNetworkCapability(int);
- method public void removeTransportType(int);
- method public void setLinkDownstreamBandwidthKbps(int);
- method public void setLinkUpstreamBandwidthKbps(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int NET_CAPABILITY_CBS = 5; // 0x5
@@ -16223,7 +16206,15 @@
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
- field public final android.net.NetworkCapabilities networkCapabilities;
+ }
+
+ public static class NetworkRequest.Builder {
+ ctor public NetworkRequest.Builder();
+ method public android.net.NetworkRequest.Builder addCapability(int);
+ method public android.net.NetworkRequest.Builder addTransportType(int);
+ method public android.net.NetworkRequest build();
+ method public android.net.NetworkRequest.Builder removeCapability(int);
+ method public android.net.NetworkRequest.Builder removeTransportType(int);
}
public class ParseException extends java.lang.RuntimeException {
@@ -16252,18 +16243,15 @@
method public void writeToParcel(android.os.Parcel, int);
}
- public class RouteInfo implements android.os.Parcelable {
- ctor public RouteInfo(android.net.LinkAddress, java.net.InetAddress, java.lang.String);
- ctor public RouteInfo(android.net.LinkAddress, java.net.InetAddress);
- ctor public RouteInfo(java.net.InetAddress);
- ctor public RouteInfo(android.net.LinkAddress);
+ public final class RouteInfo implements android.os.Parcelable {
method public int describeContents();
- method public android.net.LinkAddress getDestination();
+ method public android.net.IpPrefix getDestination();
method public java.net.InetAddress getGateway();
method public java.lang.String getInterface();
method public boolean isDefaultRoute();
method public boolean matches(java.net.InetAddress);
method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
}
public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
@@ -25827,21 +25815,28 @@
method public final void cancelNotification(java.lang.String);
method public final void cancelNotifications(java.lang.String[]);
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
- method public android.service.notification.NotificationListenerService.Ranking getCurrentRanking();
+ method public android.service.notification.NotificationListenerService.RankingMap getCurrentRanking();
method public android.os.IBinder onBind(android.content.Intent);
method public void onListenerConnected();
- method public abstract void onNotificationPosted(android.service.notification.StatusBarNotification);
- method public void onNotificationRankingUpdate();
- method public abstract void onNotificationRemoved(android.service.notification.StatusBarNotification);
+ method public void onNotificationPosted(android.service.notification.StatusBarNotification);
+ method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
+ method public void onNotificationRankingUpdate(android.service.notification.NotificationListenerService.RankingMap);
+ method public void onNotificationRemoved(android.service.notification.StatusBarNotification);
+ method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
}
- public static class NotificationListenerService.Ranking implements android.os.Parcelable {
+ public static class NotificationListenerService.Ranking {
+ method public java.lang.String getKey();
+ method public int getRank();
+ method public boolean isAmbient();
+ method public boolean isInterceptedByDoNotDisturb();
+ }
+
+ public static class NotificationListenerService.RankingMap implements android.os.Parcelable {
method public int describeContents();
method public java.lang.String[] getOrderedKeys();
- method public int getRank(java.lang.String);
- method public boolean isAmbient(java.lang.String);
- method public boolean isInterceptedByDoNotDisturb(java.lang.String);
+ method public android.service.notification.NotificationListenerService.Ranking getRanking(java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
}
@@ -33903,15 +33898,15 @@
field public static final android.os.Parcelable.Creator CREATOR;
}
- public static final class CursorAnchorInfo.CursorAnchorInfoBuilder {
- ctor public CursorAnchorInfo.CursorAnchorInfoBuilder();
- method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder addCharacterRect(int, float, float, float, float);
+ public static final class CursorAnchorInfo.Builder {
+ ctor public CursorAnchorInfo.Builder();
+ method public android.view.inputmethod.CursorAnchorInfo.Builder addCharacterRect(int, float, float, float, float);
method public android.view.inputmethod.CursorAnchorInfo build();
method public void reset();
- method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setComposingText(int, java.lang.CharSequence);
- method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setInsertionMarkerLocation(float, float, float, float);
- method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setMatrix(android.graphics.Matrix);
- method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setSelectionRange(int, int);
+ method public android.view.inputmethod.CursorAnchorInfo.Builder setComposingText(int, java.lang.CharSequence);
+ method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float);
+ method public android.view.inputmethod.CursorAnchorInfo.Builder setMatrix(android.graphics.Matrix);
+ method public android.view.inputmethod.CursorAnchorInfo.Builder setSelectionRange(int, int);
}
public class EditorInfo implements android.text.InputType android.os.Parcelable {
diff --git a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
index dce0a75..e6847a9 100644
--- a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
+++ b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
@@ -20,6 +20,7 @@
import android.app.IActivityManager;
import android.app.IActivityManager.ContentProviderHolder;
import android.content.IContentProvider;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -33,7 +34,8 @@
enum CommandVerb {
UNSPECIFIED,
GET,
- PUT
+ PUT,
+ DELETE
}
static String[] mArgs;
@@ -74,6 +76,8 @@
mVerb = CommandVerb.GET;
} else if ("put".equalsIgnoreCase(arg)) {
mVerb = CommandVerb.PUT;
+ } else if ("delete".equalsIgnoreCase(arg)) {
+ mVerb = CommandVerb.DELETE;
} else {
// invalid
System.err.println("Invalid command: " + arg);
@@ -87,7 +91,7 @@
break; // invalid
}
mTable = arg.toLowerCase();
- } else if (mVerb == CommandVerb.GET) {
+ } else if (mVerb == CommandVerb.GET || mVerb == CommandVerb.DELETE) {
mKey = arg;
if (mNextArg >= mArgs.length) {
valid = true;
@@ -136,6 +140,10 @@
case PUT:
putForUser(provider, mUser, mTable, mKey, mValue);
break;
+ case DELETE:
+ System.out.println("Deleted "
+ + deleteForUser(provider, mUser, mTable, mKey) + " rows");
+ break;
default:
System.err.println("Unspecified command");
break;
@@ -211,9 +219,31 @@
}
}
+ int deleteForUser(IContentProvider provider, int userHandle,
+ final String table, final String key) {
+ Uri targetUri;
+ if ("system".equals(table)) targetUri = Settings.System.getUriFor(key);
+ else if ("secure".equals(table)) targetUri = Settings.Secure.getUriFor(key);
+ else if ("global".equals(table)) targetUri = Settings.Global.getUriFor(key);
+ else {
+ System.err.println("Invalid table; no delete performed");
+ throw new IllegalArgumentException("Invalid table " + table);
+ }
+
+ int num = 0;
+ try {
+ num = provider.delete(null, targetUri, null, null);
+ } catch (RemoteException e) {
+ System.err.println("Can't clear key " + key + " in " + table + " for user "
+ + userHandle);
+ }
+ return num;
+ }
+
private static void printUsage() {
System.err.println("usage: settings [--user NUM] get namespace key");
System.err.println(" settings [--user NUM] put namespace key value");
+ System.err.println(" settings [--user NUM] delete namespace key");
System.err.println("\n'namespace' is one of {system, secure, global}, case-insensitive");
System.err.println("If '--user NUM' is not given, the operations are performed on the owner user.");
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 946555f..f6883e2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5616,6 +5616,34 @@
mExitTransitionListener = listener;
}
+ /**
+ * Postpone the entering activity transition when Activity was started with
+ * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
+ * android.util.Pair[])}.
+ * <p>This method gives the Activity the ability to delay starting the entering and
+ * shared element transitions until all data is loaded. Until then, the Activity won't
+ * draw into its window, leaving the window transparent. This may also cause the
+ * returning animation to be delayed until data is ready. This method should be
+ * called in {@link #onCreate(android.os.Bundle)} or in
+ * {@link #onActivityReenter(int, android.content.Intent)}.
+ * {@link #startPostponedEnterTransition()} must be called to allow the Activity to
+ * start the transitions. If the Activity did not use
+ * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
+ * android.util.Pair[])}, then this method does nothing.</p>
+ */
+ public void postponeEnterTransition() {
+ mActivityTransitionState.postponeEnterTransition();
+ }
+
+ /**
+ * Begin postponed transitions after {@link #postponeEnterTransition()} was called.
+ * If postponeEnterTransition() was called, you must call startPostponedEnterTransition()
+ * to have your Activity start drawing.
+ */
+ public void startPostponedEnterTransition() {
+ mActivityTransitionState.startPostponedEnterTransition();
+ }
+
// ------------------ Internal API ------------------
final void setParent(Activity parent) {
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index b658597..703df51 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -214,11 +214,21 @@
ArrayList<String> allSharedElementNames,
ArrayList<String> accepted, ArrayList<String> localNames,
SharedElementListener listener, boolean isReturning) {
+ this(window, allSharedElementNames, listener, isReturning);
+ viewsReady(accepted, localNames);
+ }
+
+ public ActivityTransitionCoordinator(Window window,
+ ArrayList<String> allSharedElementNames,
+ SharedElementListener listener, boolean isReturning) {
super(new Handler());
mWindow = window;
mListener = listener;
mAllSharedElementNames = allSharedElementNames;
mIsReturning = isReturning;
+ }
+
+ protected void viewsReady(ArrayList<String> accepted, ArrayList<String> localNames) {
setSharedElements(accepted, localNames);
if (getViewsTransition() != null) {
getDecor().captureTransitioningViews(mTransitioningViews);
@@ -274,6 +284,8 @@
return names;
}
+ public ArrayList<String> getAllSharedElementNames() { return mAllSharedElementNames; }
+
public static void setViewVisibility(Collection<View> views, int visibility) {
if (views != null) {
for (View view : views) {
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index b32e9ad..d94dadda 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -87,6 +87,11 @@
*/
private boolean mHasExited;
+ /**
+ * Postpone painting and starting the enter transition until this is false.
+ */
+ private boolean mIsEnterPostponed;
+
public ActivityTransitionState() {
}
@@ -140,15 +145,38 @@
if (mEnterActivityOptions.isReturning()) {
restoreExitedViews();
activity.getWindow().getDecorView().setVisibility(View.VISIBLE);
- mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
- resultReceiver, sharedElementNames, mExitingFrom, mExitingTo);
+ }
+ mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
+ resultReceiver, sharedElementNames, mEnterActivityOptions.isReturning());
+
+ if (!mIsEnterPostponed) {
+ startEnter();
+ }
+ }
+
+ public void postponeEnterTransition() {
+ mIsEnterPostponed = true;
+ }
+
+ public void startPostponedEnterTransition() {
+ if (mIsEnterPostponed) {
+ mIsEnterPostponed = false;
+ if (mEnterTransitionCoordinator != null) {
+ startEnter();
+ }
+ }
+ }
+
+ private void startEnter() {
+ if (mEnterActivityOptions.isReturning()) {
+ mEnterTransitionCoordinator.viewsReady(mExitingFrom, mExitingTo);
} else {
- mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
- resultReceiver, sharedElementNames, null, null);
- mEnteringNames = sharedElementNames;
+ mEnterTransitionCoordinator.viewsReady(null, null);
+ mEnteringNames = mEnterTransitionCoordinator.getAllSharedElementNames();
mEnteringFrom = mEnterTransitionCoordinator.getAcceptedNames();
mEnteringTo = mEnterTransitionCoordinator.getMappedNames();
}
+
mExitingFrom = null;
mExitingTo = null;
mEnterActivityOptions = null;
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 4b052e7..779e3de 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -53,18 +53,37 @@
private boolean mIsCanceled;
private ObjectAnimator mBackgroundAnimator;
private boolean mIsExitTransitionComplete;
+ private boolean mIsReadyForTransition;
+ private Bundle mSharedElementsBundle;
public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
- ArrayList<String> sharedElementNames,
- ArrayList<String> acceptedNames, ArrayList<String> mappedNames) {
- super(activity.getWindow(), sharedElementNames, acceptedNames, mappedNames,
- getListener(activity, acceptedNames), acceptedNames != null);
+ ArrayList<String> sharedElementNames, boolean isReturning) {
+ super(activity.getWindow(), sharedElementNames,
+ getListener(activity, isReturning), isReturning);
mActivity = activity;
setResultReceiver(resultReceiver);
prepareEnter();
Bundle resultReceiverBundle = new Bundle();
resultReceiverBundle.putParcelable(KEY_REMOTE_RECEIVER, this);
mResultReceiver.send(MSG_SET_REMOTE_RECEIVER, resultReceiverBundle);
+ getDecor().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ if (mIsReadyForTransition) {
+ getDecor().getViewTreeObserver().removeOnPreDrawListener(this);
+ }
+ return mIsReadyForTransition;
+ }
+ });
+ }
+
+ public void viewsReady(ArrayList<String> accepted, ArrayList<String> localNames) {
+ if (mIsReadyForTransition) {
+ return;
+ }
+ super.viewsReady(accepted, localNames);
+
+ mIsReadyForTransition = true;
if (mIsReturning) {
mHandler = new Handler() {
@Override
@@ -75,6 +94,13 @@
mHandler.sendEmptyMessageDelayed(MSG_CANCEL, MAX_WAIT_MS);
send(MSG_SEND_SHARED_ELEMENT_DESTINATION, null);
}
+ setViewVisibility(mSharedElements, View.INVISIBLE);
+ if (getViewsTransition() != null) {
+ setViewVisibility(mTransitioningViews, View.INVISIBLE);
+ }
+ if (mSharedElementsBundle != null) {
+ onTakeSharedElements();
+ }
}
private void sendSharedElementDestination() {
@@ -94,9 +120,7 @@
}
}
- private static SharedElementListener getListener(Activity activity,
- ArrayList<String> acceptedNames) {
- boolean isReturning = acceptedNames != null;
+ private static SharedElementListener getListener(Activity activity, boolean isReturning) {
return isReturning ? activity.mExitTransitionListener : activity.mEnterTransitionListener;
}
@@ -108,7 +132,8 @@
if (mHandler != null) {
mHandler.removeMessages(MSG_CANCEL);
}
- onTakeSharedElements(resultData);
+ mSharedElementsBundle = resultData;
+ onTakeSharedElements();
}
break;
case MSG_EXIT_TRANSITION_COMPLETE:
@@ -139,7 +164,7 @@
mSharedElementNames.clear();
mSharedElements.clear();
mAllSharedElementNames.clear();
- onTakeSharedElements(null);
+ startSharedElementTransition(null);
onRemoteExitTransitionComplete();
}
}
@@ -149,10 +174,6 @@
}
protected void prepareEnter() {
- setViewVisibility(mSharedElements, View.INVISIBLE);
- if (getViewsTransition() != null) {
- setViewVisibility(mTransitioningViews, View.INVISIBLE);
- }
mActivity.overridePendingTransition(0, 0);
if (!mIsReturning) {
mActivity.convertToTranslucent(null, null);
@@ -185,7 +206,25 @@
}
}
- protected void onTakeSharedElements(Bundle sharedElementState) {
+ protected void onTakeSharedElements() {
+ if (!mIsReadyForTransition || mSharedElementsBundle == null) {
+ return;
+ }
+ final Bundle sharedElementState = mSharedElementsBundle;
+ mSharedElementsBundle = null;
+ getDecor().getViewTreeObserver()
+ .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ getDecor().getViewTreeObserver().removeOnPreDrawListener(this);
+ startSharedElementTransition(sharedElementState);
+ return false;
+ }
+ });
+ getDecor().invalidate();
+ }
+
+ private void startSharedElementTransition(Bundle sharedElementState) {
setEpicenter();
// Remove rejected shared elements
ArrayList<String> rejectedNames = new ArrayList<String>(mAllSharedElementNames);
@@ -299,8 +338,8 @@
}
public void stop() {
+ makeOpaque();
mHasStopped = true;
- mActivity = null;
mIsCanceled = true;
mResultReceiver = null;
if (mBackgroundAnimator != null) {
@@ -310,7 +349,7 @@
}
private void makeOpaque() {
- if (!mHasStopped) {
+ if (!mHasStopped && mActivity != null) {
mActivity.convertFromTranslucent();
mActivity = null;
}
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
index 85e970c..0d947217 100644
--- a/core/java/android/app/VoiceInteractor.java
+++ b/core/java/android/app/VoiceInteractor.java
@@ -293,7 +293,7 @@
IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
IVoiceInteractorCallback callback) throws RemoteException {
- return interactor.startConfirmation(packageName, callback, mCommand, mArgs);
+ return interactor.startCommand(packageName, callback, mCommand, mArgs);
}
}
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index ff56720..9eea545 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -30,7 +30,7 @@
*
* <p>These properties are fixed for a given CameraDevice, and can be queried
* through the {@link CameraManager CameraManager}
- * interface in addition to through the CameraDevice interface.</p>
+ * interface with {@link CameraManager#getCameraCharacteristics}.</p>
*
* <p>{@link CameraCharacteristics} objects are immutable.</p>
*
@@ -555,7 +555,7 @@
* <p>List containing a subset of the optical image
* stabilization (OIS) modes specified in
* {@link CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE android.lens.opticalStabilizationMode}.</p>
- * <p>If OIS is not implemented for a given camera device, this should
+ * <p>If OIS is not implemented for a given camera device, this will
* contain only OFF.</p>
*
* @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
@@ -612,7 +612,7 @@
/**
* <p>Direction the camera faces relative to
- * device screen</p>
+ * device screen.</p>
* @see #LENS_FACING_FRONT
* @see #LENS_FACING_BACK
*/
@@ -622,7 +622,7 @@
/**
* <p>The set of noise reduction modes supported by this camera device.</p>
* <p>This tag lists the valid modes for {@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode}.</p>
- * <p>Full-capability camera devices must laways support OFF and FAST.</p>
+ * <p>Full-capability camera devices must always support OFF and FAST.</p>
*
* @see CaptureRequest#NOISE_REDUCTION_MODE
*/
@@ -778,18 +778,20 @@
new Key<Byte>("android.request.pipelineMaxDepth", byte.class);
/**
- * <p>Optional. Defaults to 1. Defines how many sub-components
+ * <p>Defines how many sub-components
* a result will be composed of.</p>
* <p>In order to combat the pipeline latency, partial results
* may be delivered to the application layer from the camera device as
* soon as they are available.</p>
- * <p>A value of 1 means that partial results are not supported.</p>
+ * <p>Optional; defaults to 1. A value of 1 means that partial
+ * results are not supported, and only the final TotalCaptureResult will
+ * be produced by the camera device.</p>
* <p>A typical use case for this might be: after requesting an
* auto-focus (AF) lock the new AF state might be available 50%
* of the way through the pipeline. The camera device could
* then immediately dispatch this state via a partial result to
- * the framework/application layer, and the rest of the
- * metadata via later partial results.</p>
+ * the application, and the rest of the metadata via later
+ * partial results.</p>
*/
public static final Key<Integer> REQUEST_PARTIAL_RESULT_COUNT =
new Key<Integer>("android.request.partialResultCount", int.class);
@@ -806,8 +808,6 @@
* to do this query each of android.request.availableRequestKeys,
* android.request.availableResultKeys,
* android.request.availableCharacteristicsKeys.</p>
- * <p>XX: Maybe these should go into {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel}
- * as a table instead?</p>
* <p>The following capabilities are guaranteed to be available on
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} <code>==</code> FULL devices:</p>
* <ul>
@@ -815,14 +815,11 @@
* <li>MANUAL_POST_PROCESSING</li>
* </ul>
* <p>Other capabilities may be available on either FULL or LIMITED
- * devices, but the app. should query this field to be sure.</p>
+ * devices, but the application should query this field to be sure.</p>
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
- * @see #REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
- * @see #REQUEST_AVAILABLE_CAPABILITIES_OPTIONAL
* @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR
* @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING
- * @see #REQUEST_AVAILABLE_CAPABILITIES_ZSL
* @see #REQUEST_AVAILABLE_CAPABILITIES_DNG
*/
public static final Key<int[]> REQUEST_AVAILABLE_CAPABILITIES =
@@ -838,7 +835,6 @@
* at a more granular level than capabilities. This is especially
* important for optional keys that are not listed under any capability
* in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}.</p>
- * <p>TODO: This should be used by #getAvailableCaptureRequestKeys.</p>
*
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
* @hide
@@ -863,7 +859,6 @@
* at a more granular level than capabilities. This is especially
* important for optional keys that are not listed under any capability
* in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}.</p>
- * <p>TODO: This should be used by #getAvailableCaptureResultKeys.</p>
*
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
* @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
@@ -879,7 +874,6 @@
* android.request.availableResultKeys (except that it applies for
* CameraCharacteristics instead of CaptureResult). See above for more
* details.</p>
- * <p>TODO: This should be used by CameraCharacteristics#getKeys.</p>
* @hide
*/
public static final Key<int[]> REQUEST_AVAILABLE_CHARACTERISTICS_KEYS =
@@ -927,10 +921,15 @@
new Key<android.util.Size[]>("android.scaler.availableJpegSizes", android.util.Size[].class);
/**
- * <p>The maximum ratio between active area width
- * and crop region width, or between active area height and
- * crop region height, if the crop region height is larger
- * than width</p>
+ * <p>The maximum ratio between both active area width
+ * and crop region width, and active area height and
+ * crop region height.</p>
+ * <p>This represents the maximum amount of zooming possible by
+ * the camera device, or equivalently, the minimum cropping
+ * window size.</p>
+ * <p>Crop regions that have a width or height that is smaller
+ * than this ratio allows will be rounded up to the minimum
+ * allowed size by the camera device.</p>
*/
public static final Key<Float> SCALER_AVAILABLE_MAX_DIGITAL_ZOOM =
new Key<Float>("android.scaler.availableMaxDigitalZoom", float.class);
@@ -1339,9 +1338,9 @@
new Key<android.util.Range<Integer>>("android.sensor.info.sensitivityRange", new TypeReference<android.util.Range<Integer>>() {{ }});
/**
- * <p>Arrangement of color filters on sensor;
+ * <p>The arrangement of color filters on sensor;
* represents the colors in the top-left 2x2 section of
- * the sensor, in reading order</p>
+ * the sensor, in reading order.</p>
* @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB
* @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG
* @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG
@@ -1666,10 +1665,9 @@
new Key<int[]>("android.sensor.availableTestPatternModes", int[].class);
/**
- * <p>Which face detection modes are available,
- * if any.</p>
- * <p>OFF means face detection is disabled, it must
- * be included in the list.</p>
+ * <p>The face detection modes that are available
+ * for this camera device.</p>
+ * <p>OFF is always supported.</p>
* <p>SIMPLE means the device supports the
* android.statistics.faceRectangles and
* android.statistics.faceScores outputs.</p>
@@ -1681,8 +1679,8 @@
new Key<int[]>("android.statistics.info.availableFaceDetectModes", int[].class);
/**
- * <p>Maximum number of simultaneously detectable
- * faces</p>
+ * <p>The maximum number of simultaneously detectable
+ * faces.</p>
*/
public static final Key<Integer> STATISTICS_INFO_MAX_FACE_COUNT =
new Key<Integer>("android.statistics.info.maxFaceCount", int.class);
@@ -1691,7 +1689,7 @@
* <p>The set of hot pixel map output modes supported by this camera device.</p>
* <p>This tag lists valid output modes for {@link CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE android.statistics.hotPixelMapMode}.</p>
* <p>If no hotpixel map is available for this camera device, this will contain
- * only OFF. If the hotpixel map is available, this should include both
+ * only OFF. If the hotpixel map is available, this will include both
* the ON and OFF options.</p>
*
* @see CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 90e5e4e..33e1915 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -157,8 +157,8 @@
/**
* <p>The lens focus distance is not accurate, and the units used for
- * {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} do not correspond to any physical units.
- * Setting the lens to the same focus distance on separate occasions may
+ * {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} do not correspond to any physical units.</p>
+ * <p>Setting the lens to the same focus distance on separate occasions may
* result in a different real focus distance, depending on factors such
* as the orientation of the device, the age of the focusing mechanism,
* and the device temperature. The focus distance value will still be
@@ -172,20 +172,24 @@
public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED = 0;
/**
- * <p>The lens focus distance is measured in diopters. However, setting the lens
- * to the same focus distance on separate occasions may result in a
- * different real focus distance, depending on factors such as the
- * orientation of the device, the age of the focusing mechanism, and
- * the device temperature.</p>
+ * <p>The lens focus distance is measured in diopters.</p>
+ * <p>However, setting the lens to the same focus distance
+ * on separate occasions may result in a different real
+ * focus distance, depending on factors such as the
+ * orientation of the device, the age of the focusing
+ * mechanism, and the device temperature.</p>
* @see CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
*/
public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE = 1;
/**
- * <p>The lens focus distance is measured in diopters. The lens mechanism is
- * calibrated so that setting the same focus distance is repeatable on
- * multiple occasions with good accuracy, and the focus distance corresponds
- * to the real physical distance to the plane of best focus.</p>
+ * <p>The lens focus distance is measured in diopters, and
+ * is calibrated.</p>
+ * <p>The lens mechanism is calibrated so that setting the
+ * same focus distance is repeatable on multiple
+ * occasions with good accuracy, and the focus distance
+ * corresponds to the real physical distance to the plane
+ * of best focus.</p>
* @see CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
*/
public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED = 2;
@@ -195,11 +199,13 @@
//
/**
+ * <p>The camera device faces the same direction as the device's screen.</p>
* @see CameraCharacteristics#LENS_FACING
*/
public static final int LENS_FACING_FRONT = 0;
/**
+ * <p>The camera device faces the opposite direction as the device's screen.</p>
* @see CameraCharacteristics#LENS_FACING
*/
public static final int LENS_FACING_BACK = 1;
@@ -215,11 +221,10 @@
* <p>The full set of features supported by this capability makes
* the camera2 api backwards compatible with the camera1
* (android.hardware.Camera) API.</p>
- * <p>TODO: @hide this. Doesn't really mean anything except
- * act as a catch-all for all the 'base' functionality.</p>
*
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+ * @hide
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0;
@@ -228,15 +233,14 @@
* tags or functionality not encapsulated by one of the other
* capabilities.</p>
* <p>A typical example is all tags marked 'optional'.</p>
- * <p>TODO: @hide. We may not need this if we @hide all the optional
- * tags not belonging to a capability.</p>
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+ * @hide
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_OPTIONAL = 1;
/**
* <p>The camera device can be manually controlled (3A algorithms such
- * as auto exposure, and auto focus can be bypassed).
+ * as auto-exposure, and auto-focus can be bypassed).
* The camera device supports basic manual control of the sensor image
* acquisition related stages. This means the following controls are
* guaranteed to be supported:</p>
@@ -257,11 +261,11 @@
* <li>{@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange}</li>
* </ul>
* </li>
- * <li>Manual lens control<ul>
+ * <li>Manual lens control (if the lens is adjustable)<ul>
* <li>android.lens.*</li>
* </ul>
* </li>
- * <li>Manual flash control<ul>
+ * <li>Manual flash control (if a flash unit is present)<ul>
* <li>android.flash.*</li>
* </ul>
* </li>
@@ -312,8 +316,6 @@
* </ul>
* <p>If auto white balance is enabled, then the camera device
* will accurately report the values applied by AWB in the result.</p>
- * <p>The camera device will also support everything in MANUAL_SENSOR
- * except manual lens control and manual flash control.</p>
* <p>A given camera device may also support additional post-processing
* controls, but this capability only covers the above list of controls.</p>
*
@@ -340,8 +342,8 @@
* (both input/output) will match the maximum available
* resolution of JPEG streams.</li>
* </ul>
- * <p>@hide this, TODO: remove it when input related APIs are ready.</p>
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+ * @hide
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_ZSL = 4;
@@ -355,7 +357,7 @@
* <li>RAW16 is reprocessable into both YUV_420_888 and JPEG
* formats.</li>
* <li>The maximum available resolution for RAW16 streams (both
- * input/output) will match the either value in
+ * input/output) will match either the value in
* {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize} or
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</li>
* <li>All DNG-related optional metadata entries are provided
@@ -373,13 +375,13 @@
//
/**
- * <p>The camera device will only support centered crop regions.</p>
+ * <p>The camera device only supports centered crop regions.</p>
* @see CameraCharacteristics#SCALER_CROPPING_TYPE
*/
public static final int SCALER_CROPPING_TYPE_CENTER_ONLY = 0;
/**
- * <p>The camera device will support arbitrarily chosen crop regions.</p>
+ * <p>The camera device supports arbitrarily chosen crop regions.</p>
* @see CameraCharacteristics#SCALER_CROPPING_TYPE
*/
public static final int SCALER_CROPPING_TYPE_FREEFORM = 1;
@@ -525,7 +527,7 @@
//
/**
- * <p>android.led.transmit control is used</p>
+ * <p>android.led.transmit control is used.</p>
* @see CameraCharacteristics#LED_AVAILABLE_LEDS
* @hide
*/
@@ -536,11 +538,14 @@
//
/**
+ * <p>This camera device has only limited capabilities.</p>
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
*/
public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0;
/**
+ * <p>This camera device is capable of supporting advanced imaging
+ * applications.</p>
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
*/
public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1;
@@ -550,9 +555,9 @@
//
/**
- * <p>Every frame has the requests immediately applied.
- * (and furthermore for all results,
- * <code>android.sync.frameNumber == android.request.frameCount</code>)</p>
+ * <p>Every frame has the requests immediately applied.</p>
+ * <p>Furthermore for all results,
+ * <code>android.sync.frameNumber == android.request.frameCount</code></p>
* <p>Changing controls over multiple requests one after another will
* produce results that have those controls applied atomically
* each frame.</p>
@@ -592,8 +597,8 @@
public static final int COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0;
/**
- * <p>Must not slow down capture rate relative to sensor raw
- * output.</p>
+ * <p>Color correction processing must not slow down
+ * capture rate relative to sensor raw output.</p>
* <p>Advanced white balance adjustments above and beyond
* the specified white balance pipeline may be applied.</p>
* <p>If AWB is enabled with <code>{@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} != OFF</code>, then
@@ -606,8 +611,9 @@
public static final int COLOR_CORRECTION_MODE_FAST = 1;
/**
- * <p>Capture rate (relative to sensor raw output)
- * may be reduced by high quality.</p>
+ * <p>Color correction processing operates at improved
+ * quality but reduced capture rate (relative to sensor raw
+ * output).</p>
* <p>Advanced white balance adjustments above and beyond
* the specified white balance pipeline may be applied.</p>
* <p>If AWB is enabled with <code>{@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} != OFF</code>, then
@@ -658,8 +664,8 @@
//
/**
- * <p>The camera device's autoexposure routine is disabled;
- * the application-selected {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
+ * <p>The camera device's autoexposure routine is disabled.</p>
+ * <p>The application-selected {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
* {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} and
* {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} are used by the camera
* device, along with android.flash.* fields, if there's
@@ -674,7 +680,8 @@
/**
* <p>The camera device's autoexposure routine is active,
- * with no flash control. The application's values for
+ * with no flash control.</p>
+ * <p>The application's values for
* {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
* {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, and
* {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} are ignored. The
@@ -691,10 +698,10 @@
/**
* <p>Like ON, except that the camera device also controls
* the camera's flash unit, firing it in low-light
- * conditions. The flash may be fired during a
- * precapture sequence (triggered by
- * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}) and may be fired
- * for captures for which the
+ * conditions.</p>
+ * <p>The flash may be fired during a precapture sequence
+ * (triggered by {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}) and
+ * may be fired for captures for which the
* {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} field is set to
* STILL_CAPTURE</p>
*
@@ -707,10 +714,10 @@
/**
* <p>Like ON, except that the camera device also controls
* the camera's flash unit, always firing it for still
- * captures. The flash may be fired during a precapture
- * sequence (triggered by
- * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}) and will always
- * be fired for captures for which the
+ * captures.</p>
+ * <p>The flash may be fired during a precapture sequence
+ * (triggered by {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}) and
+ * will always be fired for captures for which the
* {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} field is set to
* STILL_CAPTURE</p>
*
@@ -722,9 +729,10 @@
/**
* <p>Like ON_AUTO_FLASH, but with automatic red eye
- * reduction. If deemed necessary by the camera device,
- * a red eye reduction flash will fire during the
- * precapture sequence.</p>
+ * reduction.</p>
+ * <p>If deemed necessary by the camera device, a red eye
+ * reduction flash will fire during the precapture
+ * sequence.</p>
* @see CaptureRequest#CONTROL_AE_MODE
*/
public static final int CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4;
@@ -741,8 +749,9 @@
/**
* <p>The precapture metering sequence will be started
- * by the camera device. The exact effect of the precapture
- * trigger depends on the current AE mode and state.</p>
+ * by the camera device.</p>
+ * <p>The exact effect of the precapture trigger depends on
+ * the current AE mode and state.</p>
* @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
*/
public static final int CONTROL_AE_PRECAPTURE_TRIGGER_START = 1;
@@ -754,7 +763,7 @@
/**
* <p>The auto-focus routine does not control the lens;
* {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} is controlled by the
- * application</p>
+ * application.</p>
*
* @see CaptureRequest#LENS_FOCUS_DISTANCE
* @see CaptureRequest#CONTROL_AF_MODE
@@ -839,8 +848,11 @@
public static final int CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4;
/**
- * <p>Extended depth of field (digital focus). AF
- * trigger is ignored, AF state should always be
+ * <p>Extended depth of field (digital focus) mode.</p>
+ * <p>The camera device will produce images with an extended
+ * depth of field automatically; no special focusing
+ * operations need to be done before taking a picture.</p>
+ * <p>AF triggers are ignored, and the AF state will always be
* INACTIVE.</p>
* @see CaptureRequest#CONTROL_AF_MODE
*/
@@ -874,8 +886,8 @@
//
/**
- * <p>The camera device's auto white balance routine is disabled;
- * the application-selected color transform matrix
+ * <p>The camera device's auto-white balance routine is disabled.</p>
+ * <p>The application-selected color transform matrix
* ({@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}) and gains
* ({@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}) are used by the camera
* device for manual white balance control.</p>
@@ -887,9 +899,12 @@
public static final int CONTROL_AWB_MODE_OFF = 0;
/**
- * <p>The camera device's auto white balance routine is active;
- * the application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
- * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.</p>
+ * <p>The camera device's auto-white balance routine is active.</p>
+ * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+ * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+ * For devices that support the MANUAL_POST_PROCESSING capability, the
+ * values used by the camera device for the transform and gains
+ * will be available in the capture result for this request.</p>
*
* @see CaptureRequest#COLOR_CORRECTION_GAINS
* @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
@@ -898,65 +913,125 @@
public static final int CONTROL_AWB_MODE_AUTO = 1;
/**
- * <p>The camera device's auto white balance routine is disabled;
+ * <p>The camera device's auto-white balance routine is disabled;
* the camera device uses incandescent light as the assumed scene
- * illumination for white balance. While the exact white balance
- * transforms are up to the camera device, they will approximately
- * match the CIE standard illuminant A.</p>
+ * illumination for white balance.</p>
+ * <p>While the exact white balance transforms are up to the
+ * camera device, they will approximately match the CIE
+ * standard illuminant A.</p>
+ * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+ * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+ * For devices that support the MANUAL_POST_PROCESSING capability, the
+ * values used by the camera device for the transform and gains
+ * will be available in the capture result for this request.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_GAINS
+ * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
* @see CaptureRequest#CONTROL_AWB_MODE
*/
public static final int CONTROL_AWB_MODE_INCANDESCENT = 2;
/**
- * <p>The camera device's auto white balance routine is disabled;
+ * <p>The camera device's auto-white balance routine is disabled;
* the camera device uses fluorescent light as the assumed scene
- * illumination for white balance. While the exact white balance
- * transforms are up to the camera device, they will approximately
- * match the CIE standard illuminant F2.</p>
+ * illumination for white balance.</p>
+ * <p>While the exact white balance transforms are up to the
+ * camera device, they will approximately match the CIE
+ * standard illuminant F2.</p>
+ * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+ * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+ * For devices that support the MANUAL_POST_PROCESSING capability, the
+ * values used by the camera device for the transform and gains
+ * will be available in the capture result for this request.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_GAINS
+ * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
* @see CaptureRequest#CONTROL_AWB_MODE
*/
public static final int CONTROL_AWB_MODE_FLUORESCENT = 3;
/**
- * <p>The camera device's auto white balance routine is disabled;
+ * <p>The camera device's auto-white balance routine is disabled;
* the camera device uses warm fluorescent light as the assumed scene
- * illumination for white balance. While the exact white balance
- * transforms are up to the camera device, they will approximately
- * match the CIE standard illuminant F4.</p>
+ * illumination for white balance.</p>
+ * <p>While the exact white balance transforms are up to the
+ * camera device, they will approximately match the CIE
+ * standard illuminant F4.</p>
+ * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+ * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+ * For devices that support the MANUAL_POST_PROCESSING capability, the
+ * values used by the camera device for the transform and gains
+ * will be available in the capture result for this request.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_GAINS
+ * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
* @see CaptureRequest#CONTROL_AWB_MODE
*/
public static final int CONTROL_AWB_MODE_WARM_FLUORESCENT = 4;
/**
- * <p>The camera device's auto white balance routine is disabled;
+ * <p>The camera device's auto-white balance routine is disabled;
* the camera device uses daylight light as the assumed scene
- * illumination for white balance. While the exact white balance
- * transforms are up to the camera device, they will approximately
- * match the CIE standard illuminant D65.</p>
+ * illumination for white balance.</p>
+ * <p>While the exact white balance transforms are up to the
+ * camera device, they will approximately match the CIE
+ * standard illuminant D65.</p>
+ * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+ * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+ * For devices that support the MANUAL_POST_PROCESSING capability, the
+ * values used by the camera device for the transform and gains
+ * will be available in the capture result for this request.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_GAINS
+ * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
* @see CaptureRequest#CONTROL_AWB_MODE
*/
public static final int CONTROL_AWB_MODE_DAYLIGHT = 5;
/**
- * <p>The camera device's auto white balance routine is disabled;
+ * <p>The camera device's auto-white balance routine is disabled;
* the camera device uses cloudy daylight light as the assumed scene
* illumination for white balance.</p>
+ * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+ * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+ * For devices that support the MANUAL_POST_PROCESSING capability, the
+ * values used by the camera device for the transform and gains
+ * will be available in the capture result for this request.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_GAINS
+ * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
* @see CaptureRequest#CONTROL_AWB_MODE
*/
public static final int CONTROL_AWB_MODE_CLOUDY_DAYLIGHT = 6;
/**
- * <p>The camera device's auto white balance routine is disabled;
+ * <p>The camera device's auto-white balance routine is disabled;
* the camera device uses twilight light as the assumed scene
* illumination for white balance.</p>
+ * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+ * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+ * For devices that support the MANUAL_POST_PROCESSING capability, the
+ * values used by the camera device for the transform and gains
+ * will be available in the capture result for this request.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_GAINS
+ * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
* @see CaptureRequest#CONTROL_AWB_MODE
*/
public static final int CONTROL_AWB_MODE_TWILIGHT = 7;
/**
- * <p>The camera device's auto white balance routine is disabled;
+ * <p>The camera device's auto-white balance routine is disabled;
* the camera device uses shade light as the assumed scene
* illumination for white balance.</p>
+ * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+ * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+ * For devices that support the MANUAL_POST_PROCESSING capability, the
+ * values used by the camera device for the transform and gains
+ * will be available in the capture result for this request.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_GAINS
+ * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
* @see CaptureRequest#CONTROL_AWB_MODE
*/
public static final int CONTROL_AWB_MODE_SHADE = 8;
@@ -966,38 +1041,43 @@
//
/**
- * <p>This request doesn't fall into the other
- * categories. Default to preview-like
+ * <p>The goal of this request doesn't fall into the other
+ * categories. The camera device will default to preview-like
* behavior.</p>
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
*/
public static final int CONTROL_CAPTURE_INTENT_CUSTOM = 0;
/**
- * <p>This request is for a preview-like usecase. The
- * precapture trigger may be used to start off a metering
- * w/flash sequence</p>
+ * <p>This request is for a preview-like use case.</p>
+ * <p>The precapture trigger may be used to start off a metering
+ * w/flash sequence.</p>
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
*/
public static final int CONTROL_CAPTURE_INTENT_PREVIEW = 1;
/**
* <p>This request is for a still capture-type
- * usecase.</p>
+ * use case.</p>
+ * <p>If the flash unit is under automatic control, it may fire as needed.</p>
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
*/
public static final int CONTROL_CAPTURE_INTENT_STILL_CAPTURE = 2;
/**
* <p>This request is for a video recording
- * usecase.</p>
+ * use case.</p>
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
*/
public static final int CONTROL_CAPTURE_INTENT_VIDEO_RECORD = 3;
/**
* <p>This request is for a video snapshot (still
- * image while recording video) usecase</p>
+ * image while recording video) use case.</p>
+ * <p>The camera device should take the highest-quality image
+ * possible (given the other settings) without disrupting the
+ * frame rate of video recording.<br />
+ * </p>
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
*/
public static final int CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT = 4;
@@ -1006,15 +1086,16 @@
* <p>This request is for a ZSL usecase; the
* application will stream full-resolution images and
* reprocess one or several later for a final
- * capture</p>
+ * capture.</p>
* @see CaptureRequest#CONTROL_CAPTURE_INTENT
*/
public static final int CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG = 5;
/**
* <p>This request is for manual capture use case where
- * the applications want to directly control the capture parameters
- * (e.g. {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}, {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} etc.).</p>
+ * the applications want to directly control the capture parameters.</p>
+ * <p>For example, the application may wish to manually control
+ * {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}, {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, etc.</p>
*
* @see CaptureRequest#SENSOR_EXPOSURE_TIME
* @see CaptureRequest#SENSOR_SENSITIVITY
@@ -1034,7 +1115,8 @@
/**
* <p>A "monocolor" effect where the image is mapped into
- * a single color. This will typically be grayscale.</p>
+ * a single color.</p>
+ * <p>This will typically be grayscale.</p>
* @see CaptureRequest#CONTROL_EFFECT_MODE
*/
public static final int CONTROL_EFFECT_MODE_MONO = 1;
@@ -1094,31 +1176,42 @@
//
/**
- * <p>Full application control of pipeline. All 3A
- * routines are disabled, no other settings in
- * android.control.* have any effect</p>
+ * <p>Full application control of pipeline.</p>
+ * <p>All control by the device's metering and focusing (3A)
+ * routines is disabled, and no other settings in
+ * android.control.* have any effect, except that
+ * {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} may be used by the camera
+ * device to select post-processing values for processing
+ * blocks that do not allow for manual control, or are not
+ * exposed by the camera API.</p>
+ * <p>However, the camera device's 3A routines may continue to
+ * collect statistics and update their internal state so that
+ * when control is switched to AUTO mode, good control values
+ * can be immediately applied.</p>
+ *
+ * @see CaptureRequest#CONTROL_CAPTURE_INTENT
* @see CaptureRequest#CONTROL_MODE
*/
public static final int CONTROL_MODE_OFF = 0;
/**
- * <p>Use settings for each individual 3A routine.
- * Manual control of capture parameters is disabled. All
+ * <p>Use settings for each individual 3A routine.</p>
+ * <p>Manual control of capture parameters is disabled. All
* controls in android.control.* besides sceneMode take
- * effect</p>
+ * effect.</p>
* @see CaptureRequest#CONTROL_MODE
*/
public static final int CONTROL_MODE_AUTO = 1;
/**
- * <p>Use specific scene mode. Enabling this disables
- * control.aeMode, control.awbMode and control.afMode
- * controls; the camera device will ignore those settings while
- * USE_SCENE_MODE is active (except for FACE_PRIORITY
- * scene mode). Other control entries are still active.
- * This setting can only be used if scene mode is supported
- * (i.e. {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes} contain some modes
- * other than DISABLED).</p>
+ * <p>Use a specific scene mode.</p>
+ * <p>Enabling this disables control.aeMode, control.awbMode and
+ * control.afMode controls; the camera device will ignore
+ * those settings while USE_SCENE_MODE is active (except for
+ * FACE_PRIORITY scene mode). Other control entries are still
+ * active. This setting can only be used if scene mode is
+ * supported (i.e. {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}
+ * contain some modes other than DISABLED).</p>
*
* @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
* @see CaptureRequest#CONTROL_MODE
@@ -1128,7 +1221,12 @@
/**
* <p>Same as OFF mode, except that this capture will not be
* used by camera device background auto-exposure, auto-white balance and
- * auto-focus algorithms to update their statistics.</p>
+ * auto-focus algorithms (3A) to update their statistics.</p>
+ * <p>Specifically, the 3A routines are locked to the last
+ * values set from a request with AUTO, OFF, or
+ * USE_SCENE_MODE, and any statistics or state updates
+ * collected from manual captures with OFF_KEEP_STATE will be
+ * discarded by the camera device.</p>
* @see CaptureRequest#CONTROL_MODE
*/
public static final int CONTROL_MODE_OFF_KEEP_STATE = 3;
@@ -1146,8 +1244,9 @@
/**
* <p>If face detection support exists, use face
* detection data for auto-focus, auto-white balance, and
- * auto-exposure routines. If face detection statistics are
- * disabled (i.e. {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} is set to OFF),
+ * auto-exposure routines.</p>
+ * <p>If face detection statistics are disabled
+ * (i.e. {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} is set to OFF),
* this should still operate correctly (but will not return
* face detection statistics to the framework).</p>
* <p>Unlike the other scene modes, {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
@@ -1163,8 +1262,8 @@
public static final int CONTROL_SCENE_MODE_FACE_PRIORITY = 1;
/**
- * <p>Optimized for photos of quickly moving objects.
- * Similar to SPORTS.</p>
+ * <p>Optimized for photos of quickly moving objects.</p>
+ * <p>Similar to SPORTS.</p>
* @see CaptureRequest#CONTROL_SCENE_MODE
*/
public static final int CONTROL_SCENE_MODE_ACTION = 2;
@@ -1233,8 +1332,8 @@
public static final int CONTROL_SCENE_MODE_FIREWORKS = 12;
/**
- * <p>Optimized for photos of quickly moving people.
- * Similar to ACTION.</p>
+ * <p>Optimized for photos of quickly moving people.</p>
+ * <p>Similar to ACTION.</p>
* @see CaptureRequest#CONTROL_SCENE_MODE
*/
public static final int CONTROL_SCENE_MODE_SPORTS = 13;
@@ -1266,11 +1365,13 @@
//
/**
+ * <p>Video stabilization is disabled.</p>
* @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
*/
public static final int CONTROL_VIDEO_STABILIZATION_MODE_OFF = 0;
/**
+ * <p>Video stabilization is enabled.</p>
* @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
*/
public static final int CONTROL_VIDEO_STABILIZATION_MODE_ON = 1;
@@ -1280,21 +1381,20 @@
//
/**
- * <p>No edge enhancement is applied</p>
+ * <p>No edge enhancement is applied.</p>
* @see CaptureRequest#EDGE_MODE
*/
public static final int EDGE_MODE_OFF = 0;
/**
- * <p>Must not slow down frame rate relative to sensor
+ * <p>Apply edge enhancement at a quality level that does not slow down frame rate relative to sensor
* output</p>
* @see CaptureRequest#EDGE_MODE
*/
public static final int EDGE_MODE_FAST = 1;
/**
- * <p>Frame rate may be reduced by high
- * quality</p>
+ * <p>Apply high-quality edge enhancement, at a cost of reducing output frame rate.</p>
* @see CaptureRequest#EDGE_MODE
*/
public static final int EDGE_MODE_HIGH_QUALITY = 2;
@@ -1327,10 +1427,10 @@
//
/**
+ * <p>No hot pixel correction is applied.</p>
* <p>The frame rate must not be reduced relative to sensor raw output
* for this option.</p>
- * <p>No hot pixel correction is applied.
- * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+ * <p>The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
*
* @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
* @see CaptureRequest#HOT_PIXEL_MODE
@@ -1338,10 +1438,9 @@
public static final int HOT_PIXEL_MODE_OFF = 0;
/**
- * <p>The frame rate must not be reduced relative to sensor raw output
- * for this option.</p>
- * <p>Hot pixel correction is applied.
- * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+ * <p>Hot pixel correction is applied, without reducing frame
+ * rate relative to sensor raw output.</p>
+ * <p>The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
*
* @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
* @see CaptureRequest#HOT_PIXEL_MODE
@@ -1349,10 +1448,9 @@
public static final int HOT_PIXEL_MODE_FAST = 1;
/**
- * <p>The frame rate may be reduced relative to sensor raw output
- * for this option.</p>
- * <p>A high-quality hot pixel correction is applied.
- * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+ * <p>High-quality hot pixel correction is applied, at a cost
+ * of reducing frame rate relative to sensor raw output.</p>
+ * <p>The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
*
* @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
* @see CaptureRequest#HOT_PIXEL_MODE
@@ -1380,21 +1478,21 @@
//
/**
- * <p>No noise reduction is applied</p>
+ * <p>No noise reduction is applied.</p>
* @see CaptureRequest#NOISE_REDUCTION_MODE
*/
public static final int NOISE_REDUCTION_MODE_OFF = 0;
/**
- * <p>Must not slow down frame rate relative to sensor
- * output</p>
+ * <p>Noise reduction is applied without reducing frame rate relative to sensor
+ * output.</p>
* @see CaptureRequest#NOISE_REDUCTION_MODE
*/
public static final int NOISE_REDUCTION_MODE_FAST = 1;
/**
- * <p>May slow down frame rate to provide highest
- * quality</p>
+ * <p>High-quality noise reduction is applied, at the cost of reducing frame rate
+ * relative to sensor output.</p>
* @see CaptureRequest#NOISE_REDUCTION_MODE
*/
public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2;
@@ -1404,8 +1502,9 @@
//
/**
- * <p>Default. No test pattern mode is used, and the camera
+ * <p>No test pattern mode is used, and the camera
* device returns captures from the image sensor.</p>
+ * <p>This is the default if the key is not set.</p>
* @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
*/
public static final int SENSOR_TEST_PATTERN_MODE_OFF = 0;
@@ -1509,19 +1608,21 @@
//
/**
- * <p>No lens shading correction is applied</p>
+ * <p>No lens shading correction is applied.</p>
* @see CaptureRequest#SHADING_MODE
*/
public static final int SHADING_MODE_OFF = 0;
/**
- * <p>Must not slow down frame rate relative to sensor raw output</p>
+ * <p>Apply lens shading corrections, without slowing
+ * frame rate relative to sensor raw output</p>
* @see CaptureRequest#SHADING_MODE
*/
public static final int SHADING_MODE_FAST = 1;
/**
- * <p>Frame rate may be reduced by high quality</p>
+ * <p>Apply high-quality lens shading correction, at the
+ * cost of reduced frame rate.</p>
* @see CaptureRequest#SHADING_MODE
*/
public static final int SHADING_MODE_HIGH_QUALITY = 2;
@@ -1531,20 +1632,28 @@
//
/**
+ * <p>Do not include face detection statistics in capture
+ * results.</p>
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
*/
public static final int STATISTICS_FACE_DETECT_MODE_OFF = 0;
/**
- * <p>Optional Return rectangle and confidence
- * only</p>
+ * <p>Return face rectangle and confidence values only.</p>
+ * <p>In this mode, only android.statistics.faceRectangles and
+ * android.statistics.faceScores outputs are valid.</p>
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
*/
public static final int STATISTICS_FACE_DETECT_MODE_SIMPLE = 1;
/**
- * <p>Optional Return all face
- * metadata</p>
+ * <p>Return all face
+ * metadata.</p>
+ * <p>In this mode,
+ * android.statistics.faceRectangles,
+ * android.statistics.faceScores,
+ * android.statistics.faceIds, and
+ * android.statistics.faceLandmarks outputs are valid.</p>
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
*/
public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2;
@@ -1554,11 +1663,13 @@
//
/**
+ * <p>Do not include a lens shading map in the capture result.</p>
* @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
*/
public static final int STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0;
/**
+ * <p>Include a lens shading map in the capture result.</p>
* @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
*/
public static final int STATISTICS_LENS_SHADING_MAP_MODE_ON = 1;
@@ -1582,15 +1693,15 @@
public static final int TONEMAP_MODE_CONTRAST_CURVE = 0;
/**
- * <p>Advanced gamma mapping and color enhancement may be applied.</p>
- * <p>Should not slow down frame rate relative to raw sensor output.</p>
+ * <p>Advanced gamma mapping and color enhancement may be applied, without
+ * reducing frame rate compared to raw sensor output.</p>
* @see CaptureRequest#TONEMAP_MODE
*/
public static final int TONEMAP_MODE_FAST = 1;
/**
- * <p>Advanced gamma mapping and color enhancement may be applied.</p>
- * <p>May slow down frame rate relative to raw sensor output.</p>
+ * <p>High-quality gamma mapping and color enhancement will be applied, at
+ * the cost of reduced frame rate compared to raw sensor output.</p>
* @see CaptureRequest#TONEMAP_MODE
*/
public static final int TONEMAP_MODE_HIGH_QUALITY = 2;
@@ -1600,7 +1711,8 @@
//
/**
- * <p>AE is off or recently reset. When a camera device is opened, it starts in
+ * <p>AE is off or recently reset.</p>
+ * <p>When a camera device is opened, it starts in
* this state. This is a transient state, the camera device may skip reporting
* this state in capture result.</p>
* @see CaptureResult#CONTROL_AE_STATE
@@ -1609,7 +1721,8 @@
/**
* <p>AE doesn't yet have a good set of control values
- * for the current scene. This is a transient state, the camera device may skip
+ * for the current scene.</p>
+ * <p>This is a transient state, the camera device may skip
* reporting this state in capture result.</p>
* @see CaptureResult#CONTROL_AE_STATE
*/
@@ -1638,11 +1751,13 @@
/**
* <p>AE has been asked to do a precapture sequence
- * (through the {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} START),
- * and is currently executing it. Once PRECAPTURE
- * completes, AE will transition to CONVERGED or
- * FLASH_REQUIRED as appropriate. This is a transient state, the
- * camera device may skip reporting this state in capture result.</p>
+ * and is currently executing it.</p>
+ * <p>Precapture can be triggered through setting
+ * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} to START.</p>
+ * <p>Once PRECAPTURE completes, AE will transition to CONVERGED
+ * or FLASH_REQUIRED as appropriate. This is a transient
+ * state, the camera device may skip reporting this state in
+ * capture result.</p>
*
* @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
* @see CaptureResult#CONTROL_AE_STATE
@@ -1654,61 +1769,78 @@
//
/**
- * <p>AF off or has not yet tried to scan/been asked
- * to scan. When a camera device is opened, it starts in
- * this state. This is a transient state, the camera device may
- * skip reporting this state in capture result.</p>
+ * <p>AF is off or has not yet tried to scan/been asked
+ * to scan.</p>
+ * <p>When a camera device is opened, it starts in this
+ * state. This is a transient state, the camera device may
+ * skip reporting this state in capture
+ * result.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_INACTIVE = 0;
/**
- * <p>if CONTINUOUS_* modes are supported. AF is
- * currently doing an AF scan initiated by a continuous
- * autofocus mode. This is a transient state, the camera device may
- * skip reporting this state in capture result.</p>
+ * <p>AF is currently performing an AF scan initiated the
+ * camera device in a continuous autofocus mode.</p>
+ * <p>Only used by CONTINUOUS_* AF modes. This is a transient
+ * state, the camera device may skip reporting this state in
+ * capture result.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_PASSIVE_SCAN = 1;
/**
- * <p>if CONTINUOUS_* modes are supported. AF currently
- * believes it is in focus, but may restart scanning at
- * any time. This is a transient state, the camera device may skip
- * reporting this state in capture result.</p>
+ * <p>AF currently believes it is in focus, but may
+ * restart scanning at any time.</p>
+ * <p>Only used by CONTINUOUS_* AF modes. This is a transient
+ * state, the camera device may skip reporting this state in
+ * capture result.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_PASSIVE_FOCUSED = 2;
/**
- * <p>if AUTO or MACRO modes are supported. AF is doing
- * an AF scan because it was triggered by AF trigger. This is a
- * transient state, the camera device may skip reporting
- * this state in capture result.</p>
+ * <p>AF is performing an AF scan because it was
+ * triggered by AF trigger.</p>
+ * <p>Only used by AUTO or MACRO AF modes. This is a transient
+ * state, the camera device may skip reporting this state in
+ * capture result.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_ACTIVE_SCAN = 3;
/**
- * <p>if any AF mode besides OFF is supported. AF
- * believes it is focused correctly and is
- * locked.</p>
+ * <p>AF believes it is focused correctly and has locked
+ * focus.</p>
+ * <p>This state is reached only after an explicit START AF trigger has been
+ * sent ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}), when good focus has been obtained.</p>
+ * <p>The lens will remain stationary until the AF mode ({@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}) is changed or
+ * a new AF trigger is sent to the camera device ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}).</p>
+ *
+ * @see CaptureRequest#CONTROL_AF_MODE
+ * @see CaptureRequest#CONTROL_AF_TRIGGER
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_FOCUSED_LOCKED = 4;
/**
- * <p>if any AF mode besides OFF is supported. AF has
- * failed to focus successfully and is
- * locked.</p>
+ * <p>AF has failed to focus successfully and has locked
+ * focus.</p>
+ * <p>This state is reached only after an explicit START AF trigger has been
+ * sent ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}), when good focus cannot be obtained.</p>
+ * <p>The lens will remain stationary until the AF mode ({@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}) is changed or
+ * a new AF trigger is sent to the camera device ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}).</p>
+ *
+ * @see CaptureRequest#CONTROL_AF_MODE
+ * @see CaptureRequest#CONTROL_AF_TRIGGER
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5;
/**
- * <p>if CONTINUOUS_* modes are supported. AF finished a
- * passive scan without finding focus, and may restart
- * scanning at any time. This is a transient state, the camera
+ * <p>AF finished a passive scan without finding focus,
+ * and may restart scanning at any time.</p>
+ * <p>Only used by CONTINUOUS_* AF modes. This is a transient state, the camera
* device may skip reporting this state in capture result.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
@@ -1719,16 +1851,19 @@
//
/**
- * <p>AWB is not in auto mode. When a camera device is opened, it
- * starts in this state. This is a transient state, the camera device may
- * skip reporting this state in capture result.</p>
+ * <p>AWB is not in auto mode, or has not yet started metering.</p>
+ * <p>When a camera device is opened, it starts in this
+ * state. This is a transient state, the camera device may
+ * skip reporting this state in capture
+ * result.</p>
* @see CaptureResult#CONTROL_AWB_STATE
*/
public static final int CONTROL_AWB_STATE_INACTIVE = 0;
/**
* <p>AWB doesn't yet have a good set of control
- * values for the current scene. This is a transient state, the camera device
+ * values for the current scene.</p>
+ * <p>This is a transient state, the camera device
* may skip reporting this state in capture result.</p>
* @see CaptureResult#CONTROL_AWB_STATE
*/
@@ -1776,8 +1911,9 @@
public static final int FLASH_STATE_FIRED = 3;
/**
- * <p>Flash partially illuminated this frame. This is usually due to the next
- * or previous frame having the flash fire, and the flash spilling into this capture
+ * <p>Flash partially illuminated this frame.</p>
+ * <p>This is usually due to the next or previous frame having
+ * the flash fire, and the flash spilling into this capture
* due to hardware limitations.</p>
* @see CaptureResult#FLASH_STATE
*/
@@ -1800,8 +1936,10 @@
public static final int LENS_STATE_STATIONARY = 0;
/**
- * <p>Any of the lens parameters ({@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance},
- * {@link CaptureRequest#LENS_FILTER_DENSITY android.lens.filterDensity} or {@link CaptureRequest#LENS_APERTURE android.lens.aperture}) is changing.</p>
+ * <p>One or several of the lens parameters
+ * ({@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance},
+ * {@link CaptureRequest#LENS_FILTER_DENSITY android.lens.filterDensity} or {@link CaptureRequest#LENS_APERTURE android.lens.aperture}) is
+ * currently changing.</p>
*
* @see CaptureRequest#LENS_APERTURE
* @see CaptureRequest#LENS_FILTER_DENSITY
@@ -1816,16 +1954,22 @@
//
/**
+ * <p>The camera device does not detect any flickering illumination
+ * in the current scene.</p>
* @see CaptureResult#STATISTICS_SCENE_FLICKER
*/
public static final int STATISTICS_SCENE_FLICKER_NONE = 0;
/**
+ * <p>The camera device detects illumination flickering at 50Hz
+ * in the current scene.</p>
* @see CaptureResult#STATISTICS_SCENE_FLICKER
*/
public static final int STATISTICS_SCENE_FLICKER_50HZ = 1;
/**
+ * <p>The camera device detects illumination flickering at 60Hz
+ * in the current scene.</p>
* @see CaptureResult#STATISTICS_SCENE_FLICKER
*/
public static final int STATISTICS_SCENE_FLICKER_60HZ = 2;
@@ -1835,8 +1979,8 @@
//
/**
- * <p>The current result is not yet fully synchronized to any request.
- * Synchronization is in progress, and reading metadata from this
+ * <p>The current result is not yet fully synchronized to any request.</p>
+ * <p>Synchronization is in progress, and reading metadata from this
* result may include a mix of data that have taken effect since the
* last synchronization time.</p>
* <p>In some future result, within {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} frames,
@@ -1851,10 +1995,10 @@
public static final int SYNC_FRAME_NUMBER_CONVERGING = -1;
/**
- * <p>The current result's synchronization status is unknown. The
- * result may have already converged, or it may be in progress.
- * Reading from this result may include some mix of settings from
- * past requests.</p>
+ * <p>The current result's synchronization status is unknown.</p>
+ * <p>The result may have already converged, or it may be in
+ * progress. Reading from this result may include some mix
+ * of settings from past requests.</p>
* <p>After a settings change, the new settings will eventually all
* take effect for the output buffers and results. However, this
* value will not change when that happens. Altering settings
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 0ff8cce..bf7bd37 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -733,8 +733,16 @@
* included at all in the request settings. When included and
* set to START, the camera device will trigger the autoexposure
* precapture metering sequence.</p>
- * <p>The effect of auto-exposure (AE) precapture trigger depends
- * on the current AE mode and state; see
+ * <p>The precapture sequence should triggered before starting a
+ * high-quality still capture for final metering decisions to
+ * be made, and for firing pre-capture flash pulses to estimate
+ * scene brightness and required final capture flash power, when
+ * the flash is enabled.</p>
+ * <p>Normally, this entry should be set to START for only a
+ * single request, and the application should wait until the
+ * sequence completes before starting a new one.</p>
+ * <p>The exact effect of auto-exposure (AE) precapture trigger
+ * depends on the current AE mode and state; see
* {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} for AE precapture state transition
* details.</p>
*
@@ -800,7 +808,11 @@
* autofocus algorithm. If autofocus is disabled, this trigger has no effect.</p>
* <p>When set to CANCEL, the camera device will cancel any active trigger,
* and return to its initial AF state.</p>
- * <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what that means for each AF mode.</p>
+ * <p>Generally, applications should set this entry to START or CANCEL for only a
+ * single capture, and then return it to IDLE (or not set at all). Specifying
+ * START for multiple captures in a row means restarting the AF operation over
+ * and over again.</p>
+ * <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
*
* @see CaptureResult#CONTROL_AF_STATE
* @see #CONTROL_AF_TRIGGER_IDLE
@@ -813,9 +825,11 @@
/**
* <p>Whether auto-white balance (AWB) is currently locked to its
* latest calculated values.</p>
- * <p>Note that AWB lock is only meaningful for AUTO
- * mode; in other modes, AWB is already fixed to a specific
- * setting.</p>
+ * <p>Note that AWB lock is only meaningful when
+ * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} is in the AUTO mode; in other modes,
+ * AWB is already fixed to a specific setting.</p>
+ *
+ * @see CaptureRequest#CONTROL_AWB_MODE
*/
public static final Key<Boolean> CONTROL_AWB_LOCK =
new Key<Boolean>("android.control.awbLock", boolean.class);
@@ -825,17 +839,21 @@
* transform fields, and what its illumination target
* is.</p>
* <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
- * <p>When set to the ON mode, the camera device's auto white balance
+ * <p>When set to the ON mode, the camera device's auto-white balance
* routine is enabled, overriding the application's selected
* {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
* {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
- * <p>When set to the OFF mode, the camera device's auto white balance
+ * <p>When set to the OFF mode, the camera device's auto-white balance
* routine is disabled. The application manually controls the white
* balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
* and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
- * <p>When set to any other modes, the camera device's auto white balance
- * routine is disabled. The camera device uses each particular illumination
- * target for white balance adjustment.</p>
+ * <p>When set to any other modes, the camera device's auto-white
+ * balance routine is disabled. The camera device uses each
+ * particular illumination target for white balance
+ * adjustment. The application's values for
+ * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform},
+ * {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
+ * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} are ignored.</p>
*
* @see CaptureRequest#COLOR_CORRECTION_GAINS
* @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -886,8 +904,8 @@
* strategy.</p>
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
- * <p>ZERO_SHUTTER_LAG must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains ZSL. MANUAL must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+ * <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+ * contains ZSL. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
* contains MANUAL_SENSOR.</p>
*
* @see CaptureRequest#CONTROL_MODE
@@ -962,7 +980,9 @@
* <p>This is the mode that that is active when
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY,
* these modes will disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
- * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.</p>
+ * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.
+ * The scene modes available for a given camera device are listed in
+ * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}.</p>
* <p>The interpretation and implementation of these scene modes is left
* to the implementor of the camera device. Their behavior will not be
* consistent across all devices, and any given device may only implement
@@ -970,6 +990,7 @@
*
* @see CaptureRequest#CONTROL_AE_MODE
* @see CaptureRequest#CONTROL_AF_MODE
+ * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
* @see CaptureRequest#CONTROL_AWB_MODE
* @see CaptureRequest#CONTROL_MODE
* @see #CONTROL_SCENE_MODE_DISABLED
@@ -996,6 +1017,8 @@
/**
* <p>Whether video stabilization is
* active.</p>
+ * <p>Video stabilization automatically translates and scales images from the camera
+ * in order to stabilize motion between consecutive frames.</p>
* <p>If enabled, video stabilization can modify the
* {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to keep the video stream
* stabilized</p>
@@ -1110,14 +1133,14 @@
/**
* <p>Compression quality of the final JPEG
* image.</p>
- * <p>85-95 is typical usage range</p>
+ * <p>85-95 is typical usage range.</p>
*/
public static final Key<Byte> JPEG_QUALITY =
new Key<Byte>("android.jpeg.quality", byte.class);
/**
* <p>Compression quality of JPEG
- * thumbnail</p>
+ * thumbnail.</p>
*/
public static final Key<Byte> JPEG_THUMBNAIL_QUALITY =
new Key<Byte>("android.jpeg.thumbnailQuality", byte.class);
@@ -1229,12 +1252,18 @@
/**
* <p>Sets whether the camera device uses optical image stabilization (OIS)
* when capturing images.</p>
- * <p>OIS is used to compensate for motion blur due to small movements of
- * the camera during capture. Unlike digital image stabilization, OIS makes
- * use of mechanical elements to stabilize the camera sensor, and thus
- * allows for longer exposure times before camera shake becomes
- * apparent.</p>
- * <p>This is not expected to be supported on most devices.</p>
+ * <p>OIS is used to compensate for motion blur due to small
+ * movements of the camera during capture. Unlike digital image
+ * stabilization ({@link CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE android.control.videoStabilizationMode}), OIS
+ * makes use of mechanical elements to stabilize the camera
+ * sensor, and thus allows for longer exposure times before
+ * camera shake becomes apparent.</p>
+ * <p>Not all devices will support OIS; see
+ * {@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization} for
+ * available controls.</p>
+ *
+ * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
+ * @see CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION
* @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
* @see #LENS_OPTICAL_STABILIZATION_MODE_ON
*/
@@ -1242,16 +1271,15 @@
new Key<Integer>("android.lens.opticalStabilizationMode", int.class);
/**
- * <p>Mode of operation for the noise reduction.
- * algorithm</p>
+ * <p>Mode of operation for the noise reduction algorithm.</p>
* <p>Noise filtering control. OFF means no noise reduction
* will be applied by the camera device.</p>
- * <p>This must be set to a valid mode in
+ * <p>This must be set to a valid mode from
* {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}.</p>
* <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
* will be applied. HIGH_QUALITY mode indicates that the camera device
* will use the highest-quality noise filtering algorithms,
- * even if it slows down capture rate. FAST means the camera device should not
+ * even if it slows down capture rate. FAST means the camera device will not
* slow down capture rate when applying noise filtering.</p>
*
* @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
@@ -1435,7 +1463,7 @@
* <p>When enabled, the sensor sends a test pattern instead of
* doing a real exposure from the camera.</p>
* <p>When a test pattern is enabled, all manual sensor controls specified
- * by android.sensor.* should be ignored. All other controls should
+ * by android.sensor.* will be ignored. All other controls should
* work as normal.</p>
* <p>For example, if manual flash is enabled, flash firing should still
* occur (and that the test pattern remain unmodified, since the flash
@@ -1490,7 +1518,7 @@
new Key<Integer>("android.shading.mode", int.class);
/**
- * <p>State of the face detector
+ * <p>Control for the face detector
* unit.</p>
* <p>Whether face detection is enabled, and whether it
* should output just the basic fields or the full set of
@@ -1508,7 +1536,7 @@
/**
* <p>Operating mode for hotpixel map generation.</p>
* <p>If set to ON, a hotpixel map is returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.
- * If set to OFF, no hotpixel map should be returned.</p>
+ * If set to OFF, no hotpixel map will be returned.</p>
* <p>This must be set to a valid mode from {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES android.statistics.info.availableHotPixelMapModes}.</p>
*
* @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
@@ -1521,7 +1549,7 @@
* <p>Whether the camera device will output the lens
* shading map in output result metadata.</p>
* <p>When set to ON,
- * android.statistics.lensShadingMap must be provided in
+ * android.statistics.lensShadingMap will be provided in
* the output result metadata.</p>
* @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
* @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index ce3de1d..3d17ed3 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -579,8 +579,16 @@
* included at all in the request settings. When included and
* set to START, the camera device will trigger the autoexposure
* precapture metering sequence.</p>
- * <p>The effect of auto-exposure (AE) precapture trigger depends
- * on the current AE mode and state; see
+ * <p>The precapture sequence should triggered before starting a
+ * high-quality still capture for final metering decisions to
+ * be made, and for firing pre-capture flash pulses to estimate
+ * scene brightness and required final capture flash power, when
+ * the flash is enabled.</p>
+ * <p>Normally, this entry should be set to START for only a
+ * single request, and the application should wait until the
+ * sequence completes before starting a new one.</p>
+ * <p>The exact effect of auto-exposure (AE) precapture trigger
+ * depends on the current AE mode and state; see
* {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} for AE precapture state transition
* details.</p>
*
@@ -592,7 +600,7 @@
new Key<Integer>("android.control.aePrecaptureTrigger", int.class);
/**
- * <p>Current state of auto-exposure (AE) algorithm.</p>
+ * <p>Current state of the auto-exposure (AE) algorithm.</p>
* <p>Switching between or enabling AE modes ({@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}) always
* resets the AE state to INACTIVE. Similarly, switching between {@link CaptureRequest#CONTROL_MODE android.control.mode},
* or {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} if <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code> resets all
@@ -844,7 +852,11 @@
* autofocus algorithm. If autofocus is disabled, this trigger has no effect.</p>
* <p>When set to CANCEL, the camera device will cancel any active trigger,
* and return to its initial AF state.</p>
- * <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what that means for each AF mode.</p>
+ * <p>Generally, applications should set this entry to START or CANCEL for only a
+ * single capture, and then return it to IDLE (or not set at all). Specifying
+ * START for multiple captures in a row means restarting the AF operation over
+ * and over again.</p>
+ * <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
*
* @see CaptureResult#CONTROL_AF_STATE
* @see #CONTROL_AF_TRIGGER_IDLE
@@ -1034,13 +1046,13 @@
* <td align="center">PASSIVE_SCAN</td>
* <td align="center">AF_TRIGGER</td>
* <td align="center">FOCUSED_LOCKED</td>
- * <td align="center">Immediate trans. If focus is good, Lens now locked</td>
+ * <td align="center">Immediate transition, if focus is good. Lens now locked</td>
* </tr>
* <tr>
* <td align="center">PASSIVE_SCAN</td>
* <td align="center">AF_TRIGGER</td>
* <td align="center">NOT_FOCUSED_LOCKED</td>
- * <td align="center">Immediate trans. if focus is bad, Lens now locked</td>
+ * <td align="center">Immediate transition, if focus is bad. Lens now locked</td>
* </tr>
* <tr>
* <td align="center">PASSIVE_SCAN</td>
@@ -1064,13 +1076,13 @@
* <td align="center">PASSIVE_FOCUSED</td>
* <td align="center">AF_TRIGGER</td>
* <td align="center">FOCUSED_LOCKED</td>
- * <td align="center">Immediate trans. Lens now locked</td>
+ * <td align="center">Immediate transition, lens now locked</td>
* </tr>
* <tr>
* <td align="center">PASSIVE_UNFOCUSED</td>
* <td align="center">AF_TRIGGER</td>
* <td align="center">NOT_FOCUSED_LOCKED</td>
- * <td align="center">Immediate trans. Lens now locked</td>
+ * <td align="center">Immediate transition, lens now locked</td>
* </tr>
* <tr>
* <td align="center">FOCUSED_LOCKED</td>
@@ -1137,13 +1149,13 @@
* <td align="center">PASSIVE_SCAN</td>
* <td align="center">AF_TRIGGER</td>
* <td align="center">FOCUSED_LOCKED</td>
- * <td align="center">Eventual trans. once focus good, Lens now locked</td>
+ * <td align="center">Eventual transition once the focus is good. Lens now locked</td>
* </tr>
* <tr>
* <td align="center">PASSIVE_SCAN</td>
* <td align="center">AF_TRIGGER</td>
* <td align="center">NOT_FOCUSED_LOCKED</td>
- * <td align="center">Eventual trans. if cannot focus, Lens now locked</td>
+ * <td align="center">Eventual transition if cannot find focus. Lens now locked</td>
* </tr>
* <tr>
* <td align="center">PASSIVE_SCAN</td>
@@ -1254,9 +1266,11 @@
/**
* <p>Whether auto-white balance (AWB) is currently locked to its
* latest calculated values.</p>
- * <p>Note that AWB lock is only meaningful for AUTO
- * mode; in other modes, AWB is already fixed to a specific
- * setting.</p>
+ * <p>Note that AWB lock is only meaningful when
+ * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} is in the AUTO mode; in other modes,
+ * AWB is already fixed to a specific setting.</p>
+ *
+ * @see CaptureRequest#CONTROL_AWB_MODE
*/
public static final Key<Boolean> CONTROL_AWB_LOCK =
new Key<Boolean>("android.control.awbLock", boolean.class);
@@ -1266,17 +1280,21 @@
* transform fields, and what its illumination target
* is.</p>
* <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
- * <p>When set to the ON mode, the camera device's auto white balance
+ * <p>When set to the ON mode, the camera device's auto-white balance
* routine is enabled, overriding the application's selected
* {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
* {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
- * <p>When set to the OFF mode, the camera device's auto white balance
+ * <p>When set to the OFF mode, the camera device's auto-white balance
* routine is disabled. The application manually controls the white
* balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
* and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
- * <p>When set to any other modes, the camera device's auto white balance
- * routine is disabled. The camera device uses each particular illumination
- * target for white balance adjustment.</p>
+ * <p>When set to any other modes, the camera device's auto-white
+ * balance routine is disabled. The camera device uses each
+ * particular illumination target for white balance
+ * adjustment. The application's values for
+ * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform},
+ * {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
+ * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} are ignored.</p>
*
* @see CaptureRequest#COLOR_CORRECTION_GAINS
* @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -1327,8 +1345,8 @@
* strategy.</p>
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
- * <p>ZERO_SHUTTER_LAG must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains ZSL. MANUAL must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+ * <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+ * contains ZSL. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
* contains MANUAL_SENSOR.</p>
*
* @see CaptureRequest#CONTROL_MODE
@@ -1533,7 +1551,9 @@
* <p>This is the mode that that is active when
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY,
* these modes will disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
- * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.</p>
+ * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.
+ * The scene modes available for a given camera device are listed in
+ * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}.</p>
* <p>The interpretation and implementation of these scene modes is left
* to the implementor of the camera device. Their behavior will not be
* consistent across all devices, and any given device may only implement
@@ -1541,6 +1561,7 @@
*
* @see CaptureRequest#CONTROL_AE_MODE
* @see CaptureRequest#CONTROL_AF_MODE
+ * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
* @see CaptureRequest#CONTROL_AWB_MODE
* @see CaptureRequest#CONTROL_MODE
* @see #CONTROL_SCENE_MODE_DISABLED
@@ -1567,6 +1588,8 @@
/**
* <p>Whether video stabilization is
* active.</p>
+ * <p>Video stabilization automatically translates and scales images from the camera
+ * in order to stabilize motion between consecutive frames.</p>
* <p>If enabled, video stabilization can modify the
* {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to keep the video stream
* stabilized</p>
@@ -1698,14 +1721,14 @@
/**
* <p>Compression quality of the final JPEG
* image.</p>
- * <p>85-95 is typical usage range</p>
+ * <p>85-95 is typical usage range.</p>
*/
public static final Key<Byte> JPEG_QUALITY =
new Key<Byte>("android.jpeg.quality", byte.class);
/**
* <p>Compression quality of JPEG
- * thumbnail</p>
+ * thumbnail.</p>
*/
public static final Key<Byte> JPEG_THUMBNAIL_QUALITY =
new Key<Byte>("android.jpeg.thumbnailQuality", byte.class);
@@ -1817,12 +1840,18 @@
/**
* <p>Sets whether the camera device uses optical image stabilization (OIS)
* when capturing images.</p>
- * <p>OIS is used to compensate for motion blur due to small movements of
- * the camera during capture. Unlike digital image stabilization, OIS makes
- * use of mechanical elements to stabilize the camera sensor, and thus
- * allows for longer exposure times before camera shake becomes
- * apparent.</p>
- * <p>This is not expected to be supported on most devices.</p>
+ * <p>OIS is used to compensate for motion blur due to small
+ * movements of the camera during capture. Unlike digital image
+ * stabilization ({@link CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE android.control.videoStabilizationMode}), OIS
+ * makes use of mechanical elements to stabilize the camera
+ * sensor, and thus allows for longer exposure times before
+ * camera shake becomes apparent.</p>
+ * <p>Not all devices will support OIS; see
+ * {@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization} for
+ * available controls.</p>
+ *
+ * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
+ * @see CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION
* @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
* @see #LENS_OPTICAL_STABILIZATION_MODE_ON
*/
@@ -1866,16 +1895,15 @@
new Key<Integer>("android.lens.state", int.class);
/**
- * <p>Mode of operation for the noise reduction.
- * algorithm</p>
+ * <p>Mode of operation for the noise reduction algorithm.</p>
* <p>Noise filtering control. OFF means no noise reduction
* will be applied by the camera device.</p>
- * <p>This must be set to a valid mode in
+ * <p>This must be set to a valid mode from
* {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}.</p>
* <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
* will be applied. HIGH_QUALITY mode indicates that the camera device
* will use the highest-quality noise filtering algorithms,
- * even if it slows down capture rate. FAST means the camera device should not
+ * even if it slows down capture rate. FAST means the camera device will not
* slow down capture rate when applying noise filtering.</p>
*
* @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
@@ -2170,7 +2198,7 @@
* <p>When enabled, the sensor sends a test pattern instead of
* doing a real exposure from the camera.</p>
* <p>When a test pattern is enabled, all manual sensor controls specified
- * by android.sensor.* should be ignored. All other controls should
+ * by android.sensor.* will be ignored. All other controls should
* work as normal.</p>
* <p>For example, if manual flash is enabled, flash firing should still
* occur (and that the test pattern remain unmodified, since the flash
@@ -2225,7 +2253,7 @@
new Key<Integer>("android.shading.mode", int.class);
/**
- * <p>State of the face detector
+ * <p>Control for the face detector
* unit.</p>
* <p>Whether face detection is enabled, and whether it
* should output just the basic fields or the full set of
@@ -2241,9 +2269,13 @@
new Key<Integer>("android.statistics.faceDetectMode", int.class);
/**
- * <p>List of unique IDs for detected
- * faces</p>
- * <p>Only available if faceDetectMode == FULL</p>
+ * <p>List of unique IDs for detected faces.</p>
+ * <p>Each detected face is given a unique ID that is valid for as long as the face is visible
+ * to the camera device. A face that leaves the field of view and later returns may be
+ * assigned a new ID.</p>
+ * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} == FULL</p>
+ *
+ * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
* @hide
*/
public static final Key<int[]> STATISTICS_FACE_IDS =
@@ -2251,8 +2283,13 @@
/**
* <p>List of landmarks for detected
- * faces</p>
- * <p>Only available if faceDetectMode == FULL</p>
+ * faces.</p>
+ * <p>The coordinate system is that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the active array.</p>
+ * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} == FULL</p>
+ *
+ * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
* @hide
*/
public static final Key<int[]> STATISTICS_FACE_LANDMARKS =
@@ -2260,8 +2297,13 @@
/**
* <p>List of the bounding rectangles for detected
- * faces</p>
- * <p>Only available if faceDetectMode != OFF</p>
+ * faces.</p>
+ * <p>The coordinate system is that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+ * <code>(0, 0)</code> being the top-left pixel of the active array.</p>
+ * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} != OFF</p>
+ *
+ * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
* @hide
*/
public static final Key<android.graphics.Rect[]> STATISTICS_FACE_RECTANGLES =
@@ -2270,8 +2312,9 @@
/**
* <p>List of the face confidence scores for
* detected faces</p>
- * <p>Only available if faceDetectMode != OFF. The value should be
- * meaningful (for example, setting 100 at all times is illegal).</p>
+ * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} != OFF.</p>
+ *
+ * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
* @hide
*/
public static final Key<byte[]> STATISTICS_FACE_SCORES =
@@ -2435,12 +2478,13 @@
* The camera device uses this entry to tell the application what the scene
* illuminant frequency is.</p>
* <p>When manual exposure control is enabled
- * (<code>{@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} == OFF</code> or <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == OFF</code>),
- * the {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} doesn't do the antibanding, and the
- * application can ensure it selects exposure times that do not cause banding
- * issues by looking into this metadata field. See {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode}
- * for more details.</p>
- * <p>Report NONE if there doesn't appear to be flickering illumination.</p>
+ * (<code>{@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} == OFF</code> or <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} ==
+ * OFF</code>), the {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} doesn't perform
+ * antibanding, and the application can ensure it selects
+ * exposure times that do not cause banding issues by looking
+ * into this metadata field. See
+ * {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} for more details.</p>
+ * <p>Reports NONE if there doesn't appear to be flickering illumination.</p>
*
* @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
* @see CaptureRequest#CONTROL_AE_MODE
@@ -2455,7 +2499,7 @@
/**
* <p>Operating mode for hotpixel map generation.</p>
* <p>If set to ON, a hotpixel map is returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.
- * If set to OFF, no hotpixel map should be returned.</p>
+ * If set to OFF, no hotpixel map will be returned.</p>
* <p>This must be set to a valid mode from {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES android.statistics.info.availableHotPixelMapModes}.</p>
*
* @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
@@ -2483,7 +2527,7 @@
* <p>Whether the camera device will output the lens
* shading map in output result metadata.</p>
* <p>When set to ON,
- * android.statistics.lensShadingMap must be provided in
+ * android.statistics.lensShadingMap will be provided in
* the output result metadata.</p>
* @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
* @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
diff --git a/core/java/android/hardware/camera2/params/StreamConfiguration.java b/core/java/android/hardware/camera2/params/StreamConfiguration.java
index dd862b5..a6fc10f 100644
--- a/core/java/android/hardware/camera2/params/StreamConfiguration.java
+++ b/core/java/android/hardware/camera2/params/StreamConfiguration.java
@@ -30,7 +30,8 @@
* Immutable class to store the available stream
* {@link CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS configurations} to set up
* {@link android.view.Surface Surfaces} for creating a {@link CameraCaptureSession capture session}
- * with {@link CameraDevice#createCaptureSession}. <!-- TODO: link to input stream configuration -->
+ * with {@link CameraDevice#createCaptureSession}.
+ * <!-- TODO: link to input stream configuration -->
*
* <p>This is the authoritative list for all input/output formats (and sizes respectively
* for that format) that are supported by a camera device.</p>
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 60e76e0..65d4726 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -429,6 +429,11 @@
*/
public final static int INVALID_NET_ID = 0;
+ /**
+ * @hide
+ */
+ public final static int REQUEST_ID_UNSET = 0;
+
private final IConnectivityManager mService;
private final String mPackageName;
@@ -883,8 +888,8 @@
* @hide
*/
public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
- for (Integer capability : nc.getNetworkCapabilities()) {
- switch (capability.intValue()) {
+ for (int capability : nc.getCapabilities()) {
+ switch (capability) {
case NetworkCapabilities.NET_CAPABILITY_CBS:
case NetworkCapabilities.NET_CAPABILITY_DUN:
case NetworkCapabilities.NET_CAPABILITY_EIMS:
@@ -902,7 +907,7 @@
}
// All the capabilities are typically provided by restricted networks.
// Conclude that this network is restricted.
- nc.removeNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+ nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
}
private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
@@ -926,15 +931,14 @@
return null;
}
NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
- netCap.addNetworkCapability(cap);
+ netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
maybeMarkCapabilitiesRestricted(netCap);
return netCap;
} else if (networkType == TYPE_WIFI) {
if ("p2p".equals(feature)) {
NetworkCapabilities netCap = new NetworkCapabilities();
netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
- netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
+ netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
maybeMarkCapabilitiesRestricted(netCap);
return netCap;
}
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 22b26b1..49a307e 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -74,8 +74,10 @@
if (linkProperties.getRoutes().size() == 0) {
for (RouteInfo r : orig.linkProperties.getRoutes()) linkProperties.addRoute(r);
}
- if (linkProperties.getDnses().size() == 0) {
- for (InetAddress d : orig.linkProperties.getDnses()) linkProperties.addDns(d);
+ if (linkProperties.getDnsServers().size() == 0) {
+ for (InetAddress d : orig.linkProperties.getDnsServers()) {
+ linkProperties.addDnsServer(d);
+ }
}
}
@@ -211,7 +213,7 @@
public boolean addDns(String addrString) {
if (TextUtils.isEmpty(addrString) == false) {
try {
- linkProperties.addDns(NetworkUtils.numericToInetAddress(addrString));
+ linkProperties.addDnsServer(NetworkUtils.numericToInetAddress(addrString));
} catch (IllegalArgumentException e) {
Log.e(TAG, "addDns failed with addrString " + addrString);
return true;
diff --git a/core/java/android/net/DnsPinger.java b/core/java/android/net/DnsPinger.java
index 66f0fd0..7acf3f5 100644
--- a/core/java/android/net/DnsPinger.java
+++ b/core/java/android/net/DnsPinger.java
@@ -248,7 +248,7 @@
return mDefaultDns;
}
- Collection<InetAddress> dnses = curLinkProps.getDnses();
+ Collection<InetAddress> dnses = curLinkProps.getDnsServers();
if (dnses == null || dnses.size() == 0) {
loge("getDns::LinkProps has null dns - returning default");
return mDefaultDns;
diff --git a/core/java/android/net/IpPrefix.aidl b/core/java/android/net/IpPrefix.aidl
new file mode 100644
index 0000000..9e552c7
--- /dev/null
+++ b/core/java/android/net/IpPrefix.aidl
@@ -0,0 +1,20 @@
+/**
+ *
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+parcelable IpPrefix;
diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java
new file mode 100644
index 0000000..a14d13f
--- /dev/null
+++ b/core/java/android/net/IpPrefix.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+/**
+ * This class represents an IP prefix, i.e., a contiguous block of IP addresses aligned on a
+ * power of two boundary (also known as an "IP subnet"). A prefix is specified by two pieces of
+ * information:
+ *
+ * <ul>
+ * <li>A starting IP address (IPv4 or IPv6). This is the first IP address of the prefix.
+ * <li>A prefix length. This specifies the length of the prefix by specifing the number of bits
+ * in the IP address, starting from the most significant bit in network byte order, that
+ * are constant for all addresses in the prefix.
+ * </ul>
+ *
+ * For example, the prefix <code>192.0.2.0/24</code> covers the 256 IPv4 addresses from
+ * <code>192.0.2.0</code> to <code>192.0.2.255</code>, inclusive, and the prefix
+ * <code>2001:db8:1:2</code> covers the 2^64 IPv6 addresses from <code>2001:db8:1:2::</code> to
+ * <code>2001:db8:1:2:ffff:ffff:ffff:ffff</code>, inclusive.
+ *
+ * Objects of this class are immutable.
+ */
+public final class IpPrefix implements Parcelable {
+ private final byte[] address; // network byte order
+ private final int prefixLength;
+
+ /**
+ * Constructs a new {@code IpPrefix} from a byte array containing an IPv4 or IPv6 address in
+ * network byte order and a prefix length.
+ *
+ * @param address the IP address. Must be non-null and exactly 4 or 16 bytes long.
+ * @param prefixLength the prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
+ *
+ * @hide
+ */
+ public IpPrefix(byte[] address, int prefixLength) {
+ if (address.length != 4 && address.length != 16) {
+ throw new IllegalArgumentException(
+ "IpPrefix has " + address.length + " bytes which is neither 4 nor 16");
+ }
+ if (prefixLength < 0 || prefixLength > (address.length * 8)) {
+ throw new IllegalArgumentException("IpPrefix with " + address.length +
+ " bytes has invalid prefix length " + prefixLength);
+ }
+ this.address = address.clone();
+ this.prefixLength = prefixLength;
+ // TODO: Validate that the non-prefix bits are zero
+ }
+
+ /**
+ * @hide
+ */
+ public IpPrefix(InetAddress address, int prefixLength) {
+ this(address.getAddress(), prefixLength);
+ }
+
+ /**
+ * Compares this {@code IpPrefix} object against the specified object in {@code obj}. Two
+ * objects are equal if they have the same startAddress and prefixLength.
+ *
+ * @param obj the object to be tested for equality.
+ * @return {@code true} if both objects are equal, {@code false} otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof IpPrefix)) {
+ return false;
+ }
+ IpPrefix that = (IpPrefix) obj;
+ return Arrays.equals(this.address, that.address) && this.prefixLength == that.prefixLength;
+ }
+
+ /**
+ * Gets the hashcode of the represented IP prefix.
+ *
+ * @return the appropriate hashcode value.
+ */
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(address) + 11 * prefixLength;
+ }
+
+ /**
+ * Returns a copy of the first IP address in the prefix. Modifying the returned object does not
+ * change this object's contents.
+ *
+ * @return the address in the form of a byte array.
+ */
+ public InetAddress getAddress() {
+ try {
+ return InetAddress.getByAddress(address);
+ } catch (UnknownHostException e) {
+ // Cannot happen. InetAddress.getByAddress can only throw an exception if the byte
+ // array is the wrong length, but we check that in the constructor.
+ return null;
+ }
+ }
+
+ /**
+ * Returns a copy of the IP address bytes in network order (the highest order byte is the zeroth
+ * element). Modifying the returned array does not change this object's contents.
+ *
+ * @return the address in the form of a byte array.
+ */
+ public byte[] getRawAddress() {
+ return address.clone();
+ }
+
+ /**
+ * Returns the prefix length of this {@code IpAddress}.
+ *
+ * @return the prefix length.
+ */
+ public int getPrefixLength() {
+ return prefixLength;
+ }
+
+ /**
+ * Implement the Parcelable interface.
+ */
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Implement the Parcelable interface.
+ */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeByteArray(address);
+ dest.writeInt(prefixLength);
+ }
+
+ /**
+ * Implement the Parcelable interface.
+ */
+ public static final Creator<IpPrefix> CREATOR =
+ new Creator<IpPrefix>() {
+ public IpPrefix createFromParcel(Parcel in) {
+ byte[] address = in.createByteArray();
+ int prefixLength = in.readInt();
+ return new IpPrefix(address, prefixLength);
+ }
+
+ public IpPrefix[] newArray(int size) {
+ return new IpPrefix[size];
+ }
+ };
+}
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index d07c0b61..5246078 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -39,18 +39,13 @@
* <ul>
* <li>An IP address and prefix length (e.g., {@code 2001:db8::1/64} or {@code 192.0.2.1/24}).
* The address must be unicast, as multicast addresses cannot be assigned to interfaces.
- * <li>Address flags: A bitmask of {@code IFA_F_*} values representing properties
- * of the address.
- * <li>Address scope: An integer defining the scope in which the address is unique (e.g.,
- * {@code RT_SCOPE_LINK} or {@code RT_SCOPE_SITE}).
- * <ul>
- *<p>
- * When constructing a {@code LinkAddress}, the IP address and prefix are required. The flags and
- * scope are optional. If they are not specified, the flags are set to zero, and the scope will be
- * determined based on the IP address (e.g., link-local addresses will be created with a scope of
- * {@code RT_SCOPE_LINK}, global addresses with {@code RT_SCOPE_UNIVERSE},
- * etc.) If they are specified, they are not checked for validity.
- *
+ * <li>Address flags: A bitmask of {@code OsConstants.IFA_F_*} values representing properties
+ * of the address (e.g., {@code android.system.OsConstants.IFA_F_OPTIMISTIC}).
+ * <li>Address scope: One of the {@code OsConstants.IFA_F_*} values; defines the scope in which
+ * the address is unique (e.g.,
+ * {@code android.system.OsConstants.RT_SCOPE_LINK} or
+ * {@code android.system.OsConstants.RT_SCOPE_UNIVERSE}).
+ * </ul>
*/
public class LinkAddress implements Parcelable {
/**
@@ -202,7 +197,9 @@
/**
* Compares this {@code LinkAddress} instance against {@code obj}. Two addresses are equal if
- * their address, prefix length, flags and scope are equal.
+ * their address, prefix length, flags and scope are equal. Thus, for example, two addresses
+ * that have the same address and prefix length are not equal if one of them is deprecated and
+ * the other is not.
*
* @param obj the object to be tested for equality.
* @return {@code true} if both objects are equal, {@code false} otherwise.
@@ -236,6 +233,7 @@
* @param other the {@code LinkAddress} to compare to.
* @return {@code true} if both objects have the same address and prefix length, {@code false}
* otherwise.
+ * @hide
*/
public boolean isSameAddressAs(LinkAddress other) {
return address.equals(other.address) && prefixLength == other.prefixLength;
@@ -251,11 +249,20 @@
/**
* Returns the prefix length of this {@code LinkAddress}.
*/
- public int getNetworkPrefixLength() {
+ public int getPrefixLength() {
return prefixLength;
}
/**
+ * Returns the prefix length of this {@code LinkAddress}.
+ * TODO: Delete all callers and remove in favour of getPrefixLength().
+ * @hide
+ */
+ public int getNetworkPrefixLength() {
+ return getPrefixLength();
+ }
+
+ /**
* Returns the flags of this {@code LinkAddress}.
*/
public int getFlags() {
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 3c36679..8eefa0f 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -30,6 +30,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Hashtable;
+import java.util.List;
/**
* Describes the properties of a network link.
@@ -43,7 +44,7 @@
* does not affect live networks.
*
*/
-public class LinkProperties implements Parcelable {
+public final class LinkProperties implements Parcelable {
// The interface described by the network link.
private String mIfaceName;
private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
@@ -58,10 +59,12 @@
private Hashtable<String, LinkProperties> mStackedLinks =
new Hashtable<String, LinkProperties>();
- // @hide
+ /**
+ * @hide
+ */
public static class CompareResult<T> {
- public Collection<T> removed = new ArrayList<T>();
- public Collection<T> added = new ArrayList<T>();
+ public List<T> removed = new ArrayList<T>();
+ public List<T> added = new ArrayList<T>();
@Override
public String toString() {
@@ -74,14 +77,20 @@
}
}
+ /**
+ * @hide
+ */
public LinkProperties() {
}
+ /**
+ * @hide
+ */
public LinkProperties(LinkProperties source) {
if (source != null) {
mIfaceName = source.getInterfaceName();
for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l);
- for (InetAddress i : source.getDnses()) mDnses.add(i);
+ for (InetAddress i : source.getDnsServers()) mDnses.add(i);
mDomains = source.getDomains();
for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
mHttpProxy = (source.getHttpProxy() == null) ?
@@ -98,6 +107,7 @@
* will have their interface changed to match this new value.
*
* @param iface The name of the network interface used for this link.
+ * @hide
*/
public void setInterfaceName(String iface) {
mIfaceName = iface;
@@ -117,9 +127,11 @@
return mIfaceName;
}
- // @hide
- public Collection<String> getAllInterfaceNames() {
- Collection interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
+ /**
+ * @hide
+ */
+ public List<String> getAllInterfaceNames() {
+ List<String> interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
if (mIfaceName != null) interfaceNames.add(new String(mIfaceName));
for (LinkProperties stacked: mStackedLinks.values()) {
interfaceNames.addAll(stacked.getAllInterfaceNames());
@@ -134,23 +146,23 @@
* prefix lengths for each address. This is a simplified utility alternative to
* {@link LinkProperties#getLinkAddresses}.
*
- * @return An umodifiable {@link Collection} of {@link InetAddress} for this link.
+ * @return An umodifiable {@link List} of {@link InetAddress} for this link.
* @hide
*/
- public Collection<InetAddress> getAddresses() {
- Collection<InetAddress> addresses = new ArrayList<InetAddress>();
+ public List<InetAddress> getAddresses() {
+ List<InetAddress> addresses = new ArrayList<InetAddress>();
for (LinkAddress linkAddress : mLinkAddresses) {
addresses.add(linkAddress.getAddress());
}
- return Collections.unmodifiableCollection(addresses);
+ return Collections.unmodifiableList(addresses);
}
/**
* Returns all the addresses on this link and all the links stacked above it.
* @hide
*/
- public Collection<InetAddress> getAllAddresses() {
- Collection<InetAddress> addresses = new ArrayList<InetAddress>();
+ public List<InetAddress> getAllAddresses() {
+ List<InetAddress> addresses = new ArrayList<InetAddress>();
for (LinkAddress linkAddress : mLinkAddresses) {
addresses.add(linkAddress.getAddress());
}
@@ -174,6 +186,7 @@
* same address/prefix does not already exist. If it does exist it is replaced.
* @param address The {@code LinkAddress} to add.
* @return true if {@code address} was added or updated, false otherwise.
+ * @hide
*/
public boolean addLinkAddress(LinkAddress address) {
if (address == null) {
@@ -200,6 +213,7 @@
*
* @param toRemove A {@link LinkAddress} specifying the address to remove.
* @return true if the address was removed, false if it did not exist.
+ * @hide
*/
public boolean removeLinkAddress(LinkAddress toRemove) {
int i = findLinkAddressIndex(toRemove);
@@ -214,18 +228,18 @@
* Returns all the {@link LinkAddress} on this link. Typically a link will have
* one IPv4 address and one or more IPv6 addresses.
*
- * @return An unmodifiable {@link Collection} of {@link LinkAddress} for this link.
+ * @return An unmodifiable {@link List} of {@link LinkAddress} for this link.
*/
- public Collection<LinkAddress> getLinkAddresses() {
- return Collections.unmodifiableCollection(mLinkAddresses);
+ public List<LinkAddress> getLinkAddresses() {
+ return Collections.unmodifiableList(mLinkAddresses);
}
/**
* Returns all the addresses on this link and all the links stacked above it.
* @hide
*/
- public Collection<LinkAddress> getAllLinkAddresses() {
- Collection<LinkAddress> addresses = new ArrayList<LinkAddress>();
+ public List<LinkAddress> getAllLinkAddresses() {
+ List<LinkAddress> addresses = new ArrayList<LinkAddress>();
addresses.addAll(mLinkAddresses);
for (LinkProperties stacked: mStackedLinks.values()) {
addresses.addAll(stacked.getAllLinkAddresses());
@@ -239,6 +253,7 @@
*
* @param addresses The {@link Collection} of {@link LinkAddress} to set in this
* object.
+ * @hide
*/
public void setLinkAddresses(Collection<LinkAddress> addresses) {
mLinkAddresses.clear();
@@ -250,20 +265,21 @@
/**
* Adds the given {@link InetAddress} to the list of DNS servers.
*
- * @param dns The {@link InetAddress} to add to the list of DNS servers.
+ * @param dnsServer The {@link InetAddress} to add to the list of DNS servers.
+ * @hide
*/
- public void addDns(InetAddress dns) {
- if (dns != null) mDnses.add(dns);
+ public void addDnsServer(InetAddress dnsServer) {
+ if (dnsServer != null) mDnses.add(dnsServer);
}
/**
- * Returns all the {@link LinkAddress} for DNS servers on this link.
+ * Returns all the {@link InetAddress} for DNS servers on this link.
*
- * @return An umodifiable {@link Collection} of {@link InetAddress} for DNS servers on
+ * @return An umodifiable {@link List} of {@link InetAddress} for DNS servers on
* this link.
*/
- public Collection<InetAddress> getDnses() {
- return Collections.unmodifiableCollection(mDnses);
+ public List<InetAddress> getDnsServers() {
+ return Collections.unmodifiableList(mDnses);
}
/**
@@ -271,6 +287,7 @@
*
* @param domains A {@link String} listing in priority order the comma separated
* domains to search when resolving host names on this link.
+ * @hide
*/
public void setDomains(String domains) {
mDomains = domains;
@@ -323,6 +340,7 @@
* proper course is to add either un-named or properly named {@link RouteInfo}.
*
* @param route A {@link RouteInfo} to add to this object.
+ * @hide
*/
public void addRoute(RouteInfo route) {
if (route != null) {
@@ -339,18 +357,18 @@
/**
* Returns all the {@link RouteInfo} set on this link.
*
- * @return An unmodifiable {@link Collection} of {@link RouteInfo} for this link.
+ * @return An unmodifiable {@link List} of {@link RouteInfo} for this link.
*/
- public Collection<RouteInfo> getRoutes() {
- return Collections.unmodifiableCollection(mRoutes);
+ public List<RouteInfo> getRoutes() {
+ return Collections.unmodifiableList(mRoutes);
}
/**
* Returns all the routes on this link and all the links stacked above it.
* @hide
*/
- public Collection<RouteInfo> getAllRoutes() {
- Collection<RouteInfo> routes = new ArrayList();
+ public List<RouteInfo> getAllRoutes() {
+ List<RouteInfo> routes = new ArrayList();
routes.addAll(mRoutes);
for (LinkProperties stacked: mStackedLinks.values()) {
routes.addAll(stacked.getAllRoutes());
@@ -364,6 +382,7 @@
* not enforce it and applications may ignore them.
*
* @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
+ * @hide
*/
public void setHttpProxy(ProxyInfo proxy) {
mHttpProxy = proxy;
@@ -419,16 +438,17 @@
* Returns all the links stacked on top of this link.
* @hide
*/
- public Collection<LinkProperties> getStackedLinks() {
- Collection<LinkProperties> stacked = new ArrayList<LinkProperties>();
+ public List<LinkProperties> getStackedLinks() {
+ List<LinkProperties> stacked = new ArrayList<LinkProperties>();
for (LinkProperties link : mStackedLinks.values()) {
stacked.add(new LinkProperties(link));
}
- return Collections.unmodifiableCollection(stacked);
+ return Collections.unmodifiableList(stacked);
}
/**
* Clears this object to its initial state.
+ * @hide
*/
public void clear() {
mIfaceName = null;
@@ -443,7 +463,6 @@
/**
* Implement the Parcelable interface
- * @hide
*/
public int describeContents() {
return 0;
@@ -463,12 +482,12 @@
String domainName = "Domains: " + mDomains;
- String mtu = "MTU: " + mMtu;
+ String mtu = " MTU: " + mMtu;
String routes = " Routes: [";
for (RouteInfo route : mRoutes) routes += route.toString() + ",";
routes += "] ";
- String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " ");
+ String proxy = (mHttpProxy == null ? "" : " HttpProxy: " + mHttpProxy.toString() + " ");
String stacked = "";
if (mStackedLinks.values().size() > 0) {
@@ -486,6 +505,7 @@
* Returns true if this link has an IPv4 address.
*
* @return {@code true} if there is an IPv4 address, {@code false} otherwise.
+ * @hide
*/
public boolean hasIPv4Address() {
for (LinkAddress address : mLinkAddresses) {
@@ -500,6 +520,7 @@
* Returns true if this link has an IPv6 address.
*
* @return {@code true} if there is an IPv6 address, {@code false} otherwise.
+ * @hide
*/
public boolean hasIPv6Address() {
for (LinkAddress address : mLinkAddresses) {
@@ -543,7 +564,7 @@
* @hide
*/
public boolean isIdenticalDnses(LinkProperties target) {
- Collection<InetAddress> targetDnses = target.getDnses();
+ Collection<InetAddress> targetDnses = target.getDnsServers();
String targetDomains = target.getDomains();
if (mDomains == null) {
if (targetDomains != null) return false;
@@ -696,7 +717,7 @@
result.removed = new ArrayList<InetAddress>(mDnses);
result.added.clear();
if (target != null) {
- for (InetAddress newAddress : target.getDnses()) {
+ for (InetAddress newAddress : target.getDnsServers()) {
if (! result.removed.remove(newAddress)) {
result.added.add(newAddress);
}
@@ -831,7 +852,7 @@
addressCount = in.readInt();
for (int i=0; i<addressCount; i++) {
try {
- netProp.addDns(InetAddress.getByAddress(in.createByteArray()));
+ netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray()));
} catch (UnknownHostException e) { }
}
netProp.setDomains(in.readString());
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 35274f1..fe96287 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -44,6 +44,9 @@
private static final String TAG = "NetworkCapabilities";
private static final boolean DBG = false;
+ /**
+ * @hide
+ */
public NetworkCapabilities() {
}
@@ -154,58 +157,64 @@
* Multiple capabilities may be applied sequentially. Note that when searching
* for a network to satisfy a request, all capabilities requested must be satisfied.
*
- * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
+ * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
+ * @return This NetworkCapability to facilitate chaining.
+ * @hide
*/
- public void addNetworkCapability(int networkCapability) {
- if (networkCapability < MIN_NET_CAPABILITY ||
- networkCapability > MAX_NET_CAPABILITY) {
+ public NetworkCapabilities addCapability(int capability) {
+ if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
throw new IllegalArgumentException("NetworkCapability out of range");
}
- mNetworkCapabilities |= 1 << networkCapability;
+ mNetworkCapabilities |= 1 << capability;
+ return this;
}
/**
* Removes (if found) the given capability from this {@code NetworkCapability} instance.
*
- * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
+ * @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
+ * @return This NetworkCapability to facilitate chaining.
+ * @hide
*/
- public void removeNetworkCapability(int networkCapability) {
- if (networkCapability < MIN_NET_CAPABILITY ||
- networkCapability > MAX_NET_CAPABILITY) {
+ public NetworkCapabilities removeCapability(int capability) {
+ if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
throw new IllegalArgumentException("NetworkCapability out of range");
}
- mNetworkCapabilities &= ~(1 << networkCapability);
+ mNetworkCapabilities &= ~(1 << capability);
+ return this;
}
/**
* Gets all the capabilities set on this {@code NetworkCapability} instance.
*
- * @return a {@link Collection} of {@code NetworkCapabilities.NET_CAPABILITY_*} values
+ * @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values
* for this instance.
+ * @hide
*/
- public Collection<Integer> getNetworkCapabilities() {
+ public int[] getCapabilities() {
return enumerateBits(mNetworkCapabilities);
}
/**
* Tests for the presence of a capabilitity on this instance.
*
- * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
+ * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
* @return {@code true} if set on this instance.
*/
- public boolean hasCapability(int networkCapability) {
- if (networkCapability < MIN_NET_CAPABILITY ||
- networkCapability > MAX_NET_CAPABILITY) {
+ public boolean hasCapability(int capability) {
+ if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
return false;
}
- return ((mNetworkCapabilities & (1 << networkCapability)) != 0);
+ return ((mNetworkCapabilities & (1 << capability)) != 0);
}
- private Collection<Integer> enumerateBits(long val) {
- ArrayList<Integer> result = new ArrayList<Integer>();
+ private int[] enumerateBits(long val) {
+ int size = Long.bitCount(val);
+ int[] result = new int[size];
+ int index = 0;
int resource = 0;
while (val > 0) {
- if ((val & 1) == 1) result.add(resource);
+ if ((val & 1) == 1) result[index++] = resource;
val = val >> 1;
resource++;
}
@@ -265,33 +274,40 @@
* {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
*
* @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added.
+ * @return This NetworkCapability to facilitate chaining.
+ * @hide
*/
- public void addTransportType(int transportType) {
+ public NetworkCapabilities addTransportType(int transportType) {
if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
throw new IllegalArgumentException("TransportType out of range");
}
mTransportTypes |= 1 << transportType;
+ return this;
}
/**
* Removes (if found) the given transport from this {@code NetworkCapability} instance.
*
* @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed.
+ * @return This NetworkCapability to facilitate chaining.
+ * @hide
*/
- public void removeTransportType(int transportType) {
+ public NetworkCapabilities removeTransportType(int transportType) {
if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
throw new IllegalArgumentException("TransportType out of range");
}
mTransportTypes &= ~(1 << transportType);
+ return this;
}
/**
* Gets all the transports set on this {@code NetworkCapability} instance.
*
- * @return a {@link Collection} of {@code NetworkCapabilities.TRANSPORT_*} values
+ * @return an array of {@code NetworkCapabilities.TRANSPORT_*} values
* for this instance.
+ * @hide
*/
- public Collection<Integer> getTransportTypes() {
+ public int[] getTransportTypes() {
return enumerateBits(mTransportTypes);
}
@@ -340,6 +356,7 @@
* fast backhauls and slow backhauls.
*
* @param upKbps the estimated first hop upstream (device to network) bandwidth.
+ * @hide
*/
public void setLinkUpstreamBandwidthKbps(int upKbps) {
mLinkUpBandwidthKbps = upKbps;
@@ -368,6 +385,7 @@
* fast backhauls and slow backhauls.
*
* @param downKbps the estimated first hop downstream (network to device) bandwidth.
+ * @hide
*/
public void setLinkDownstreamBandwidthKbps(int downKbps) {
mLinkDownBandwidthKbps = downKbps;
@@ -464,24 +482,22 @@
};
public String toString() {
- Collection<Integer> types = getTransportTypes();
- String transports = (types.size() > 0 ? " Transports: " : "");
- Iterator<Integer> i = types.iterator();
- while (i.hasNext()) {
- switch (i.next()) {
+ int[] types = getTransportTypes();
+ String transports = (types.length > 0 ? " Transports: " : "");
+ for (int i = 0; i < types.length;) {
+ switch (types[i]) {
case TRANSPORT_CELLULAR: transports += "CELLULAR"; break;
case TRANSPORT_WIFI: transports += "WIFI"; break;
case TRANSPORT_BLUETOOTH: transports += "BLUETOOTH"; break;
case TRANSPORT_ETHERNET: transports += "ETHERNET"; break;
}
- if (i.hasNext()) transports += "|";
+ if (++i < types.length) transports += "|";
}
- types = getNetworkCapabilities();
- String capabilities = (types.size() > 0 ? " Capabilities: " : "");
- i = types.iterator();
- while (i.hasNext()) {
- switch (i.next().intValue()) {
+ types = getCapabilities();
+ String capabilities = (types.length > 0 ? " Capabilities: " : "");
+ for (int i = 0; i < types.length; ) {
+ switch (types[i]) {
case NET_CAPABILITY_MMS: capabilities += "MMS"; break;
case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break;
case NET_CAPABILITY_DUN: capabilities += "DUN"; break;
@@ -497,7 +513,7 @@
case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break;
case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
}
- if (i.hasNext()) capabilities += "&";
+ if (++i < types.length) capabilities += "&";
}
String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 47377e9..7911c72 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -22,19 +22,14 @@
import java.util.concurrent.atomic.AtomicInteger;
/**
- * Defines a request for a network, made by calling {@link ConnectivityManager#requestNetwork}
- * or {@link ConnectivityManager#listenForNetwork}.
- *
- * This token records the {@link NetworkCapabilities} used to make the request and identifies
- * the request. It should be used to release the request via
- * {@link ConnectivityManager#releaseNetworkRequest} when the network is no longer desired.
+ * Defines a request for a network, made through {@link NetworkRequest.Builder} and used
+ * to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes
+ * via {@link ConnectivityManager#listenForNetwork}.
*/
public class NetworkRequest implements Parcelable {
/**
- * The {@link NetworkCapabilities} that define this request. This should not be modified.
- * The networkCapabilities of the request are set when
- * {@link ConnectivityManager#requestNetwork} is called and the value is presented here
- * as a convenient reminder of what was requested.
+ * The {@link NetworkCapabilities} that define this request.
+ * @hide
*/
public final NetworkCapabilities networkCapabilities;
@@ -71,6 +66,95 @@
this.legacyType = that.legacyType;
}
+ /**
+ * Builder used to create {@link NetworkRequest} objects. Specify the Network features
+ * needed in terms of {@link NetworkCapabilities} features
+ */
+ public static class Builder {
+ private final NetworkCapabilities mNetworkCapabilities = new NetworkCapabilities();
+
+ /**
+ * Default constructor for Builder.
+ */
+ public Builder() {}
+
+ /**
+ * Build {@link NetworkRequest} give the current set of capabilities.
+ */
+ public NetworkRequest build() {
+ return new NetworkRequest(mNetworkCapabilities, ConnectivityManager.TYPE_NONE,
+ ConnectivityManager.REQUEST_ID_UNSET);
+ }
+
+ /**
+ * Add the given capability requirement to this builder. These represent
+ * the requested network's required capabilities. Note that when searching
+ * for a network to satisfy a request, all capabilities requested must be
+ * satisfied. See {@link NetworkCapabilities} for {@code NET_CAPABILITIY_*}
+ * definitions.
+ *
+ * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to add.
+ * @return The builder to facilitate chaining
+ * {@code builder.addCapability(...).addCapability();}.
+ */
+ public Builder addCapability(int capability) {
+ mNetworkCapabilities.addCapability(capability);
+ return this;
+ }
+
+ /**
+ * Removes (if found) the given capability from this builder instance.
+ *
+ * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to remove.
+ * @return The builder to facilitate chaining.
+ */
+ public Builder removeCapability(int capability) {
+ mNetworkCapabilities.removeCapability(capability);
+ return this;
+ }
+
+ /**
+ * Adds the given transport requirement to this builder. These represent
+ * the set of allowed transports for the request. Only networks using one
+ * of these transports will satisfy the request. If no particular transports
+ * are required, none should be specified here. See {@link NetworkCapabilities}
+ * for {@code TRANSPORT_*} definitions.
+ *
+ * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to add.
+ * @return The builder to facilitate chaining.
+ */
+ public Builder addTransportType(int transportType) {
+ mNetworkCapabilities.addTransportType(transportType);
+ return this;
+ }
+
+ /**
+ * Removes (if found) the given transport from this builder instance.
+ *
+ * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to remove.
+ * @return The builder to facilitate chaining.
+ */
+ public Builder removeTransportType(int transportType) {
+ mNetworkCapabilities.removeTransportType(transportType);
+ return this;
+ }
+
+ /**
+ * @hide
+ */
+ public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
+ mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
+ return this;
+ }
+ /**
+ * @hide
+ */
+ public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
+ mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
+ return this;
+ }
+ }
+
// implement the Parcelable interface
public int describeContents() {
return 0;
diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java
index 4973b3d..573a8f8 100644
--- a/core/java/android/net/ProxyDataTracker.java
+++ b/core/java/android/net/ProxyDataTracker.java
@@ -107,8 +107,8 @@
mNetworkCapabilities = new NetworkCapabilities();
mNetworkInfo.setIsAvailable(true);
try {
- mLinkProperties.addDns(InetAddress.getByName(DNS1));
- mLinkProperties.addDns(InetAddress.getByName(DNS2));
+ mLinkProperties.addDnsServer(InetAddress.getByName(DNS1));
+ mLinkProperties.addDnsServer(InetAddress.getByName(DNS2));
} catch (UnknownHostException e) {
Log.e(TAG, "Could not add DNS address", e);
}
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index ad8e4f7..c2b888c 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -35,10 +35,10 @@
*
* A route contains three pieces of information:
* <ul>
- * <li>a destination {@link LinkAddress} for directly-connected subnets. If this is
- * {@code null} it indicates a default route of the address family (IPv4 or IPv6)
+ * <li>a destination {@link IpPrefix} specifying the network destinations covered by this route.
+ * If this is {@code null} it indicates a default route of the address family (IPv4 or IPv6)
* implied by the gateway IP address.
- * <li>a gateway {@link InetAddress} for default routes. If this is {@code null} it
+ * <li>a gateway {@link InetAddress} indicating the next hop to use. If this is {@code null} it
* indicates a directly-connected route.
* <li>an interface (which may be unspecified).
* </ul>
@@ -46,9 +46,10 @@
* destination and gateway are both specified, they must be of the same address family
* (IPv4 or IPv6).
*/
-public class RouteInfo implements Parcelable {
+public final class RouteInfo implements Parcelable {
/**
* The IP destination address for this route.
+ * TODO: Make this an IpPrefix.
*/
private final LinkAddress mDestination;
@@ -80,6 +81,19 @@
* @param destination the destination prefix
* @param gateway the IP address to route packets through
* @param iface the interface name to send packets on
+ *
+ * TODO: Convert to use IpPrefix.
+ *
+ * @hide
+ */
+ public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) {
+ this(destination == null ? null :
+ new LinkAddress(destination.getAddress(), destination.getPrefixLength()),
+ gateway, iface);
+ }
+
+ /**
+ * @hide
*/
public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
if (destination == null) {
@@ -105,7 +119,7 @@
mHasGateway = (!gateway.isAnyLocalAddress());
mDestination = new LinkAddress(NetworkUtils.getNetworkPart(destination.getAddress(),
- destination.getNetworkPrefixLength()), destination.getNetworkPrefixLength());
+ destination.getPrefixLength()), destination.getPrefixLength());
if ((destination.getAddress() instanceof Inet4Address &&
(gateway instanceof Inet4Address == false)) ||
(destination.getAddress() instanceof Inet6Address &&
@@ -128,8 +142,17 @@
* <p>
* Destination and gateway may not both be null.
*
- * @param destination the destination address and prefix in a {@link LinkAddress}
+ * @param destination the destination address and prefix in an {@link IpPrefix}
* @param gateway the {@link InetAddress} to route packets through
+ *
+ * @hide
+ */
+ public RouteInfo(IpPrefix destination, InetAddress gateway) {
+ this(destination, gateway, null);
+ }
+
+ /**
+ * @hide
*/
public RouteInfo(LinkAddress destination, InetAddress gateway) {
this(destination, gateway, null);
@@ -139,16 +162,27 @@
* Constructs a default {@code RouteInfo} object.
*
* @param gateway the {@link InetAddress} to route packets through
+ *
+ * @hide
*/
public RouteInfo(InetAddress gateway) {
- this(null, gateway, null);
+ this((LinkAddress) null, gateway, null);
}
/**
* Constructs a {@code RouteInfo} object representing a direct connected subnet.
*
- * @param destination the {@link LinkAddress} describing the address and prefix
+ * @param destination the {@link IpPrefix} describing the address and prefix
* length of the subnet.
+ *
+ * @hide
+ */
+ public RouteInfo(IpPrefix destination) {
+ this(destination, null, null);
+ }
+
+ /**
+ * @hide
*/
public RouteInfo(LinkAddress destination) {
this(destination, null, null);
@@ -176,29 +210,37 @@
private boolean isHost() {
return (mDestination.getAddress() instanceof Inet4Address &&
- mDestination.getNetworkPrefixLength() == 32) ||
+ mDestination.getPrefixLength() == 32) ||
(mDestination.getAddress() instanceof Inet6Address &&
- mDestination.getNetworkPrefixLength() == 128);
+ mDestination.getPrefixLength() == 128);
}
private boolean isDefault() {
boolean val = false;
if (mGateway != null) {
if (mGateway instanceof Inet4Address) {
- val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0);
+ val = (mDestination == null || mDestination.getPrefixLength() == 0);
} else {
- val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0);
+ val = (mDestination == null || mDestination.getPrefixLength() == 0);
}
}
return val;
}
/**
- * Retrieves the destination address and prefix length in the form of a {@link LinkAddress}.
+ * Retrieves the destination address and prefix length in the form of an {@link IpPrefix}.
*
- * @return {@link LinkAddress} specifying the destination. This is never {@code null}.
+ * @return {@link IpPrefix} specifying the destination. This is never {@code null}.
*/
- public LinkAddress getDestination() {
+ public IpPrefix getDestination() {
+ return new IpPrefix(mDestination.getAddress(), mDestination.getPrefixLength());
+ }
+
+ /**
+ * TODO: Convert callers to use IpPrefix and then remove.
+ * @hide
+ */
+ public LinkAddress getDestinationLinkAddress() {
return mDestination;
}
@@ -233,7 +275,8 @@
/**
* Indicates if this route is a host route (ie, matches only a single host address).
*
- * @return {@code true} if the destination has a prefix length of 32/128 for v4/v6.
+ * @return {@code true} if the destination has a prefix length of 32 or 128 for IPv4 or IPv6,
+ * respectively.
* @hide
*/
public boolean isHostRoute() {
@@ -263,7 +306,7 @@
// match the route destination and destination with prefix length
InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
- mDestination.getNetworkPrefixLength());
+ mDestination.getPrefixLength());
return mDestination.getAddress().equals(dstNet);
}
@@ -285,8 +328,8 @@
for (RouteInfo route : routes) {
if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) {
if ((bestRoute != null) &&
- (bestRoute.mDestination.getNetworkPrefixLength() >=
- route.mDestination.getNetworkPrefixLength())) {
+ (bestRoute.mDestination.getPrefixLength() >=
+ route.mDestination.getPrefixLength())) {
continue;
}
if (route.matches(dest)) bestRoute = route;
@@ -295,13 +338,22 @@
return bestRoute;
}
+ /**
+ * Returns a human-readable description of this object.
+ */
public String toString() {
String val = "";
if (mDestination != null) val = mDestination.toString();
- if (mGateway != null) val += " -> " + mGateway.getHostAddress();
+ val += " ->";
+ if (mGateway != null) val += " " + mGateway.getHostAddress();
+ if (mInterface != null) val += " " + mInterface;
return val;
}
+ /**
+ * Compares this RouteInfo object against the specified object and indicates if they are equal.
+ * @return {@code true} if the objects are equal, {@code false} otherwise.
+ */
public boolean equals(Object obj) {
if (this == obj) return true;
@@ -309,11 +361,14 @@
RouteInfo target = (RouteInfo) obj;
- return Objects.equals(mDestination, target.getDestination()) &&
+ return Objects.equals(mDestination, target.getDestinationLinkAddress()) &&
Objects.equals(mGateway, target.getGateway()) &&
Objects.equals(mInterface, target.getInterface());
}
+ /**
+ * Returns a hashcode for this <code>RouteInfo</code> object.
+ */
public int hashCode() {
return (mDestination == null ? 0 : mDestination.hashCode() * 41)
+ (mGateway == null ? 0 :mGateway.hashCode() * 47)
@@ -323,7 +378,6 @@
/**
* Implement the Parcelable interface
- * @hide
*/
public int describeContents() {
return 0;
@@ -331,7 +385,6 @@
/**
* Implement the Parcelable interface
- * @hide
*/
public void writeToParcel(Parcel dest, int flags) {
if (mDestination == null) {
@@ -339,7 +392,7 @@
} else {
dest.writeByte((byte) 1);
dest.writeByteArray(mDestination.getAddress().getAddress());
- dest.writeInt(mDestination.getNetworkPrefixLength());
+ dest.writeInt(mDestination.getPrefixLength());
}
if (mGateway == null) {
@@ -354,7 +407,6 @@
/**
* Implement the Parcelable interface.
- * @hide
*/
public static final Creator<RouteInfo> CREATOR =
new Creator<RouteInfo>() {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bd988a6..55c66ba 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6029,6 +6029,7 @@
/**
* Battery level [1-99] at which low power mode automatically turns on.
+ * If 0, it will not automatically turn on.
* @hide
*/
public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level";
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index fd475cd..8bd0f4d 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -29,6 +29,7 @@
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.util.ArrayMap;
import android.util.Log;
import java.util.List;
@@ -54,7 +55,7 @@
+ "[" + getClass().getSimpleName() + "]";
private INotificationListenerWrapper mWrapper = null;
- private Ranking mRanking;
+ private RankingMap mRankingMap;
private INotificationManager mNoMan;
@@ -75,7 +76,22 @@
* object as well as its identifying information (tag and id) and source
* (package name).
*/
- public abstract void onNotificationPosted(StatusBarNotification sbn);
+ public void onNotificationPosted(StatusBarNotification sbn) {
+ // optional
+ }
+
+ /**
+ * Implement this method to learn about new notifications as they are posted by apps.
+ *
+ * @param sbn A data structure encapsulating the original {@link android.app.Notification}
+ * object as well as its identifying information (tag and id) and source
+ * (package name).
+ * @param rankingMap The current ranking map that can be used to retrieve ranking information
+ * for active notifications, including the newly posted one.
+ */
+ public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
+ onNotificationPosted(sbn);
+ }
/**
* Implement this method to learn when notifications are removed.
@@ -94,7 +110,33 @@
* and source (package name) used to post the {@link android.app.Notification} that
* was just removed.
*/
- public abstract void onNotificationRemoved(StatusBarNotification sbn);
+ public void onNotificationRemoved(StatusBarNotification sbn) {
+ // optional
+ }
+
+ /**
+ * Implement this method to learn when notifications are removed.
+ * <P>
+ * This might occur because the user has dismissed the notification using system UI (or another
+ * notification listener) or because the app has withdrawn the notification.
+ * <P>
+ * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
+ * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
+ * fields such as {@link android.app.Notification#contentView} and
+ * {@link android.app.Notification#largeIcon}. However, all other fields on
+ * {@link StatusBarNotification}, sufficient to match this call with a prior call to
+ * {@link #onNotificationPosted(StatusBarNotification)}, will be intact.
+ *
+ * @param sbn A data structure encapsulating at least the original information (tag and id)
+ * and source (package name) used to post the {@link android.app.Notification} that
+ * was just removed.
+ * @param rankingMap The current ranking map that can be used to retrieve ranking information
+ * for active notifications.
+ *
+ */
+ public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
+ onNotificationRemoved(sbn);
+ }
/**
* Implement this method to learn about when the listener is enabled and connected to
@@ -107,10 +149,11 @@
/**
* Implement this method to be notified when the notification ranking changes.
- * <P>
- * Call {@link #getCurrentRanking()} to retrieve the new ranking.
+ *
+ * @param rankingMap The current ranking map that can be used to retrieve ranking information
+ * for active notifications.
*/
- public void onNotificationRankingUpdate() {
+ public void onNotificationRankingUpdate(RankingMap rankingMap) {
// optional
}
@@ -241,16 +284,19 @@
*
* <p>
* The returned object represents the current ranking snapshot and only
- * applies for currently active notifications. Hence you must retrieve a
- * new Ranking after each notification event such as
- * {@link #onNotificationPosted(StatusBarNotification)},
- * {@link #onNotificationRemoved(StatusBarNotification)}, etc.
+ * applies for currently active notifications.
+ * <p>
+ * Generally you should use the RankingMap that is passed with events such
+ * as {@link #onNotificationPosted(StatusBarNotification, RankingMap)},
+ * {@link #onNotificationRemoved(StatusBarNotification, RankingMap)}, and
+ * so on. This method should only be used when needing access outside of
+ * such events, for example to retrieve the RankingMap right after
+ * initialization.
*
- * @return A {@link NotificationListenerService.Ranking} object providing
- * access to ranking information
+ * @return A {@link RankingMap} object providing access to ranking information
*/
- public Ranking getCurrentRanking() {
- return mRanking;
+ public RankingMap getCurrentRanking() {
+ return mRankingMap;
}
@Override
@@ -313,7 +359,7 @@
synchronized (mWrapper) {
applyUpdate(update);
try {
- NotificationListenerService.this.onNotificationPosted(sbn);
+ NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap);
} catch (Throwable t) {
Log.w(TAG, "Error running onNotificationPosted", t);
}
@@ -326,7 +372,7 @@
synchronized (mWrapper) {
applyUpdate(update);
try {
- NotificationListenerService.this.onNotificationRemoved(sbn);
+ NotificationListenerService.this.onNotificationRemoved(sbn, mRankingMap);
} catch (Throwable t) {
Log.w(TAG, "Error running onNotificationRemoved", t);
}
@@ -351,7 +397,7 @@
synchronized (mWrapper) {
applyUpdate(update);
try {
- NotificationListenerService.this.onNotificationRankingUpdate();
+ NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap);
} catch (Throwable t) {
Log.w(TAG, "Error running onNotificationRankingUpdate", t);
}
@@ -360,7 +406,65 @@
}
private void applyUpdate(NotificationRankingUpdate update) {
- mRanking = new Ranking(update);
+ mRankingMap = new RankingMap(update);
+ }
+
+ /**
+ * Provides access to ranking information on a currently active
+ * notification.
+ *
+ * <p>
+ * Note that this object is not updated on notification events (such as
+ * {@link #onNotificationPosted(StatusBarNotification, RankingMap)},
+ * {@link #onNotificationRemoved(StatusBarNotification)}, etc.). Make sure
+ * to retrieve a new Ranking from the current {@link RankingMap} whenever
+ * a notification event occurs.
+ */
+ public static class Ranking {
+ private final String mKey;
+ private final int mRank;
+ private final boolean mIsAmbient;
+ private final boolean mIsInterceptedByDnd;
+
+ private Ranking(String key, int rank, boolean isAmbient, boolean isInterceptedByDnd) {
+ mKey = key;
+ mRank = rank;
+ mIsAmbient = isAmbient;
+ mIsInterceptedByDnd = isInterceptedByDnd;
+ }
+
+ /**
+ * Returns the key of the notification this Ranking applies to.
+ */
+ public String getKey() {
+ return mKey;
+ }
+
+ /**
+ * Returns the rank of the notification.
+ *
+ * @return the rank of the notification, that is the 0-based index in
+ * the list of active notifications.
+ */
+ public int getRank() {
+ return mRank;
+ }
+
+ /**
+ * Returns whether the notification is an ambient notification, that is
+ * a notification that doesn't require the user's immediate attention.
+ */
+ public boolean isAmbient() {
+ return mIsAmbient;
+ }
+
+ /**
+ * Returns whether the notification was intercepted by
+ * "Do not disturb".
+ */
+ public boolean isInterceptedByDoNotDisturb() {
+ return mIsInterceptedByDnd;
+ }
}
/**
@@ -371,11 +475,14 @@
* Note that this object represents a ranking snapshot that only applies to
* notifications active at the time of retrieval.
*/
- public static class Ranking implements Parcelable {
+ public static class RankingMap implements Parcelable {
private final NotificationRankingUpdate mRankingUpdate;
+ private final ArrayMap<String, Ranking> mRankingCache;
+ private boolean mRankingCacheInitialized;
- private Ranking(NotificationRankingUpdate rankingUpdate) {
+ private RankingMap(NotificationRankingUpdate rankingUpdate) {
mRankingUpdate = rankingUpdate;
+ mRankingCache = new ArrayMap<>(rankingUpdate.getOrderedKeys().length);
}
/**
@@ -389,56 +496,37 @@
}
/**
- * Returns the rank of the notification with the given key, that is the
- * index of <code>key</code> in the array of keys returned by
- * {@link #getOrderedKeys()}.
+ * Returns the Ranking for the notification with the given key.
*
- * @return The rank of the notification with the given key; -1 when the
- * given key is unknown.
+ * @return the Ranking of the notification with the given key;
+ * <code>null</code> when the key is unknown.
*/
- public int getRank(String key) {
- // TODO: Optimize.
+ public Ranking getRanking(String key) {
+ synchronized (mRankingCache) {
+ if (!mRankingCacheInitialized) {
+ initializeRankingCache();
+ mRankingCacheInitialized = true;
+ }
+ }
+ return mRankingCache.get(key);
+ }
+
+ private void initializeRankingCache() {
String[] orderedKeys = mRankingUpdate.getOrderedKeys();
- for (int i = 0; i < orderedKeys.length; i++) {
- if (orderedKeys[i].equals(key)) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Returns whether the notification with the given key was intercepted
- * by "Do not disturb".
- */
- public boolean isInterceptedByDoNotDisturb(String key) {
- // TODO: Optimize.
- for (String interceptedKey : mRankingUpdate.getDndInterceptedKeys()) {
- if (interceptedKey.equals(key)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns whether the notification with the given key is an ambient
- * notification, that is a notification that doesn't require the user's
- * immediate attention.
- */
- public boolean isAmbient(String key) {
- // TODO: Optimize.
int firstAmbientIndex = mRankingUpdate.getFirstAmbientIndex();
- if (firstAmbientIndex < 0) {
- return false;
- }
- String[] orderedKeys = mRankingUpdate.getOrderedKeys();
- for (int i = firstAmbientIndex; i < orderedKeys.length; i++) {
- if (orderedKeys[i].equals(key)) {
- return true;
+ for (int i = 0; i < orderedKeys.length; i++) {
+ String key = orderedKeys[i];
+ boolean isAmbient = firstAmbientIndex > -1 && firstAmbientIndex <= i;
+ boolean isInterceptedByDnd = false;
+ // TODO: Optimize.
+ for (String s : mRankingUpdate.getDndInterceptedKeys()) {
+ if (s.equals(key)) {
+ isInterceptedByDnd = true;
+ break;
+ }
}
+ mRankingCache.put(key, new Ranking(key, i, isAmbient, isInterceptedByDnd));
}
- return false;
}
// ----------- Parcelable
@@ -453,16 +541,16 @@
dest.writeParcelable(mRankingUpdate, flags);
}
- public static final Creator<Ranking> CREATOR = new Creator<Ranking>() {
+ public static final Creator<RankingMap> CREATOR = new Creator<RankingMap>() {
@Override
- public Ranking createFromParcel(Parcel source) {
+ public RankingMap createFromParcel(Parcel source) {
NotificationRankingUpdate rankingUpdate = source.readParcelable(null);
- return new Ranking(rankingUpdate);
+ return new RankingMap(rankingUpdate);
}
@Override
- public Ranking[] newArray(int size) {
- return new Ranking[size];
+ public RankingMap[] newArray(int size) {
+ return new RankingMap[size];
}
};
}
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index f440853..1d9aa05 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -440,26 +440,10 @@
}
// Documentation from interface
- public SpannableStringBuilder replace(int start, int end,
+ public SpannableStringBuilder replace(final int start, final int end,
CharSequence tb, int tbstart, int tbend) {
checkRange("replace", start, end);
- // Sanity check
- if (start > end) {
- Log.w(TAG, "Bad arguments to #replace : "
- + "start = " + start + ", end = " + end);
- final int tmp = start;
- start = end;
- end = tmp;
- }
- if (tbstart > tbend) {
- Log.w(TAG, "Bad arguments to #replace : "
- + "tbstart = " + tbstart + ", tbend = " + tbend);
- final int tmp = tbstart;
- tbstart = tbend;
- tbend = tmp;
- }
-
int filtercount = mFilters.length;
for (int i = 0; i < filtercount; i++) {
CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end);
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 11db996..72b9d3e 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -74,7 +74,8 @@
private boolean mProfilingEnabled;
ThreadedRenderer(boolean translucent) {
- AtlasInitializer.sInstance.init();
+ // Temporarily disabled
+ //AtlasInitializer.sInstance.init();
long rootNodePtr = nCreateRootRenderNode();
mRootNode = RenderNode.adopt(rootNodePtr);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 117fe8e..7c70ee4 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6105,7 +6105,7 @@
// apply insets path and take things from there.
try {
mPrivateFlags3 |= PFLAG3_FITTING_SYSTEM_WINDOWS;
- return !dispatchApplyWindowInsets(new WindowInsets(insets)).hasInsets();
+ return dispatchApplyWindowInsets(new WindowInsets(insets)).isConsumed();
} finally {
mPrivateFlags3 &= ~PFLAG3_FITTING_SYSTEM_WINDOWS;
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 0f40ee7..eef09ae 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5574,11 +5574,11 @@
@Override
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
insets = super.dispatchApplyWindowInsets(insets);
- if (insets.hasInsets()) {
+ if (!insets.isConsumed()) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
insets = getChildAt(i).dispatchApplyWindowInsets(insets);
- if (!insets.hasInsets()) {
+ if (insets.isConsumed()) {
break;
}
}
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 294f472..3a1e826 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -35,6 +35,9 @@
private Rect mTempRect;
private boolean mIsRound;
+ private boolean mSystemWindowInsetsConsumed = false;
+ private boolean mWindowDecorInsetsConsumed = false;
+
private static final Rect EMPTY_RECT = new Rect(0, 0, 0, 0);
/**
@@ -52,13 +55,17 @@
/** @hide */
public WindowInsets(Rect systemWindowInsets, boolean isRound) {
- this(systemWindowInsets, EMPTY_RECT, isRound);
+ this(systemWindowInsets, null, isRound);
}
/** @hide */
public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, boolean isRound) {
- mSystemWindowInsets = systemWindowInsets;
- mWindowDecorInsets = windowDecorInsets;
+ mSystemWindowInsetsConsumed = systemWindowInsets == null;
+ mSystemWindowInsets = mSystemWindowInsetsConsumed ? EMPTY_RECT : systemWindowInsets;
+
+ mWindowDecorInsetsConsumed = windowDecorInsets == null;
+ mWindowDecorInsets = mWindowDecorInsetsConsumed ? EMPTY_RECT : windowDecorInsets;
+
mIsRound = isRound;
}
@@ -70,12 +77,14 @@
public WindowInsets(WindowInsets src) {
mSystemWindowInsets = src.mSystemWindowInsets;
mWindowDecorInsets = src.mWindowDecorInsets;
+ mSystemWindowInsetsConsumed = src.mSystemWindowInsetsConsumed;
+ mWindowDecorInsetsConsumed = src.mWindowDecorInsetsConsumed;
mIsRound = src.mIsRound;
}
/** @hide */
public WindowInsets(Rect systemWindowInsets) {
- this(systemWindowInsets, EMPTY_RECT);
+ this(systemWindowInsets, null);
}
/**
@@ -238,6 +247,24 @@
}
/**
+ * Check if these insets have been fully consumed.
+ *
+ * <p>Insets are considered "consumed" if the applicable <code>consume*</code> methods
+ * have been called such that all insets have been set to zero. This affects propagation of
+ * insets through the view hierarchy; insets that have not been fully consumed will continue
+ * to propagate down to child views.</p>
+ *
+ * <p>The result of this method is equivalent to the return value of
+ * {@link View#fitSystemWindows(android.graphics.Rect)}.</p>
+ *
+ * @return true if the insets have been fully consumed.
+ * @hide Pending API
+ */
+ public boolean isConsumed() {
+ return mSystemWindowInsetsConsumed && mWindowDecorInsetsConsumed;
+ }
+
+ /**
* Returns true if the associated window has a round shape.
*
* <p>A round window's left, top, right and bottom edges reach all the way to the
@@ -258,7 +285,8 @@
*/
public WindowInsets consumeSystemWindowInsets() {
final WindowInsets result = new WindowInsets(this);
- result.mSystemWindowInsets = new Rect(0, 0, 0, 0);
+ result.mSystemWindowInsets = EMPTY_RECT;
+ result.mSystemWindowInsetsConsumed = true;
return result;
}
@@ -276,10 +304,12 @@
boolean right, boolean bottom) {
if (left || top || right || bottom) {
final WindowInsets result = new WindowInsets(this);
- result.mSystemWindowInsets = new Rect(left ? 0 : mSystemWindowInsets.left,
+ result.mSystemWindowInsets = new Rect(
+ left ? 0 : mSystemWindowInsets.left,
top ? 0 : mSystemWindowInsets.top,
right ? 0 : mSystemWindowInsets.right,
bottom ? 0 : mSystemWindowInsets.bottom);
+ result.mSystemWindowInsetsConsumed = !hasSystemWindowInsets();
return result;
}
return this;
@@ -299,6 +329,7 @@
int right, int bottom) {
final WindowInsets result = new WindowInsets(this);
result.mSystemWindowInsets = new Rect(left, top, right, bottom);
+ result.mSystemWindowInsetsConsumed = !hasSystemWindowInsets();
return result;
}
@@ -308,6 +339,7 @@
public WindowInsets consumeWindowDecorInsets() {
final WindowInsets result = new WindowInsets(this);
result.mWindowDecorInsets.set(0, 0, 0, 0);
+ result.mWindowDecorInsetsConsumed = true;
return result;
}
@@ -322,6 +354,7 @@
top ? 0 : mWindowDecorInsets.top,
right ? 0 : mWindowDecorInsets.right,
bottom ? 0 : mWindowDecorInsets.bottom);
+ result.mWindowDecorInsetsConsumed = !hasWindowDecorInsets();
return result;
}
return this;
@@ -333,6 +366,7 @@
public WindowInsets replaceWindowDecorInsets(int left, int top, int right, int bottom) {
final WindowInsets result = new WindowInsets(this);
result.mWindowDecorInsets = new Rect(left, top, right, bottom);
+ result.mWindowDecorInsetsConsumed = !hasWindowDecorInsets();
return result;
}
diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java
index fad6747..66f5f6c 100644
--- a/core/java/android/view/inputmethod/CursorAnchorInfo.java
+++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -186,12 +186,12 @@
/**
* Builder for {@link CursorAnchorInfo}. This class is not designed to be thread-safe.
*/
- public static final class CursorAnchorInfoBuilder {
+ public static final class Builder {
/**
* Sets the text range of the selection. Calling this can be skipped if there is no
* selection.
*/
- public CursorAnchorInfoBuilder setSelectionRange(final int newStart, final int newEnd) {
+ public Builder setSelectionRange(final int newStart, final int newEnd) {
mSelectionStart = newStart;
mSelectionEnd = newEnd;
return this;
@@ -205,8 +205,7 @@
* @param index index where the composing text starts.
* @param composingText the entire composing text.
*/
- public CursorAnchorInfoBuilder setComposingText(final int index,
- final CharSequence composingText) {
+ public Builder setComposingText(final int index, final CharSequence composingText) {
mComposingTextStart = index;
if (composingText == null) {
mComposingText = null;
@@ -236,9 +235,8 @@
* that will be transformed with the transformation matrix when rendered on the screen. This
* should be calculated or compatible with {@link Layout#getLineBottom(int)}.
*/
- public CursorAnchorInfoBuilder setInsertionMarkerLocation(
- final float horizontalPosition, final float lineTop, final float lineBaseline,
- final float lineBottom){
+ public Builder setInsertionMarkerLocation(final float horizontalPosition,
+ final float lineTop, final float lineBaseline, final float lineBottom){
mInsertionMarkerHorizontal = horizontalPosition;
mInsertionMarkerTop = lineTop;
mInsertionMarkerBaseline = lineBaseline;
@@ -269,9 +267,8 @@
* @throws IllegalArgumentException If the index is a negative value, or not greater than
* all of the previously called indices.
*/
- public CursorAnchorInfoBuilder addCharacterRect(final int index,
- final float leadingEdgeX, final float leadingEdgeY, final float trailingEdgeX,
- final float trailingEdgeY) {
+ public Builder addCharacterRect(final int index, final float leadingEdgeX,
+ final float leadingEdgeY, final float trailingEdgeX, final float trailingEdgeY) {
if (index < 0) {
throw new IllegalArgumentException("index must not be a negative integer.");
}
@@ -289,7 +286,7 @@
* @param matrix transformation matrix from local coordinates into screen coordinates. null
* is interpreted as an identity matrix.
*/
- public CursorAnchorInfoBuilder setMatrix(final Matrix matrix) {
+ public Builder setMatrix(final Matrix matrix) {
mMatrix.set(matrix != null ? matrix : Matrix.IDENTITY_MATRIX);
return this;
}
@@ -297,7 +294,7 @@
/**
* @return {@link CursorAnchorInfo} using parameters in this
- * {@link CursorAnchorInfoBuilder}.
+ * {@link Builder}.
*/
public CursorAnchorInfo build() {
return new CursorAnchorInfo(this);
@@ -323,7 +320,7 @@
}
}
- private CursorAnchorInfo(final CursorAnchorInfoBuilder builder) {
+ private CursorAnchorInfo(final Builder builder) {
mSelectionStart = builder.mSelectionStart;
mSelectionEnd = builder.mSelectionEnd;
mComposingTextStart = builder.mComposingTextStart;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 27d6b82..4467128 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -96,7 +96,6 @@
import android.view.WindowManager;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.CursorAnchorInfo;
-import android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
@@ -3013,7 +3012,7 @@
* {@link InputMethodManager#isWatchingCursor(View)} returns false.
*/
private final class CursorAnchorInfoNotifier implements TextViewPositionListener {
- final CursorAnchorInfoBuilder mSelectionInfoBuilder = new CursorAnchorInfoBuilder();
+ final CursorAnchorInfo.Builder mSelectionInfoBuilder = new CursorAnchorInfo.Builder();
final int[] mTmpIntOffset = new int[2];
final Matrix mViewToScreenMatrix = new Matrix();
@@ -3037,7 +3036,7 @@
return;
}
- final CursorAnchorInfoBuilder builder = mSelectionInfoBuilder;
+ final CursorAnchorInfo.Builder builder = mSelectionInfoBuilder;
builder.reset();
final int selectionStart = mTextView.getSelectionStart();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 43c8dde..84202eb 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5842,7 +5842,6 @@
int end = text.partialEndOffset;
if (end > N) end = N;
removeParcelableSpans(content, start, end);
- // If start > end, content.replace will swap them before using them.
content.replace(start, end, text.text);
}
}
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index cbd9a6a..4f1cd68 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -146,6 +146,8 @@
private ActionMenuPresenter mOuterActionMenuPresenter;
private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
+ private boolean mCollapsible;
+
public Toolbar(Context context) {
this(context, null);
}
@@ -969,6 +971,23 @@
return child.getMeasuredWidth() + hMargins;
}
+ /**
+ * Returns true if the Toolbar is collapsible and has no child views with a measured size > 0.
+ */
+ private boolean shouldCollapse() {
+ if (!mCollapsible) return false;
+
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ final View child = getChildAt(i);
+ if (shouldLayout(child) && child.getMeasuredWidth() > 0 &&
+ child.getMeasuredHeight() > 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = 0;
@@ -1093,7 +1112,8 @@
final int measuredHeight = resolveSizeAndState(
Math.max(height, getSuggestedMinimumHeight()),
heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT);
- setMeasuredDimension(measuredWidth, measuredHeight);
+
+ setMeasuredDimension(measuredWidth, shouldCollapse() ? 0 : measuredHeight);
}
@Override
@@ -1490,6 +1510,16 @@
}
/**
+ * Force the toolbar to collapse to zero-height during measurement if
+ * it could be considered "empty" (no visible elements with nonzero measured size)
+ * @hide
+ */
+ public void setCollapsible(boolean collapsible) {
+ mCollapsible = collapsible;
+ requestLayout();
+ }
+
+ /**
* Interface responsible for receiving menu item click events if the items themselves
* do not have individual item click listeners.
*/
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
index b298d85..bed0b88 100644
--- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -424,7 +424,7 @@
@Override
public void setCollapsible(boolean collapsible) {
- // Ignore
+ mToolbar.setCollapsible(collapsible);
}
@Override
@@ -569,7 +569,7 @@
@Override
public void setNavigationIcon(int resId) {
- setNavigationIcon(mToolbar.getContext().getDrawable(resId));
+ setNavigationIcon(resId != 0 ? mToolbar.getContext().getDrawable(resId) : null);
}
@Override
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 8e56eec..432a615 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -828,13 +828,12 @@
: layout(layout), canvas(canvas), x(x), y(y), paint(paint), glyphs(glyphs),
pos(pos) { }
- void operator()(SkTypeface* t, size_t start, size_t end) {
+ void operator()(size_t start, size_t end) {
for (size_t i = start; i < end; i++) {
glyphs[i] = layout.getGlyphId(i);
pos[i].fX = x + layout.getX(i);
pos[i].fY = y + layout.getY(i);
}
- paint->setTypeface(t);
canvas->drawPosText(glyphs + start, (end - start) << 1, pos + start, *paint);
}
private:
@@ -857,7 +856,7 @@
paint->setTextAlign(SkPaint::kLeft_Align);
paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
DrawTextFunctor f(layout, canvas, x, y, paint, glyphs, pos);
- MinikinUtils::forFontRun(layout, f);
+ MinikinUtils::forFontRun(layout, paint, f);
doDrawTextDecorations(canvas, x, y, layout.getAdvance(), paint);
paint->setTextAlign(align);
delete[] glyphs;
diff --git a/core/jni/android/graphics/MinikinSkia.cpp b/core/jni/android/graphics/MinikinSkia.cpp
index 2b96f1b..25eb941 100644
--- a/core/jni/android/graphics/MinikinSkia.cpp
+++ b/core/jni/android/graphics/MinikinSkia.cpp
@@ -43,13 +43,14 @@
return !!glyph;
}
-static void MinikinFontSkia_SetSkiaPaint(SkTypeface* typeface, SkPaint* skPaint, const MinikinPaint& paint) {
- skPaint->setTypeface(typeface);
+static void MinikinFontSkia_SetSkiaPaint(const MinikinFont* font, SkPaint* skPaint, const MinikinPaint& paint) {
skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
skPaint->setTextSize(paint.size);
skPaint->setTextScaleX(paint.scaleX);
skPaint->setTextSkewX(paint.skewX);
MinikinFontSkia::unpackPaintFlags(skPaint, paint.paintFlags);
+ // Apply font fakery on top of user-supplied flags.
+ MinikinFontSkia::populateSkPaint(skPaint, font, paint.fakery);
}
float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
@@ -57,7 +58,7 @@
SkPaint skPaint;
uint16_t glyph16 = glyph_id;
SkScalar skWidth;
- MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
+ MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint);
skPaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, NULL);
#ifdef VERBOSE
ALOGD("width for typeface %d glyph %d = %f", mTypeface->uniqueID(), glyph_id, skWidth);
@@ -70,7 +71,7 @@
SkPaint skPaint;
uint16_t glyph16 = glyph_id;
SkRect skBounds;
- MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
+ MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint);
skPaint.getTextWidths(&glyph16, sizeof(glyph16), NULL, &skBounds);
bounds->mLeft = skBounds.fLeft;
bounds->mTop = skBounds.fTop;
@@ -90,7 +91,7 @@
}
}
-SkTypeface *MinikinFontSkia::GetSkTypeface() {
+SkTypeface *MinikinFontSkia::GetSkTypeface() const {
return mTypeface;
}
@@ -115,4 +116,12 @@
paint->setHinting(static_cast<SkPaint::Hinting>(paintFlags >> 16));
}
+void MinikinFontSkia::populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery) {
+ paint->setTypeface(reinterpret_cast<const MinikinFontSkia*>(font)->GetSkTypeface());
+ paint->setFakeBoldText(paint->isFakeBoldText() || fakery.isFakeBold());
+ if (fakery.isFakeItalic()) {
+ paint->setTextSkewX(paint->getTextSkewX() - 0.25f);
+ }
+}
+
}
diff --git a/core/jni/android/graphics/MinikinSkia.h b/core/jni/android/graphics/MinikinSkia.h
index 0452c57..ac4d2a0 100644
--- a/core/jni/android/graphics/MinikinSkia.h
+++ b/core/jni/android/graphics/MinikinSkia.h
@@ -36,10 +36,13 @@
int32_t GetUniqueId() const;
- SkTypeface *GetSkTypeface();
+ SkTypeface* GetSkTypeface() const;
static uint32_t packPaintFlags(const SkPaint* paint);
static void unpackPaintFlags(SkPaint* paint, uint32_t paintFlags);
+
+ // set typeface and fake bold/italic parameters
+ static void populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery);
private:
SkTypeface *mTypeface;
};
diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h
index ea7eb5d..a96c6b1 100644
--- a/core/jni/android/graphics/MinikinUtils.h
+++ b/core/jni/android/graphics/MinikinUtils.h
@@ -36,23 +36,30 @@
static float xOffsetForTextAlign(SkPaint* paint, const Layout& layout);
- // f is a functor of type void f(SkTypeface *, size_t start, size_t end);
+ // f is a functor of type void f(size_t start, size_t end);
template <typename F>
- static void forFontRun(const Layout& layout, F& f) {
- SkTypeface* lastFace = NULL;
+ static void forFontRun(const Layout& layout, SkPaint* paint, F& f) {
+ float saveSkewX = paint->getTextSkewX();
+ bool savefakeBold = paint->isFakeBoldText();
+ MinikinFont* curFont = NULL;
size_t start = 0;
size_t nGlyphs = layout.nGlyphs();
for (size_t i = 0; i < nGlyphs; i++) {
- MinikinFontSkia* mfs = static_cast<MinikinFontSkia*>(layout.getFont(i));
- SkTypeface* skFace = mfs->GetSkTypeface();
- if (i > 0 && skFace != lastFace) {
- f(lastFace, start, i);
+ MinikinFont* nextFont = layout.getFont(i);
+ if (i > 0 && nextFont != curFont) {
+ MinikinFontSkia::populateSkPaint(paint, curFont, layout.getFakery(start));
+ f(start, i);
+ paint->setTextSkewX(saveSkewX);
+ paint->setFakeBoldText(savefakeBold);
start = i;
}
- lastFace = skFace;
+ curFont = nextFont;
}
if (nGlyphs > start) {
- f(lastFace, start, nGlyphs);
+ MinikinFontSkia::populateSkPaint(paint, curFont, layout.getFakery(start));
+ f(start, nGlyphs);
+ paint->setTextSkewX(saveSkewX);
+ paint->setFakeBoldText(savefakeBold);
}
}
};
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 3dc874e..8b11d31 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -429,27 +429,29 @@
GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(skewX);
}
- static jfloat ascent(JNIEnv* env, jobject paint) {
- NPE_CHECK_RETURN_ZERO(env, paint);
- SkPaint::FontMetrics metrics;
- (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
- return SkScalarToFloat(metrics.fAscent);
- }
-
- static jfloat descent(JNIEnv* env, jobject paint) {
- NPE_CHECK_RETURN_ZERO(env, paint);
- SkPaint::FontMetrics metrics;
- (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
- return SkScalarToFloat(metrics.fDescent);
- }
-
- static SkScalar getMetricsInternal(SkPaint *paint, SkPaint::FontMetrics *metrics) {
+ static SkScalar getMetricsInternal(JNIEnv* env, jobject jpaint, SkPaint::FontMetrics *metrics) {
const int kElegantTop = 2500;
const int kElegantBottom = -1000;
- const int kElegantAscent = 1946;
- const int kElegantDescent = -512;
+ const int kElegantAscent = 1900;
+ const int kElegantDescent = -500;
const int kElegantLeading = 0;
+ SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
+#ifdef USE_MINIKIN
+ TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
+ typeface = TypefaceImpl_resolveDefault(typeface);
+ FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle);
+ float saveSkewX = paint->getTextSkewX();
+ bool savefakeBold = paint->isFakeBoldText();
+ MinikinFontSkia::populateSkPaint(paint, baseFont.font, baseFont.fakery);
+#endif
SkScalar spacing = paint->getFontMetrics(metrics);
+#ifdef USE_MINIKIN
+ // The populateSkPaint call may have changed fake bold / text skew
+ // because we want to measure with those effects applied, so now
+ // restore the original settings.
+ paint->setTextSkewX(saveSkewX);
+ paint->setFakeBoldText(savefakeBold);
+#endif
SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
if (paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant) {
SkScalar size = paint->getTextSize();
@@ -463,10 +465,24 @@
return spacing;
}
+ static jfloat ascent(JNIEnv* env, jobject paint) {
+ NPE_CHECK_RETURN_ZERO(env, paint);
+ SkPaint::FontMetrics metrics;
+ getMetricsInternal(env, paint, &metrics);
+ return SkScalarToFloat(metrics.fAscent);
+ }
+
+ static jfloat descent(JNIEnv* env, jobject paint) {
+ NPE_CHECK_RETURN_ZERO(env, paint);
+ SkPaint::FontMetrics metrics;
+ getMetricsInternal(env, paint, &metrics);
+ return SkScalarToFloat(metrics.fDescent);
+ }
+
static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
NPE_CHECK_RETURN_ZERO(env, paint);
SkPaint::FontMetrics metrics;
- SkScalar spacing = getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
+ SkScalar spacing = getMetricsInternal(env, paint, &metrics);
if (metricsObj) {
SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class));
@@ -483,7 +499,7 @@
NPE_CHECK_RETURN_ZERO(env, paint);
SkPaint::FontMetrics metrics;
- getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
+ getMetricsInternal(env, paint, &metrics);
int ascent = SkScalarRoundToInt(metrics.fAscent);
int descent = SkScalarRoundToInt(metrics.fDescent);
int leading = SkScalarRoundToInt(metrics.fLeading);
@@ -830,13 +846,12 @@
: layout(layout), path(path), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) {
}
- void operator()(SkTypeface* t, size_t start, size_t end) {
+ void operator()(size_t start, size_t end) {
for (size_t i = start; i < end; i++) {
glyphs[i] = layout.getGlyphId(i);
pos[i].fX = x + layout.getX(i);
pos[i].fY = y + layout.getY(i);
}
- paint->setTypeface(t);
if (start == 0) {
paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, path);
} else {
@@ -871,7 +886,7 @@
paint->setTextAlign(SkPaint::kLeft_Align);
paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
GetTextFunctor f(layout, path, x, y, paint, glyphs, pos);
- MinikinUtils::forFontRun(layout, f);
+ MinikinUtils::forFontRun(layout, paint, f);
paint->setTextAlign(align);
delete[] glyphs;
delete[] pos;
diff --git a/core/jni/android/graphics/TypefaceImpl.cpp b/core/jni/android/graphics/TypefaceImpl.cpp
index 27df7cf..1800d0c 100644
--- a/core/jni/android/graphics/TypefaceImpl.cpp
+++ b/core/jni/android/graphics/TypefaceImpl.cpp
@@ -173,7 +173,7 @@
} else {
const FontStyle defaultStyle;
FontFamily* firstFamily = reinterpret_cast<FontFamily*>(families[0]);
- MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle);
+ MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle).font;
SkTypeface* skTypeface = reinterpret_cast<MinikinFontSkia*>(mf)->GetSkTypeface();
// TODO: probably better to query more precise style from family, will be important
// when we open up API to access 100..900 weights
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index a46ccd6..d032cb6 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -656,13 +656,12 @@
uirenderer::Rect& bounds)
: layout(layout), renderer(renderer), x(x), y(y), paint(paint), glyphs(glyphs),
pos(pos), totalAdvance(totalAdvance), bounds(bounds) { }
- void operator()(SkTypeface* t, size_t start, size_t end) {
+ void operator()(size_t start, size_t end) {
for (size_t i = start; i < end; i++) {
glyphs[i] = layout.getGlyphId(i);
pos[2 * i] = layout.getX(i);
pos[2 * i + 1] = layout.getY(i);
}
- paint->setTypeface(t);
size_t glyphsCount = end - start;
int bytesCount = glyphsCount * sizeof(jchar);
renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount,
@@ -692,7 +691,7 @@
float totalAdvance = layout->getAdvance();
RenderTextFunctor f(*layout, renderer, x, y, paint, glyphs, pos, totalAdvance, bounds);
- MinikinUtils::forFontRun(*layout, f);
+ MinikinUtils::forFontRun(*layout, paint, f);
delete[] glyphs;
delete[] pos;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8768779..c5fd83d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2688,7 +2688,8 @@
android:theme="@style/Theme.Holo.Dialog.Alert"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true"
- android:multiprocess="true">
+ android:multiprocess="true"
+ android:documentLaunchMode="never">
<intent-filter>
<action android:name="android.intent.action.CHOOSER" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/core/res/res/drawable-hdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-hdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..0c3c3b4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-mdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..8322ae3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-xhdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..e6c0047
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-xxhdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..bb9debb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable/dialog_background_shadow_material.xml b/core/res/res/drawable/dialog_background_shadow_material.xml
new file mode 100644
index 0000000..0554920
--- /dev/null
+++ b/core/res/res/drawable/dialog_background_shadow_material.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/dialog_background_mtrl_mult"
+ android:tint="?attr/colorBackground"
+ android:tintMode="multiply" />
diff --git a/core/res/res/layout/dialog_custom_title_material.xml b/core/res/res/layout/dialog_custom_title_material.xml
index 1bb93eb..550b72e 100644
--- a/core/res/res/layout/dialog_custom_title_material.xml
+++ b/core/res/res/layout/dialog_custom_title_material.xml
@@ -23,6 +23,7 @@
android:fitsSystemWindows="true">
<FrameLayout android:id="@android:id/title_container"
android:layout_width="match_parent"
+ android:layout_height="?android:attr/windowTitleSize"
android:layout_weight="0"
android:gravity="center_vertical|start"
style="?android:attr/windowTitleBackgroundStyle" />
diff --git a/core/res/res/layout/dialog_title_material.xml b/core/res/res/layout/dialog_title_material.xml
index b92c1e7..918c8f1 100644
--- a/core/res/res/layout/dialog_title_material.xml
+++ b/core/res/res/layout/dialog_title_material.xml
@@ -22,7 +22,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:fitsSystemWindows="true">
- <TextView android:id="@+id/alertTitle"
+ <TextView android:id="@+id/title"
style="?android:attr/windowTitleStyle"
android:singleLine="true"
android:ellipsize="end"
diff --git a/core/res/res/layout/preference_material.xml b/core/res/res/layout/preference_material.xml
index a4fe73d..a9599139 100644
--- a/core/res/res/layout/preference_material.xml
+++ b/core/res/res/layout/preference_material.xml
@@ -31,7 +31,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minWidth="58dip"
- android:gravity="left|center_vertical"
+ android:gravity="start|center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+android:id/icon"
diff --git a/core/res/res/values-large/themes.xml b/core/res/res/values-large/themes.xml
deleted file mode 100644
index 8c8f86c..0000000
--- a/core/res/res/values-large/themes.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2010, 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.
-*/
--->
-
-<!--
-===============================================================
- PLEASE READ
-===============================================================
-
-The Holo themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see themes_device_defaults.xml.
-
-===============================================================
- PLEASE READ
-===============================================================
- -->
-<resources>
- <style name="Theme.Holo.DialogWhenLarge"
- parent="@android:style/Theme.Holo.Dialog.FixedSize">
- <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
- </style>
- <style name="Theme.Holo.DialogWhenLarge.NoActionBar"
- parent="@android:style/Theme.Holo.Dialog.NoActionBar.FixedSize">
- <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
- </style>
- <style name="Theme.Holo.Light.DialogWhenLarge"
- parent="@android:style/Theme.Holo.Light.Dialog.FixedSize">
- </style>
- <style name="Theme.Holo.Light.DialogWhenLarge.NoActionBar"
- parent="@android:style/Theme.Holo.Light.Dialog.NoActionBar.FixedSize">
- </style>
-
- <style name="Theme.Material.DialogWhenLarge"
- parent="@android:style/Theme.Material.Dialog.FixedSize">
- <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
- </style>
- <style name="Theme.Material.DialogWhenLarge.NoActionBar"
- parent="@android:style/Theme.Material.Dialog.NoActionBar.FixedSize">
- <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
- </style>
- <style name="Theme.Material.Light.DialogWhenLarge"
- parent="@android:style/Theme.Material.Light.Dialog.FixedSize">
- </style>
- <style name="Theme.Material.Light.DialogWhenLarge.NoActionBar"
- parent="@android:style/Theme.Material.Light.Dialog.NoActionBar.FixedSize">
- </style>
-</resources>
diff --git a/core/res/res/values-large/themes_device_defaults.xml b/core/res/res/values-large/themes_device_defaults.xml
index d57e827..d252c27 100644
--- a/core/res/res/values-large/themes_device_defaults.xml
+++ b/core/res/res/values-large/themes_device_defaults.xml
@@ -31,18 +31,12 @@
===============================================================
-->
<resources>
- <style name="Theme.DeviceDefault.DialogWhenLarge"
- parent="@android:style/Theme.DeviceDefault.Dialog.FixedSize">
+ <style name="Theme.DeviceDefault.DialogWhenLarge" parent="@style/Theme.DeviceDefault.Dialog.FixedSize">
<item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
</style>
- <style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar"
- parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar.FixedSize">
+ <style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar" parent="@style/Theme.DeviceDefault.Dialog.NoActionBar.FixedSize">
<item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
</style>
- <style name="Theme.DeviceDefault.Light.DialogWhenLarge"
- parent="@android:style/Theme.DeviceDefault.Light.Dialog.FixedSize">
- </style>
- <style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar"
- parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar.FixedSize">
- </style>
+ <style name="Theme.DeviceDefault.Light.DialogWhenLarge" parent="@style/Theme.DeviceDefault.Light.Dialog.FixedSize" />
+ <style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.DeviceDefault.Light.Dialog.NoActionBar.FixedSize" />
</resources>
diff --git a/core/res/res/values-large/themes_holo.xml b/core/res/res/values-large/themes_holo.xml
new file mode 100644
index 0000000..3f03932
--- /dev/null
+++ b/core/res/res/values-large/themes_holo.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2010, 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.
+*/
+-->
+
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+
+The Holo themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see themes_device_defaults.xml.
+
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
+<resources>
+ <style name="Theme.Holo.DialogWhenLarge" parent="@style/Theme.Holo.Dialog.FixedSize">
+ <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+ </style>
+ <style name="Theme.Holo.DialogWhenLarge.NoActionBar" parent="@style/Theme.Holo.Dialog.NoActionBar.FixedSize">
+ <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+ </style>
+ <style name="Theme.Holo.Light.DialogWhenLarge" parent="@style/Theme.Holo.Light.Dialog.FixedSize" />
+ <style name="Theme.Holo.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.Holo.Light.Dialog.NoActionBar.FixedSize" />
+</resources>
diff --git a/core/res/res/values-large/themes_material.xml b/core/res/res/values-large/themes_material.xml
new file mode 100644
index 0000000..2781608
--- /dev/null
+++ b/core/res/res/values-large/themes_material.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see themes_device_defaults.xml.
+
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
+<resources>
+ <style name="Theme.Material.DialogWhenLarge" parent="@style/Theme.Material.Dialog.FixedSize">
+ <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+ </style>
+ <style name="Theme.Material.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.Dialog.NoActionBar.FixedSize">
+ <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+ </style>
+ <style name="Theme.Material.Light.DialogWhenLarge" parent="@style/Theme.Material.Light.Dialog.FixedSize" />
+ <style name="Theme.Material.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.Light.Dialog.NoActionBar.FixedSize" />
+</resources>
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index fdbe0a0..faa9fb7 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -89,6 +89,9 @@
<color name="material_teal_A200">#ff18ffff</color>
<color name="material_teal_A400">#ff00e5ff</color>
+ <!-- Accent color used by Settings -->
+ <color name="material_dark_teal_A400">#ff009688</color>
+
<color name="material_green_100">#ffb7e1cd</color>
<color name="material_green_300">#ff57bb8a</color>
<color name="material_green_500">#ff0f9d58</color>
@@ -143,7 +146,10 @@
<color name="material_blue_grey_600">#ff546e7a</color>
<color name="material_blue_grey_700">#ff455a64</color>
<color name="material_blue_grey_800">#ff37474f</color>
+ <!-- Primary color used by Settings -->
<color name="material_blue_grey_900">#ff263238</color>
+ <!-- Primary dark color used by Settings -->
+ <color name="material_blue_grey_950">#ff21272b</color>
<color name="material_brown_100">#ffd7ccc8</color>
<color name="material_brown_300">#ffa1887f</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 59d01de..27ac6c30 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -595,10 +595,11 @@
<integer name="config_shutdownBatteryTemperature">680</integer>
<!-- Display low battery warning when battery level dips to this value -->
- <integer name="config_lowBatteryWarningLevel">20</integer>
+ <integer name="config_lowBatteryWarningLevel">15</integer>
- <!-- Close low battery warning when battery level reaches this value -->
- <integer name="config_lowBatteryCloseWarningLevel">25</integer>
+ <!-- Close low battery warning when battery level reaches the lowBatteryWarningLevel
+ plus this -->
+ <integer name="config_lowBatteryCloseWarningBump">5</integer>
<!-- Default color for notification LED. -->
<color name="config_defaultNotificationColor">#ffffffff</color>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 94cf116..e16082f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2244,6 +2244,8 @@
<public type="style" name="TextAppearance.Material.Widget.TextView.PopupMenu" />
<public type="style" name="TextAppearance.Material.Widget.TextView.SpinnerItem" />
+ <public type="style" name="Theme.DeviceDefault.Settings" />
+
<public type="style" name="Theme.Material" />
<public type="style" name="Theme.Material.Dialog" />
<public type="style" name="Theme.Material.Dialog.MinWidth" />
@@ -2257,6 +2259,7 @@
<public type="style" name="Theme.Material.NoActionBar.Overscan" />
<public type="style" name="Theme.Material.NoActionBar.TranslucentDecor" />
<public type="style" name="Theme.Material.Panel" />
+ <public type="style" name="Theme.Material.Settings" />
<public type="style" name="Theme.Material.Voice" />
<public type="style" name="Theme.Material.Wallpaper" />
<public type="style" name="Theme.Material.Wallpaper.NoTitleBar" />
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index a40835c..7120521 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -344,8 +344,7 @@
<item name="android:textColor">#66000000</item>
</style>
- <style name="Widget.StatusBar.Material.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal">
- </style>
+ <style name="Widget.StatusBar.Material.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal" />
<style name="Widget.StatusBar.Material.ProgressBar.Media">
<item name="android:progressDrawable">@drawable/notification_material_media_progress</item>
@@ -963,12 +962,17 @@
<!-- Window title -->
<style name="WindowTitleBackground.Material">
<item name="background">@null</item>
+ <item name="paddingStart">16dp</item>
+ <item name="paddingEnd">16dp</item>
+ <item name="paddingTop">16dp</item>
</style>
<style name="WindowTitle.Material">
<item name="singleLine">true</item>
<item name="textAppearance">@style/TextAppearance.Material.WindowTitle</item>
<item name="shadowRadius">0</item>
+ <item name="ellipsize">end</item>
+ <item name="textAlignment">viewStart</item>
</style>
<style name="DialogWindowTitle.Material">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 853df6e..d8e31ea 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1509,7 +1509,7 @@
<java-symbol type="integer" name="config_defaultNotificationLedOn" />
<java-symbol type="integer" name="config_deskDockKeepsScreenOn" />
<java-symbol type="integer" name="config_lightSensorWarmupTime" />
- <java-symbol type="integer" name="config_lowBatteryCloseWarningLevel" />
+ <java-symbol type="integer" name="config_lowBatteryCloseWarningBump" />
<java-symbol type="integer" name="config_lowBatteryWarningLevel" />
<java-symbol type="integer" name="config_networkPolicyDefaultWarning" />
<java-symbol type="integer" name="config_networkTransitionTimeout" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 6b7d861..27c8754 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -555,4 +555,7 @@
<style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.Material.Light.SearchBar" />
+ <!-- DeviceDefault theme for a window that should look like the Settings app. -->
+ <style name="Theme.DeviceDefault.Settings" parent="Theme.Material.Settings" />
+
</resources>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 1304d2b..a42996a 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -154,7 +154,7 @@
<item name="windowContentOverlay">@null</item>
<item name="windowShowWallpaper">false</item>
<item name="windowTitleStyle">@style/WindowTitle.Material</item>
- <item name="windowTitleSize">25dip</item>
+ <item name="windowTitleSize">@dimen/action_bar_default_height_material</item>
<item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
<item name="windowContentTransitions">false</item>
<item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
@@ -503,7 +503,7 @@
<item name="windowContentOverlay">@drawable/ab_solid_shadow_material</item>
<item name="windowShowWallpaper">false</item>
<item name="windowTitleStyle">@style/WindowTitle.Material</item>
- <item name="windowTitleSize">25dip</item>
+ <item name="windowTitleSize">@dimen/action_bar_default_height_material</item>
<item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
<item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
<item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
@@ -1006,7 +1006,7 @@
<style name="Theme.Material.Dialog">
<item name="windowFrame">@null</item>
<item name="windowTitleStyle">@style/DialogWindowTitle.Material</item>
- <item name="windowBackground">@drawable/dialog_background_material</item>
+ <item name="windowBackground">@drawable/dialog_background_shadow_material</item>
<item name="windowIsFloating">true</item>
<item name="windowContentOverlay">@null</item>
<item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
@@ -1102,18 +1102,15 @@
<!-- Theme for a window that will be displayed either full-screen on
smaller screens (small, normal) or as a dialog on larger screens
(large, xlarge). -->
- <style name="Theme.Material.DialogWhenLarge" parent="@style/Theme.Material">
- </style>
+ <style name="Theme.Material.DialogWhenLarge" parent="@style/Theme.Material" />
<!-- Theme for a window without a title bar that will be displayed either
full-screen on smaller screens (small, normal) or as a dialog on larger screens
(large, xlarge). -->
- <style name="Theme.Material.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.NoActionBar">
- </style>
+ <style name="Theme.Material.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.NoActionBar" />
<!-- Theme for a presentation window on a secondary display. -->
- <style name="Theme.Material.Dialog.Presentation" parent="@style/Theme.Material.NoActionBar.Fullscreen">
- </style>
+ <style name="Theme.Material.Dialog.Presentation" parent="@style/Theme.Material.NoActionBar.Fullscreen" />
<!-- Light material dialog themes -->
@@ -1125,7 +1122,7 @@
<style name="Theme.Material.Light.Dialog">
<item name="windowFrame">@null</item>
<item name="windowTitleStyle">@style/DialogWindowTitle.Material.Light</item>
- <item name="windowBackground">?attr/colorBackground</item>
+ <item name="windowBackground">@drawable/dialog_background_shadow_material</item>
<item name="windowIsFloating">true</item>
<item name="windowContentOverlay">@null</item>
<item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
@@ -1189,15 +1186,12 @@
<!-- Theme for a window that will be displayed either full-screen on
smaller screens (small, normal) or as a dialog on larger screens
(large, xlarge). -->
- <style name="Theme.Material.Light.DialogWhenLarge" parent="@style/Theme.Material.Light">
- </style>
+ <style name="Theme.Material.Light.DialogWhenLarge" parent="@style/Theme.Material.Light" />
<!-- Theme for a window without an action bar that will be displayed either full-screen
on smaller screens (small, normal) or as a dialog on larger screens
(large, xlarge). -->
- <style name="Theme.Material.Light.DialogWhenLarge.NoActionBar"
- parent="@style/Theme.Material.Light.NoActionBar">
- </style>
+ <style name="Theme.Material.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.Light.NoActionBar" />
<!-- Material light theme for alert dialog windows, which is used by the
{@link android.app.AlertDialog} class. This is basically a dialog
@@ -1219,8 +1213,7 @@
</style>
<!-- Theme for a presentation window on a secondary display. -->
- <style name="Theme.Material.Light.Dialog.Presentation" parent="@style/Theme.Material.Light.NoActionBar.Fullscreen" >
- </style>
+ <style name="Theme.Material.Light.Dialog.Presentation" parent="@style/Theme.Material.Light.NoActionBar.Fullscreen" />
<!-- Default material (dark) for windows that want to have the user's selected
wallpaper appear behind them. -->
@@ -1236,4 +1229,11 @@
<item name="windowNoTitle">true</item>
</style>
+ <!-- Default theme for Settings and activities launched from Settings. -->
+ <style name="Theme.Material.Settings" parent="@style/Theme.Material.Light.DarkActionBar">
+ <item name="colorPrimary">@color/material_blue_grey_900</item>
+ <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
+ <item name="colorAccent">@color/material_dark_teal_A400</item>
+ </style>
+
</resources>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
index db125e6..116a31e 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
@@ -336,7 +336,7 @@
if (!InetAddress.isNumeric(dnsAddr)) {
throw new SAXException();
}
- mLinkProperties.addDns(InetAddress.getByName(dnsAddr));
+ mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr));
} catch (UnknownHostException e) {
throw new SAXException();
}
@@ -348,7 +348,7 @@
if (!InetAddress.isNumeric(dnsAddr)) {
throw new SAXException();
}
- mLinkProperties.addDns(InetAddress.getByName(dnsAddr));
+ mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr));
} catch (UnknownHostException e) {
throw new SAXException();
}
diff --git a/core/tests/coretests/src/android/net/LinkAddressTest.java b/core/tests/coretests/src/android/net/LinkAddressTest.java
index bccf556..814ecdd 100644
--- a/core/tests/coretests/src/android/net/LinkAddressTest.java
+++ b/core/tests/coretests/src/android/net/LinkAddressTest.java
@@ -56,26 +56,26 @@
// Valid addresses work as expected.
address = new LinkAddress(V4_ADDRESS, 25);
assertEquals(V4_ADDRESS, address.getAddress());
- assertEquals(25, address.getNetworkPrefixLength());
+ assertEquals(25, address.getPrefixLength());
assertEquals(0, address.getFlags());
assertEquals(RT_SCOPE_UNIVERSE, address.getScope());
address = new LinkAddress(V6_ADDRESS, 127);
assertEquals(V6_ADDRESS, address.getAddress());
- assertEquals(127, address.getNetworkPrefixLength());
+ assertEquals(127, address.getPrefixLength());
assertEquals(0, address.getFlags());
assertEquals(RT_SCOPE_UNIVERSE, address.getScope());
// Nonsensical flags/scopes or combinations thereof are acceptable.
address = new LinkAddress(V6 + "/64", IFA_F_DEPRECATED | IFA_F_PERMANENT, RT_SCOPE_LINK);
assertEquals(V6_ADDRESS, address.getAddress());
- assertEquals(64, address.getNetworkPrefixLength());
+ assertEquals(64, address.getPrefixLength());
assertEquals(IFA_F_DEPRECATED | IFA_F_PERMANENT, address.getFlags());
assertEquals(RT_SCOPE_LINK, address.getScope());
address = new LinkAddress(V4 + "/23", 123, 456);
assertEquals(V4_ADDRESS, address.getAddress());
- assertEquals(23, address.getNetworkPrefixLength());
+ assertEquals(23, address.getPrefixLength());
assertEquals(123, address.getFlags());
assertEquals(456, address.getScope());
@@ -94,10 +94,10 @@
}
assertEquals(NetworkUtils.numericToInetAddress("127.0.0.1"), ipv4Loopback.getAddress());
- assertEquals(8, ipv4Loopback.getNetworkPrefixLength());
+ assertEquals(8, ipv4Loopback.getPrefixLength());
assertEquals(NetworkUtils.numericToInetAddress("::1"), ipv6Loopback.getAddress());
- assertEquals(128, ipv6Loopback.getNetworkPrefixLength());
+ assertEquals(128, ipv6Loopback.getPrefixLength());
// Null addresses are rejected.
try {
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index 553afe0..e649baa 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -88,8 +88,8 @@
source.addLinkAddress(LINKADDRV4);
source.addLinkAddress(LINKADDRV6);
// set 2 dnses
- source.addDns(DNS1);
- source.addDns(DNS2);
+ source.addDnsServer(DNS1);
+ source.addDnsServer(DNS2);
// set 2 gateways
source.addRoute(new RouteInfo(GATEWAY1));
source.addRoute(new RouteInfo(GATEWAY2));
@@ -101,8 +101,8 @@
target.setInterfaceName(NAME);
target.addLinkAddress(LINKADDRV4);
target.addLinkAddress(LINKADDRV6);
- target.addDns(DNS1);
- target.addDns(DNS2);
+ target.addDnsServer(DNS1);
+ target.addDnsServer(DNS2);
target.addRoute(new RouteInfo(GATEWAY1));
target.addRoute(new RouteInfo(GATEWAY2));
target.setMtu(MTU);
@@ -114,8 +114,8 @@
target.setInterfaceName("qmi1");
target.addLinkAddress(LINKADDRV4);
target.addLinkAddress(LINKADDRV6);
- target.addDns(DNS1);
- target.addDns(DNS2);
+ target.addDnsServer(DNS1);
+ target.addDnsServer(DNS2);
target.addRoute(new RouteInfo(GATEWAY1));
target.addRoute(new RouteInfo(GATEWAY2));
target.setMtu(MTU);
@@ -127,8 +127,8 @@
target.addLinkAddress(new LinkAddress(
NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
target.addLinkAddress(LINKADDRV6);
- target.addDns(DNS1);
- target.addDns(DNS2);
+ target.addDnsServer(DNS1);
+ target.addDnsServer(DNS2);
target.addRoute(new RouteInfo(GATEWAY1));
target.addRoute(new RouteInfo(GATEWAY2));
target.setMtu(MTU);
@@ -139,8 +139,8 @@
target.addLinkAddress(LINKADDRV4);
target.addLinkAddress(LINKADDRV6);
// change dnses
- target.addDns(NetworkUtils.numericToInetAddress("75.208.7.2"));
- target.addDns(DNS2);
+ target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2"));
+ target.addDnsServer(DNS2);
target.addRoute(new RouteInfo(GATEWAY1));
target.addRoute(new RouteInfo(GATEWAY2));
target.setMtu(MTU);
@@ -150,8 +150,8 @@
target.setInterfaceName(NAME);
target.addLinkAddress(LINKADDRV4);
target.addLinkAddress(LINKADDRV6);
- target.addDns(DNS1);
- target.addDns(DNS2);
+ target.addDnsServer(DNS1);
+ target.addDnsServer(DNS2);
// change gateway
target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
target.addRoute(new RouteInfo(GATEWAY2));
@@ -162,8 +162,8 @@
target.setInterfaceName(NAME);
target.addLinkAddress(LINKADDRV4);
target.addLinkAddress(LINKADDRV6);
- target.addDns(DNS1);
- target.addDns(DNS2);
+ target.addDnsServer(DNS1);
+ target.addDnsServer(DNS2);
target.addRoute(new RouteInfo(GATEWAY1));
target.addRoute(new RouteInfo(GATEWAY2));
// change mtu
@@ -185,8 +185,8 @@
source.addLinkAddress(LINKADDRV4);
source.addLinkAddress(LINKADDRV6);
// set 2 dnses
- source.addDns(DNS1);
- source.addDns(DNS2);
+ source.addDnsServer(DNS1);
+ source.addDnsServer(DNS2);
// set 2 gateways
source.addRoute(new RouteInfo(GATEWAY1));
source.addRoute(new RouteInfo(GATEWAY2));
@@ -197,8 +197,8 @@
target.setInterfaceName(NAME);
target.addLinkAddress(LINKADDRV6);
target.addLinkAddress(LINKADDRV4);
- target.addDns(DNS2);
- target.addDns(DNS1);
+ target.addDnsServer(DNS2);
+ target.addDnsServer(DNS1);
target.addRoute(new RouteInfo(GATEWAY2));
target.addRoute(new RouteInfo(GATEWAY1));
target.setMtu(MTU);
diff --git a/core/tests/coretests/src/android/net/RouteInfoTest.java b/core/tests/coretests/src/android/net/RouteInfoTest.java
index 55d6592..c80d0bf 100644
--- a/core/tests/coretests/src/android/net/RouteInfoTest.java
+++ b/core/tests/coretests/src/android/net/RouteInfoTest.java
@@ -43,17 +43,17 @@
// Invalid input.
try {
- r = new RouteInfo(null, null, "rmnet0");
+ r = new RouteInfo((LinkAddress) null, null, "rmnet0");
fail("Expected RuntimeException: destination and gateway null");
} catch(RuntimeException e) {}
// Null destination is default route.
- r = new RouteInfo(null, Address("2001:db8::1"), null);
+ r = new RouteInfo((LinkAddress) null, Address("2001:db8::1"), null);
assertEquals(Prefix("::/0"), r.getDestination());
assertEquals(Address("2001:db8::1"), r.getGateway());
assertNull(r.getInterface());
- r = new RouteInfo(null, Address("192.0.2.1"), "wlan0");
+ r = new RouteInfo((LinkAddress) null, Address("192.0.2.1"), "wlan0");
assertEquals(Prefix("0.0.0.0/0"), r.getDestination());
assertEquals(Address("192.0.2.1"), r.getGateway());
assertEquals("wlan0", r.getInterface());
@@ -71,17 +71,19 @@
}
public void testMatches() {
- class PatchedRouteInfo extends RouteInfo {
+ class PatchedRouteInfo {
+ private final RouteInfo mRouteInfo;
+
public PatchedRouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
- super(destination, gateway, iface);
+ mRouteInfo = new RouteInfo(destination, gateway, iface);
}
public boolean matches(InetAddress destination) {
- return super.matches(destination);
+ return mRouteInfo.matches(destination);
}
}
- RouteInfo r;
+ PatchedRouteInfo r;
r = new PatchedRouteInfo(Prefix("2001:db8:f00::ace:d00d/127"), null, "rmnet0");
assertTrue(r.matches(Address("2001:db8:f00::ace:d00c")));
@@ -96,11 +98,11 @@
assertFalse(r.matches(Address("192.0.0.21")));
assertFalse(r.matches(Address("8.8.8.8")));
- RouteInfo ipv6Default = new PatchedRouteInfo(Prefix("::/0"), null, "rmnet0");
+ PatchedRouteInfo ipv6Default = new PatchedRouteInfo(Prefix("::/0"), null, "rmnet0");
assertTrue(ipv6Default.matches(Address("2001:db8::f00")));
assertFalse(ipv6Default.matches(Address("192.0.2.1")));
- RouteInfo ipv4Default = new PatchedRouteInfo(Prefix("0.0.0.0/0"), null, "rmnet0");
+ PatchedRouteInfo ipv4Default = new PatchedRouteInfo(Prefix("0.0.0.0/0"), null, "rmnet0");
assertTrue(ipv4Default.matches(Address("255.255.255.255")));
assertTrue(ipv4Default.matches(Address("192.0.2.1")));
assertFalse(ipv4Default.matches(Address("2001:db8::f00")));
diff --git a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
index 7d72f3e..d850c7c 100644
--- a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
+++ b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
@@ -21,7 +21,7 @@
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.inputmethod.CursorAnchorInfo;
-import android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder;
+import android.view.inputmethod.CursorAnchorInfo.Builder;
public class CursorAnchorInfoTest extends InstrumentationTestCase {
// null represents a character that is invisible, for example because it's overlapped by some
@@ -64,7 +64,7 @@
Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
TRANSFORM_MATRIX.setScale(10.0f, 20.0f);
- final CursorAnchorInfoBuilder builder = new CursorAnchorInfoBuilder();
+ final Builder builder = new Builder();
builder.setSelectionRange(SELECTION_START, SELECTION_END)
.setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT)
.setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
@@ -148,7 +148,7 @@
final Matrix MATRIX3 = new Matrix();
MATRIX3.setTranslate(210.0f, 220.0f);
final Matrix matrix = new Matrix();
- final CursorAnchorInfoBuilder builder = new CursorAnchorInfoBuilder();
+ final Builder builder = new Builder();
matrix.set(MATRIX1);
builder.setMatrix(matrix);
@@ -171,7 +171,7 @@
public void testBuilderAdd() throws Exception {
// A negative index should be rejected.
try {
- new CursorAnchorInfoBuilder().addCharacterRect(-1, 0.0f, 0.0f, 0.0f, 0.0f);
+ new Builder().addCharacterRect(-1, 0.0f, 0.0f, 0.0f, 0.0f);
} catch (IllegalArgumentException ex) {
assertTrue(true);
}
@@ -191,4 +191,3 @@
}
}
}
-
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index c9921ba3..59e15e1 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -975,11 +975,14 @@
// Bezier approximation
///////////////////////////////////////////////////////////////////////////////
+// Depth at which recursion is aborted
+#define ABORT_DEPTH 20
+
void PathTessellator::recursiveCubicBezierVertices(
float p1x, float p1y, float c1x, float c1y,
float p2x, float p2y, float c2x, float c2y,
float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
- Vector<Vertex>& outputVertices) {
+ Vector<Vertex>& outputVertices, int depth) {
float dx = p2x - p1x;
float dy = p2y - p1y;
float d1 = fabs((c1x - p2x) * dy - (c1y - p2y) * dx);
@@ -988,7 +991,7 @@
// multiplying by sqrInvScaleY/X equivalent to multiplying in dimensional scale factors
- if (d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
+ if (depth >= ABORT_DEPTH || d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
// below thresh, draw line by adding endpoint
pushToVector(outputVertices, p2x, p2y);
} else {
@@ -1012,11 +1015,11 @@
recursiveCubicBezierVertices(
p1x, p1y, p1c1x, p1c1y,
mx, my, p1c1c2x, p1c1c2y,
- sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+ sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
recursiveCubicBezierVertices(
mx, my, p2c1c2x, p2c1c2y,
p2x, p2y, p2c2x, p2c2y,
- sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+ sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
}
}
@@ -1025,12 +1028,12 @@
float bx, float by,
float cx, float cy,
float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
- Vector<Vertex>& outputVertices) {
+ Vector<Vertex>& outputVertices, int depth) {
float dx = bx - ax;
float dy = by - ay;
float d = (cx - bx) * dy - (cy - by) * dx;
- if (d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
+ if (depth >= ABORT_DEPTH || d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
// below thresh, draw line by adding endpoint
pushToVector(outputVertices, bx, by);
} else {
@@ -1044,9 +1047,9 @@
float my = (acy + bcy) * 0.5f;
recursiveQuadraticBezierVertices(ax, ay, mx, my, acx, acy,
- sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+ sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
recursiveQuadraticBezierVertices(mx, my, bx, by, bcx, bcy,
- sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+ sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
}
}
diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h
index f033470..8ac9a3b 100644
--- a/libs/hwui/PathTessellator.h
+++ b/libs/hwui/PathTessellator.h
@@ -105,7 +105,7 @@
float bx, float by,
float cx, float cy,
float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
- Vector<Vertex> &outputVertices);
+ Vector<Vertex> &outputVertices, int depth = 0);
/*
endpoints p1, p2
@@ -117,7 +117,7 @@
float p2x, float p2y,
float c2x, float c2y,
float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
- Vector<Vertex> &outputVertices);
+ Vector<Vertex> &outputVertices, int depth = 0);
};
}; // namespace uirenderer
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index 41cc9d2..e6bc873 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -165,12 +165,12 @@
ShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
const SkPath* casterPerimeter, const Matrix4* transformXY, const Matrix4* transformZ,
const Vector3& lightCenter, float lightRadius)
- : drawTransform(drawTransform)
+ : drawTransform(*drawTransform)
, localClip(localClip)
, opaque(opaque)
- , casterPerimeter(casterPerimeter)
- , transformXY(transformXY)
- , transformZ(transformZ)
+ , casterPerimeter(*casterPerimeter)
+ , transformXY(*transformXY)
+ , transformZ(*transformZ)
, lightCenter(lightCenter)
, lightRadius(lightRadius) {
}
@@ -182,14 +182,19 @@
delete bufferPair;
}
- // Note - only the localClip is deep copied, since other pointers point at Allocator controlled
- // objects, which are safe for the entire frame
- const Matrix4* drawTransform;
+ /* Note - we deep copy all task parameters, because *even though* pointers into Allocator
+ * controlled objects (like the SkPath and Matrix4s) should be safe for the entire frame,
+ * certain Allocators are destroyed before trim() is called to flush incomplete tasks.
+ *
+ * These deep copies could be avoided, long term, by cancelling or flushing outstanding tasks
+ * before tearning down single-frame LinearAllocators.
+ */
+ const Matrix4 drawTransform;
const Rect localClip;
bool opaque;
- const SkPath* casterPerimeter;
- const Matrix4* transformXY;
- const Matrix4* transformZ;
+ const SkPath casterPerimeter;
+ const Matrix4 transformXY;
+ const Matrix4 transformZ;
const Vector3 lightCenter;
const float lightRadius;
};
@@ -281,8 +286,8 @@
VertexBuffer* ambientBuffer = new VertexBuffer;
VertexBuffer* spotBuffer = new VertexBuffer;
- tessellateShadows(t->drawTransform, &t->localClip, t->opaque, t->casterPerimeter,
- t->transformXY, t->transformZ, t->lightCenter, t->lightRadius,
+ tessellateShadows(&t->drawTransform, &t->localClip, t->opaque, &t->casterPerimeter,
+ &t->transformXY, &t->transformZ, t->lightCenter, t->lightRadius,
*ambientBuffer, *spotBuffer);
t->setResult(new TessellationCache::vertexBuffer_pair_t(ambientBuffer, spotBuffer));
@@ -345,11 +350,12 @@
void TessellationCache::trim() {
- uint32_t size = getSize();
- while (size > mMaxSize) {
- size -= mCache.peekOldestValue()->getSize();
- mCache.removeOldest();
- }
+ // uint32_t size = getSize();
+ // while (size > mMaxSize) {
+ // size -= mCache.peekOldestValue()->getSize();
+ // mCache.removeOldest();
+ // }
+ mCache.clear(); // Workaround caching tessellation corruption
mShadowCache.clear();
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index ce9fbb1..458139b 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2344,19 +2344,24 @@
if (rctlr == null) {
return false;
}
- IAudioService service = getService();
- final RemoteController.OnClientUpdateListener l = rctlr.getUpdateListener();
- final ComponentName listenerComponent = new ComponentName(mContext, l.getClass());
- try {
- int[] artworkDimensions = rctlr.getArtworkSize();
- boolean reg = service.registerRemoteController(rctlr.getRcDisplay(),
- artworkDimensions[0]/*w*/, artworkDimensions[1]/*h*/,
- listenerComponent);
- rctlr.setIsRegistered(reg);
- return reg;
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in registerRemoteController " + e);
- return false;
+ if (USE_SESSIONS) {
+ rctlr.startListeningToSessions();
+ return true;
+ } else {
+ IAudioService service = getService();
+ final RemoteController.OnClientUpdateListener l = rctlr.getUpdateListener();
+ final ComponentName listenerComponent = new ComponentName(mContext, l.getClass());
+ try {
+ int[] artworkDimensions = rctlr.getArtworkSize();
+ boolean reg = service.registerRemoteController(rctlr.getRcDisplay(),
+ artworkDimensions[0]/* w */, artworkDimensions[1]/* h */,
+ listenerComponent);
+ rctlr.setIsRegistered(reg);
+ return reg;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in registerRemoteController " + e);
+ return false;
+ }
}
}
@@ -2369,12 +2374,16 @@
if (rctlr == null) {
return;
}
- IAudioService service = getService();
- try {
- service.unregisterRemoteControlDisplay(rctlr.getRcDisplay());
- rctlr.setIsRegistered(false);
- } catch (RemoteException e) {
- Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e);
+ if (USE_SESSIONS) {
+ rctlr.stopListeningToSessions();
+ } else {
+ IAudioService service = getService();
+ try {
+ service.unregisterRemoteControlDisplay(rctlr.getRcDisplay());
+ rctlr.setIsRegistered(false);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e);
+ }
}
}
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 3711585..76c7299 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -19,11 +19,17 @@
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.IRemoteControlDisplay;
import android.media.MediaMetadataEditor;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionLegacyHelper;
+import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -34,6 +40,7 @@
import android.view.KeyEvent;
import java.lang.ref.WeakReference;
+import java.util.List;
/**
* The RemoteController class is used to control media playback, display and update media metadata
@@ -56,6 +63,7 @@
private final static int TRANSPORT_UNKNOWN = 0;
private final static String TAG = "RemoteController";
private final static boolean DEBUG = false;
+ private final static boolean USE_SESSIONS = true;
private final static Object mGenLock = new Object();
private final static Object mInfoLock = new Object();
private final RcDisplay mRcd;
@@ -64,6 +72,11 @@
private final int mMaxBitmapDimension;
private MetadataEditor mMetadataEditor;
+ private MediaSessionManager mSessionManager;
+ private MediaSessionManager.SessionListener mSessionListener
+ = new TopTransportSessionListener();
+ private MediaController.Callback mSessionCb = new MediaControllerCallback();
+
/**
* Synchronized on mGenLock
*/
@@ -79,6 +92,8 @@
private int mArtworkWidth = -1;
private int mArtworkHeight = -1;
private boolean mEnabled = true;
+ // synchronized on mInfoLock, for USE_SESSION apis.
+ private MediaController mCurrentSession;
/**
* Class constructor.
@@ -123,6 +138,8 @@
mContext = context;
mRcd = new RcDisplay(this);
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ mSessionManager = (MediaSessionManager) context
+ .getSystemService(Context.MEDIA_SESSION_SERVICE);
if (ActivityManager.isLowRamDeviceStatic()) {
mMaxBitmapDimension = MAX_BITMAP_DIMENSION;
@@ -194,8 +211,15 @@
* @hide
*/
public String getRemoteControlClientPackageName() {
- return mClientPendingIntentCurrent != null ?
- mClientPendingIntentCurrent.getCreatorPackage() : null;
+ if (USE_SESSIONS) {
+ synchronized (mInfoLock) {
+ return mCurrentSession != null ? mCurrentSession.getSessionInfo().getPackageName()
+ : null;
+ }
+ } else {
+ return mClientPendingIntentCurrent != null ?
+ mClientPendingIntentCurrent.getCreatorPackage() : null;
+ }
}
/**
@@ -215,22 +239,38 @@
* @see OnClientUpdateListener#onClientPlaybackStateUpdate(int, long, long, float)
*/
public long getEstimatedMediaPosition() {
- if (mLastPlaybackInfo != null) {
- if (!RemoteControlClient.playbackPositionShouldMove(mLastPlaybackInfo.mState)) {
- return mLastPlaybackInfo.mCurrentPosMs;
+ if (USE_SESSIONS) {
+ synchronized (mInfoLock) {
+ if (mCurrentSession != null) {
+ PlaybackState state = mCurrentSession.getPlaybackState();
+ if (state != null) {
+ return state.getPosition();
+ }
+ }
}
-
- // Take the current position at the time of state change and estimate.
- final long thenPos = mLastPlaybackInfo.mCurrentPosMs;
- if (thenPos < 0) {
- return -1;
+ } else {
+ final PlaybackInfo lastPlaybackInfo;
+ synchronized (mInfoLock) {
+ lastPlaybackInfo = mLastPlaybackInfo;
}
+ if (lastPlaybackInfo != null) {
+ if (!RemoteControlClient.playbackPositionShouldMove(lastPlaybackInfo.mState)) {
+ return lastPlaybackInfo.mCurrentPosMs;
+ }
- final long now = SystemClock.elapsedRealtime();
- final long then = mLastPlaybackInfo.mStateChangeTimeMs;
- final long sinceThen = now - then;
- final long scaledSinceThen = (long) (sinceThen * mLastPlaybackInfo.mSpeed);
- return thenPos + scaledSinceThen;
+ // Take the current position at the time of state change and
+ // estimate.
+ final long thenPos = lastPlaybackInfo.mCurrentPosMs;
+ if (thenPos < 0) {
+ return -1;
+ }
+
+ final long now = SystemClock.elapsedRealtime();
+ final long then = lastPlaybackInfo.mStateChangeTimeMs;
+ final long sinceThen = now - then;
+ final long scaledSinceThen = (long) (sinceThen * lastPlaybackInfo.mSpeed);
+ return thenPos + scaledSinceThen;
+ }
}
return -1;
}
@@ -267,30 +307,40 @@
if (!KeyEvent.isMediaKey(keyEvent.getKeyCode())) {
throw new IllegalArgumentException("not a media key event");
}
- final PendingIntent pi;
- synchronized(mInfoLock) {
- if (!mIsRegistered) {
- Log.e(TAG, "Cannot use sendMediaKeyEvent() from an unregistered RemoteController");
- return false;
- }
- if (!mEnabled) {
- Log.e(TAG, "Cannot use sendMediaKeyEvent() from a disabled RemoteController");
- return false;
- }
- pi = mClientPendingIntentCurrent;
- }
- if (pi != null) {
- Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
- intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
- try {
- pi.send(mContext, 0, intent);
- } catch (CanceledException e) {
- Log.e(TAG, "Error sending intent for media button down: ", e);
+ if (USE_SESSIONS) {
+ synchronized (mInfoLock) {
+ if (mCurrentSession != null) {
+ return mCurrentSession.dispatchMediaButtonEvent(keyEvent);
+ }
return false;
}
} else {
- Log.i(TAG, "No-op when sending key click, no receiver right now");
- return false;
+ final PendingIntent pi;
+ synchronized (mInfoLock) {
+ if (!mIsRegistered) {
+ Log.e(TAG,
+ "Cannot use sendMediaKeyEvent() from an unregistered RemoteController");
+ return false;
+ }
+ if (!mEnabled) {
+ Log.e(TAG, "Cannot use sendMediaKeyEvent() from a disabled RemoteController");
+ return false;
+ }
+ pi = mClientPendingIntentCurrent;
+ }
+ if (pi != null) {
+ Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+ try {
+ pi.send(mContext, 0, intent);
+ } catch (CanceledException e) {
+ Log.e(TAG, "Error sending intent for media button down: ", e);
+ return false;
+ }
+ } else {
+ Log.i(TAG, "No-op when sending key click, no receiver right now");
+ return false;
+ }
}
return true;
}
@@ -311,11 +361,19 @@
if (timeMs < 0) {
throw new IllegalArgumentException("illegal negative time value");
}
- final int genId;
- synchronized (mGenLock) {
- genId = mClientGenerationIdCurrent;
+ if (USE_SESSIONS) {
+ synchronized (mInfoLock) {
+ if (mCurrentSession != null) {
+ mCurrentSession.getTransportControls().seekTo(timeMs);
+ }
+ }
+ } else {
+ final int genId;
+ synchronized (mGenLock) {
+ genId = mClientGenerationIdCurrent;
+ }
+ mAudioManager.setRemoteControlClientPlaybackPosition(genId, timeMs);
}
- mAudioManager.setRemoteControlClientPlaybackPosition(genId, timeMs);
return true;
}
@@ -430,7 +488,6 @@
return editor;
}
-
/**
* A class to read the metadata published by a {@link RemoteControlClient}, or send a
* {@link RemoteControlClient} new values for keys that can be edited.
@@ -477,26 +534,41 @@
if (!mMetadataChanged) {
return;
}
- final int genId;
- synchronized(mGenLock) {
- genId = mClientGenerationIdCurrent;
- }
- synchronized(mInfoLock) {
- if (mEditorMetadata.containsKey(
- String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER))) {
- Rating rating = (Rating) getObject(
- MediaMetadataEditor.RATING_KEY_BY_USER, null);
- mAudioManager.updateRemoteControlClientMetadata(genId,
- MediaMetadataEditor.RATING_KEY_BY_USER,
- rating);
- } else {
- Log.e(TAG, "no metadata to apply");
+ if (USE_SESSIONS) {
+ synchronized (mInfoLock) {
+ if (mCurrentSession != null) {
+ if (mEditorMetadata.containsKey(
+ String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER))) {
+ Rating rating = (Rating) getObject(
+ MediaMetadataEditor.RATING_KEY_BY_USER, null);
+ if (rating != null) {
+ mCurrentSession.getTransportControls().setRating(rating);
+ }
+ }
+ }
}
- // NOT setting mApplied to true as this type of MetadataEditor will be applied
- // multiple times, whenever the user of a RemoteController needs to change the
- // metadata (e.g. user changes the rating of a song more than once during playback)
- mApplied = false;
+ } else {
+ final int genId;
+ synchronized(mGenLock) {
+ genId = mClientGenerationIdCurrent;
+ }
+ synchronized(mInfoLock) {
+ if (mEditorMetadata.containsKey(
+ String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER))) {
+ Rating rating = (Rating) getObject(
+ MediaMetadataEditor.RATING_KEY_BY_USER, null);
+ mAudioManager.updateRemoteControlClientMetadata(genId,
+ MediaMetadataEditor.RATING_KEY_BY_USER,
+ rating);
+ } else {
+ Log.e(TAG, "no metadata to apply");
+ }
+ }
}
+ // NOT setting mApplied to true as this type of MetadataEditor will be applied
+ // multiple times, whenever the user of a RemoteController needs to change the
+ // metadata (e.g. user changes the rating of a song more than once during playback)
+ mApplied = false;
}
}
@@ -649,6 +721,46 @@
}
}
+ /**
+ * This receives updates when the current session changes. This is
+ * registered to receive the updates on the handler thread so it can call
+ * directly into the appropriate methods.
+ */
+ private class MediaControllerCallback extends MediaController.Callback {
+ @Override
+ public void onPlaybackStateChanged(PlaybackState state) {
+ onNewPlaybackState(state);
+ }
+
+ @Override
+ public void onMetadataChanged(MediaMetadata metadata) {
+ onNewMediaMetadata(metadata);
+ }
+ }
+
+ /**
+ * Listens for changes to the active session stack and replaces the
+ * currently tracked session if it has changed.
+ */
+ private class TopTransportSessionListener extends MediaSessionManager.SessionListener {
+ @Override
+ public void onActiveSessionsChanged(List<MediaController> controllers) {
+ int size = controllers.size();
+ for (int i = 0; i < size; i++) {
+ MediaController controller = controllers.get(i);
+ long flags = controller.getFlags();
+ // We only care about sessions that handle transport controls,
+ // which will be true for apps using RCC
+ if ((flags & MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS) != 0) {
+ updateController(controller);
+ return;
+ }
+ }
+ updateController(null);
+ }
+
+ }
+
//==================================================
// Event handling
private final EventHandler mEventHandler;
@@ -658,6 +770,8 @@
private final static int MSG_NEW_METADATA = 3; // msg always has non-null obj parameter
private final static int MSG_CLIENT_CHANGE = 4;
private final static int MSG_DISPLAY_ENABLE = 5;
+ private final static int MSG_NEW_PLAYBACK_STATE = 6;
+ private final static int MSG_NEW_MEDIA_METADATA = 7;
private class EventHandler extends Handler {
@@ -686,12 +800,46 @@
case MSG_DISPLAY_ENABLE:
onDisplayEnable(msg.arg1 == 1);
break;
+ case MSG_NEW_PLAYBACK_STATE:
+ // same as new playback info but using new apis
+ onNewPlaybackState((PlaybackState) msg.obj);
+ break;
+ case MSG_NEW_MEDIA_METADATA:
+ onNewMediaMetadata((MediaMetadata) msg.obj);
+ break;
default:
Log.e(TAG, "unknown event " + msg.what);
}
}
}
+ /**
+ * @hide
+ */
+ void startListeningToSessions() {
+ final ComponentName listenerComponent = new ComponentName(mContext,
+ mOnClientUpdateListener.getClass());
+ mSessionManager.addActiveSessionsListener(mSessionListener, listenerComponent,
+ ActivityManager.getCurrentUser());
+ mSessionListener.onActiveSessionsChanged(mSessionManager
+ .getActiveSessions(listenerComponent));
+ if (DEBUG) {
+ Log.d(TAG, "Registered session listener with component " + listenerComponent
+ + " for user " + ActivityManager.getCurrentUser());
+ }
+ }
+
+ /**
+ * @hide
+ */
+ void stopListeningToSessions() {
+ mSessionManager.removeActiveSessionsListener(mSessionListener);
+ if (DEBUG) {
+ Log.d(TAG, "Unregistered session listener for user "
+ + ActivityManager.getCurrentUser());
+ }
+ }
+
/** If the msg is already queued, replace it with this one. */
private static final int SENDMSG_REPLACE = 0;
/** If the msg is already queued, ignore this one and leave the old. */
@@ -713,6 +861,7 @@
handler.sendMessageDelayed(handler.obtainMessage(msg, arg1, arg2, obj), delayMs);
}
+ ///////////// These calls are used by the old APIs with RCC and RCD //////////////////////
private void onNewPendingIntent(int genId, PendingIntent pi) {
synchronized(mGenLock) {
if (mClientGenerationIdCurrent != genId) {
@@ -848,6 +997,86 @@
}
}
+ ///////////// These calls are used by the new APIs with Sessions //////////////////////
+ private void updateController(MediaController controller) {
+ if (DEBUG) {
+ Log.d(TAG, "Updating controller to " + controller + " previous controller is "
+ + mCurrentSession);
+ }
+ synchronized (mInfoLock) {
+ if (controller == null) {
+ if (mCurrentSession != null) {
+ mCurrentSession.removeCallback(mSessionCb);
+ mCurrentSession = null;
+ sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
+ 0 /* genId */, 1 /* clearing */, null /* obj */, 0 /* delay */);
+ }
+ } else if (mCurrentSession == null
+ || !controller.getSessionInfo().getId()
+ .equals(mCurrentSession.getSessionInfo().getId())) {
+ if (mCurrentSession != null) {
+ mCurrentSession.removeCallback(mSessionCb);
+ }
+ sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
+ 0 /* genId */, 0 /* clearing */, null /* obj */, 0 /* delay */);
+ mCurrentSession = controller;
+ mCurrentSession.addCallback(mSessionCb, mEventHandler);
+
+ PlaybackState state = controller.getPlaybackState();
+ sendMsg(mEventHandler, MSG_NEW_PLAYBACK_STATE, SENDMSG_REPLACE,
+ 0 /* genId */, 0, state /* obj */, 0 /* delay */);
+
+ MediaMetadata metadata = controller.getMetadata();
+ sendMsg(mEventHandler, MSG_NEW_MEDIA_METADATA, SENDMSG_REPLACE,
+ 0 /* arg1 */, 0 /* arg2 */, metadata /* obj */, 0 /* delay */);
+ }
+ // else same controller, no need to update
+ }
+ }
+
+ private void onNewPlaybackState(PlaybackState state) {
+ final OnClientUpdateListener l;
+ synchronized (mInfoLock) {
+ l = this.mOnClientUpdateListener;
+ }
+ if (l != null) {
+ int playstate = state == null ? RemoteControlClient.PLAYSTATE_NONE : PlaybackState
+ .getRccStateFromState(state.getState());
+ if (state == null || state.getPosition() == PlaybackState.PLAYBACK_POSITION_UNKNOWN) {
+ l.onClientPlaybackStateUpdate(playstate);
+ } else {
+ l.onClientPlaybackStateUpdate(playstate, state.getLastPositionUpdateTime(),
+ state.getPosition(), state.getPlaybackRate());
+ }
+ if (state != null) {
+ l.onClientTransportControlUpdate(PlaybackState.getRccControlFlagsFromActions(state
+ .getActions()));
+ }
+ }
+ }
+
+ private void onNewMediaMetadata(MediaMetadata metadata) {
+ if (metadata == null) {
+ // RemoteController only handles non-null metadata
+ return;
+ }
+ final OnClientUpdateListener l;
+ final MetadataEditor metadataEditor;
+ // prepare the received Bundle to be used inside a MetadataEditor
+ synchronized(mInfoLock) {
+ l = mOnClientUpdateListener;
+ boolean canRate = mCurrentSession != null
+ && mCurrentSession.getRatingType() != Rating.RATING_NONE;
+ long editableKeys = canRate ? MediaMetadataEditor.RATING_KEY_BY_USER : 0;
+ Bundle legacyMetadata = MediaSessionLegacyHelper.getOldMetadata(metadata);
+ mMetadataEditor = new MetadataEditor(legacyMetadata, editableKeys);
+ metadataEditor = mMetadataEditor;
+ }
+ if (l != null) {
+ l.onClientMetadataUpdate(metadataEditor);
+ }
+ }
+
//==================================================
private static class PlaybackInfo {
int mState;
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 7c03907..f0cd785 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -37,6 +37,7 @@
boolean isTransportControlEnabled();
void showRoutePicker();
MediaSessionInfo getSessionInfo();
+ long getFlags();
// These commands are for the TransportController
void play();
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 57a0a54..5ca7daa 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -57,6 +57,7 @@
private final Object mLock = new Object();
private boolean mCbRegistered = false;
+ private MediaSessionInfo mInfo;
private TransportControls mTransportController;
@@ -174,6 +175,21 @@
}
/**
+ * Get the flags for this session.
+ *
+ * @return The current set of flags for the session.
+ * @hide
+ */
+ public long getFlags() {
+ try {
+ return mSessionBinder.getFlags();
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Error calling getFlags.", e);
+ }
+ return 0;
+ }
+
+ /**
* Adds a callback to receive updates from the Session. Updates will be
* posted on the caller's thread.
*
@@ -253,12 +269,14 @@
* @hide
*/
public MediaSessionInfo getSessionInfo() {
- try {
- return mSessionBinder.getSessionInfo();
- } catch (RemoteException e) {
- Log.e(TAG, "Error in getSessionInfo.", e);
+ if (mInfo == null) {
+ try {
+ mInfo = mSessionBinder.getSessionInfo();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error in getSessionInfo.", e);
+ }
}
- return null;
+ return mInfo;
}
/*
diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java
index 099f601..801844f 100644
--- a/media/java/android/media/session/MediaSessionLegacyHelper.java
+++ b/media/java/android/media/session/MediaSessionLegacyHelper.java
@@ -20,6 +20,10 @@
import android.app.PendingIntent.CanceledException;
import android.content.Context;
import android.content.Intent;
+import android.media.MediaMetadata;
+import android.media.MediaMetadataEditor;
+import android.media.MediaMetadataRetriever;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.ArrayMap;
@@ -64,6 +68,88 @@
return sInstance;
}
+ public static Bundle getOldMetadata(MediaMetadata metadata) {
+ Bundle oldMetadata = new Bundle();
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM)) {
+ oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUM),
+ metadata.getString(MediaMetadata.METADATA_KEY_ALBUM));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_ART)) {
+ oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
+ metadata.getBitmap(MediaMetadata.METADATA_KEY_ART));
+ } else if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART)) {
+ // Fall back to album art if the track art wasn't available
+ oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
+ metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ARTIST)) {
+ oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST),
+ metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ARTIST));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_ARTIST)) {
+ oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ARTIST),
+ metadata.getString(MediaMetadata.METADATA_KEY_ARTIST));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_AUTHOR)) {
+ oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_AUTHOR),
+ metadata.getString(MediaMetadata.METADATA_KEY_AUTHOR));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPILATION)) {
+ oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPILATION),
+ metadata.getString(MediaMetadata.METADATA_KEY_COMPILATION));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPOSER)) {
+ oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPOSER),
+ metadata.getString(MediaMetadata.METADATA_KEY_COMPOSER));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_DATE)) {
+ oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DATE),
+ metadata.getString(MediaMetadata.METADATA_KEY_DATE));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_DISC_NUMBER)) {
+ oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER),
+ metadata.getLong(MediaMetadata.METADATA_KEY_DISC_NUMBER));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
+ oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DURATION),
+ metadata.getLong(MediaMetadata.METADATA_KEY_DURATION));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_GENRE)) {
+ oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_GENRE),
+ metadata.getString(MediaMetadata.METADATA_KEY_GENRE));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_NUM_TRACKS)) {
+ oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS),
+ metadata.getLong(MediaMetadata.METADATA_KEY_NUM_TRACKS));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_RATING)) {
+ oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_OTHERS),
+ metadata.getRating(MediaMetadata.METADATA_KEY_RATING));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_USER_RATING)) {
+ oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER),
+ metadata.getRating(MediaMetadata.METADATA_KEY_USER_RATING));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_TITLE)) {
+ oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_TITLE),
+ metadata.getString(MediaMetadata.METADATA_KEY_TITLE));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_TRACK_NUMBER)) {
+ oldMetadata.putLong(
+ String.valueOf(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER),
+ metadata.getLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_WRITER)) {
+ oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_WRITER),
+ metadata.getString(MediaMetadata.METADATA_KEY_WRITER));
+ }
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_YEAR)) {
+ oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_YEAR),
+ metadata.getString(MediaMetadata.METADATA_KEY_YEAR));
+ }
+ return oldMetadata;
+ }
+
public MediaSession getSession(PendingIntent pi) {
SessionHolder holder = mSessions.get(pi);
return holder == null ? null : holder.mSession;
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 291bfc8..8eceee8 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -96,10 +96,13 @@
}
/**
- * Get a list of controllers for all ongoing sessions. This requires the
- * android.Manifest.permission.MEDIA_CONTENT_CONTROL permission be held by
- * the calling app. You may also retrieve this list if your app is an
- * enabled notification listener using the
+ * Get a list of controllers for all ongoing sessions. The controllers will
+ * be provided in priority order with the most important controller at index
+ * 0.
+ * <p>
+ * This requires the android.Manifest.permission.MEDIA_CONTENT_CONTROL
+ * permission be held by the calling app. You may also retrieve this list if
+ * your app is an enabled notification listener using the
* {@link NotificationListenerService} APIs, in which case you must pass the
* {@link ComponentName} of your enabled listener.
*
@@ -239,7 +242,8 @@
/**
* Called when the list of active sessions has changed. This can be due
* to a session being added or removed or the order of sessions
- * changing.
+ * changing. The controllers will be provided in priority order with the
+ * most important controller at index 0.
*
* @param controllers The updated list of controllers for the user that
* changed.
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index e09ac3f..3b3f249 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -432,6 +432,8 @@
return STATE_REWINDING;
case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
return STATE_SKIPPING_TO_PREVIOUS;
+ case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
+ return STATE_SKIPPING_TO_NEXT;
case RemoteControlClient.PLAYSTATE_STOPPED:
return STATE_STOPPED;
default:
@@ -440,6 +442,41 @@
}
/**
+ * Get the {@link RemoteControlClient} state for the given
+ * {@link PlaybackState} state.
+ *
+ * @param state The state used by {@link PlaybackState}.
+ * @return The equivalent state used by {@link RemoteControlClient}.
+ * @hide
+ */
+ public static int getRccStateFromState(int state) {
+ switch (state) {
+ case STATE_BUFFERING:
+ return RemoteControlClient.PLAYSTATE_BUFFERING;
+ case STATE_ERROR:
+ return RemoteControlClient.PLAYSTATE_ERROR;
+ case STATE_FAST_FORWARDING:
+ return RemoteControlClient.PLAYSTATE_FAST_FORWARDING;
+ case STATE_NONE:
+ return RemoteControlClient.PLAYSTATE_NONE;
+ case STATE_PAUSED:
+ return RemoteControlClient.PLAYSTATE_PAUSED;
+ case STATE_PLAYING:
+ return RemoteControlClient.PLAYSTATE_PLAYING;
+ case STATE_REWINDING:
+ return RemoteControlClient.PLAYSTATE_REWINDING;
+ case STATE_SKIPPING_TO_PREVIOUS:
+ return RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS;
+ case STATE_SKIPPING_TO_NEXT:
+ return RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS;
+ case STATE_STOPPED:
+ return RemoteControlClient.PLAYSTATE_STOPPED;
+ default:
+ return -1;
+ }
+ }
+
+ /**
* @hide
*/
public static long getActionsFromRccControlFlags(int rccFlags) {
@@ -454,6 +491,21 @@
return actions;
}
+ /**
+ * @hide
+ */
+ public static int getRccControlFlagsFromActions(long actions) {
+ int rccFlags = 0;
+ long action = 1;
+ while (action <= actions && action < Integer.MAX_VALUE) {
+ if ((action & actions) != 0) {
+ rccFlags |= getRccFlagForAction(action);
+ }
+ action = action << 1;
+ }
+ return rccFlags;
+ }
+
private static long getActionForRccFlag(int flag) {
switch (flag) {
case RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS:
@@ -480,6 +532,35 @@
return 0;
}
+ private static int getRccFlagForAction(long action) {
+ // We only care about the lower set of actions that can map to rcc
+ // flags.
+ int testAction = action < Integer.MAX_VALUE ? (int) action : 0;
+ switch (testAction) {
+ case (int) ACTION_SKIP_TO_PREVIOUS:
+ return RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS;
+ case (int) ACTION_REWIND:
+ return RemoteControlClient.FLAG_KEY_MEDIA_REWIND;
+ case (int) ACTION_PLAY:
+ return RemoteControlClient.FLAG_KEY_MEDIA_PLAY;
+ case (int) ACTION_PLAY_PAUSE:
+ return RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE;
+ case (int) ACTION_PAUSE:
+ return RemoteControlClient.FLAG_KEY_MEDIA_PAUSE;
+ case (int) ACTION_STOP:
+ return RemoteControlClient.FLAG_KEY_MEDIA_STOP;
+ case (int) ACTION_FAST_FORWARD:
+ return RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD;
+ case (int) ACTION_SKIP_TO_NEXT:
+ return RemoteControlClient.FLAG_KEY_MEDIA_NEXT;
+ case (int) ACTION_SEEK_TO:
+ return RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE;
+ case (int) ACTION_SET_RATING:
+ return RemoteControlClient.FLAG_KEY_MEDIA_RATING;
+ }
+ return 0;
+ }
+
public static final Parcelable.Creator<PlaybackState> CREATOR
= new Parcelable.Creator<PlaybackState>() {
@Override
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index 7918755..a8b49e2 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -130,6 +130,11 @@
}
}
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
+
private void updateOwnerInfo() {
String ownerInfo = getOwnerInfo();
if (!TextUtils.isEmpty(ownerInfo)) {
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
deleted file mode 100644
index e6af81e..0000000
--- a/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
index 873ca7e..fa5a0f0 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
index 9d3cf53..d88397e 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
index 288d36a..59d4695 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
index 266d34d..bbebcb1 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
index 0298054..93dc268 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
index 91e2edf..0073872 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
index 9ed15a7..0073872 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
index 6f2915b..8a3d69c 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
index 3f3b692..0afd6fe 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png
deleted file mode 100644
index 5ce8708..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
index 3f7c4b0..6ca3652 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
index 956bb7c..66f5c06 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 86e2947..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index d8ab8ea..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
index a53aef1..e49a2af 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
index e1b2145..84879b9 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index dffc059..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index c0209b0..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
index 2d8f81d..d005f61 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
index 61c6d11..dca30ab 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index a67ed6d..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 6101333..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
index 90eece6..6915a4a 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
index 382cf23..309fd4e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index ca1c8c4..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index cfef88d..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
index a4b3b37..23b570e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
index ee5f623..1c5f73f 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index ca3c541..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 78d4490..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
index 3d21350..40cf808 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
index 40fbaec..36dd2be 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 77bef31..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index d79f5b7..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
index 61b4569..3b979cd 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
index 1a0312b..e8d1dea 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index d04916e..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index d940d34..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
index 8715a11..0ab0991 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
index 487a0b1..4ced46b 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index a7cff47..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 0a60bb6..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
deleted file mode 100644
index e865f4c..0000000
--- a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
index 225d924..891397c5 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
index 7779d57..5cf3855 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
index 37d17d2..edb5b1f 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
index 5e70a07..3212336 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
index 39a0c07..7aff620 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
index 5bbf3fe..9f66c14 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
index 798f62f..9f66c14 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
index f8e549a..972b1a8 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
index c7fda96..473b0cb 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png
deleted file mode 100644
index bdf0f67..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
index 3361e34..8ad60a5 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
index ed52bc3..17cc722 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
index b380327..6fa0d5f 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
index 49df31b..70b3ef6 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
index ac45bcd..be6a5ef 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
index 9fb4266..b26600d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
index 459d011..b26600d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
index e1cddde..f2cb7be 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
index e459f2c..170bdb6 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
index 0ec4d23..b4bea6d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
index 4dedcbe..eb0eca1 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
index e55f2bf..3d8d19b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
index a39c3e5..0f6fdad 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
index 80e988f..cbe5f77 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
index 4ef12b0d..80eb803 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
index 8ef12a8..80eb803 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
index c2977c0..a6d892f 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
index 60ec10e..7183b81 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
index 8aa6e3a..657d546 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
index e272b62..df23594 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
index bf68b22..ab27aec 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
index 59ef663..31f98e1 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
index cf3a5ff..104aed7 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
index 2598954..18e113a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
index 66853db..18e113a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
index c46fd026..079e68d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
index 0e84d92..c38b43a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
index 7e96395e..c9507af 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
index cb94580..2426776 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
index 382ef39..48fb781 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
index 8d7be53..c6fb9bf 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
index 613fba0..528df6d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
index 0511ad1..055070a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
index 77fe9b2..055070a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
index ae78eb0..e17e8f4 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
index 5b446b1..aafee03 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png
deleted file mode 100644
index 83693c1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
index a2bb50a..e3cf7a6 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
index 24897ce..7e034b8 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
index aaeeb1b..a4b3a684 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
index ddee461..321fadb 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
index 23a7997..6e3219f 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
index 9f200c2..2b6021b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
index 43e9bc2..2b6021b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
index 5c0ba82..023ca54 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
index b76a0ca..3c9dccb 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png
deleted file mode 100644
index 461535c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png
deleted file mode 100644
index cebbb15..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
old mode 100644
new mode 100755
index 79cfcee..d8f1703
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
old mode 100644
new mode 100755
index 7959f65..4e12cc9
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
old mode 100644
new mode 100755
index c3bfcfb..37951a0
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
old mode 100644
new mode 100755
index 64f6a22..7281482
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
old mode 100644
new mode 100755
index 8fd36bc..a13418c
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
old mode 100644
new mode 100755
index 6f30e54..066c2d9
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
old mode 100644
new mode 100755
index 024ef8f..a619a94
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
old mode 100644
new mode 100755
index 6e0b071..115109a
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
old mode 100644
new mode 100755
index 9a56987..3101cb0
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png
deleted file mode 100644
index 7b03a11..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_05.xml b/packages/SystemUI/res/drawable/ic_notify_zen.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/ic_qs_location_05.xml
copy to packages/SystemUI/res/drawable/ic_notify_zen.xml
index 1a21e2f..c46455b 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_05.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_zen.xml
@@ -15,14 +15,14 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" >
<size
- android:width="64dp"
- android:height="64dp"/>
+ android:width="24dp"
+ android:height="24dp"/>
<viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0"/>
<path
android:fill="#FFFFFFFF"
- android:pathData="M12.0,13.0c-1.74,0.0 -3.15,1.41 -3.15,3.15C8.85,18.51 12.0,22.0 12.0,22.0s3.15,-3.49 3.15,-5.85C15.15,14.41 13.74,13.0 12.0,13.0zM12.0,17.27c-0.62,0.0 -1.13,-0.5 -1.13,-1.12c0.0,-0.62 0.5,-1.12 1.13,-1.12c0.62,0.0 1.12,0.5 1.12,1.12C13.12,16.77 12.62,17.27 12.0,17.27z"/>
+ android:pathData="M4.0,24.0c0.0,11.0 9.0,20.0 20.0,20.0s20.0,-9.0 20.0,-20.0S35.0,4.0 24.0,4.0S4.0,13.0 4.0,24.0zM36.6,33.8L14.2,11.4C16.9,9.3 20.3,8.0 24.0,8.0c8.8,0.0 16.0,7.2 16.0,16.0C40.0,27.7 38.7,31.1 36.6,33.8zM8.0,24.0c0.0,-3.7 1.3,-7.1 3.4,-9.8L33.8,36.6C31.1,38.7 27.7,40.0 24.0,40.0C15.2,40.0 8.0,32.8 8.0,24.0z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_01.xml b/packages/SystemUI/res/drawable/ic_power_low.xml
similarity index 66%
rename from packages/SystemUI/res/drawable/ic_qs_location_01.xml
rename to packages/SystemUI/res/drawable/ic_power_low.xml
index ff37d9a..5bb7aba 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_01.xml
+++ b/packages/SystemUI/res/drawable/ic_power_low.xml
@@ -15,14 +15,14 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" >
<size
- android:width="64dp"
- android:height="64dp"/>
+ android:width="24.0dp"
+ android:height="24.0dp"/>
<viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0"/>
<path
android:fill="#FFFFFFFF"
- android:pathData="M12.0,2.0C8.13,2.0 5.0,5.13 5.0,9.0c0.0,5.25 7.0,13.0 7.0,13.0s7.0,-7.75 7.0,-13.0C19.0,5.13 15.87,2.0 12.0,2.0zM12.0,11.5c-1.38,0.0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5c1.38,0.0 2.5,1.12 2.5,2.5S13.38,11.5 12.0,11.5z"/>
+ android:pathData="M30.0,6.0L30.0,2.0L18.0,2.0l0.0,4.0l-8.0,0.0l0.0,40.0l28.0,0.0L38.0,6.0L30.0,6.0zM26.0,37.0l-4.0,0.0l0.0,-4.0l4.0,0.0L26.0,37.0zM26.0,30.0l-4.0,0.0L22.0,15.0l4.0,0.0L26.0,30.0z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_01.xml b/packages/SystemUI/res/drawable/ic_power_saver.xml
similarity index 66%
copy from packages/SystemUI/res/drawable/ic_qs_location_01.xml
copy to packages/SystemUI/res/drawable/ic_power_saver.xml
index ff37d9a..26e7375 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_01.xml
+++ b/packages/SystemUI/res/drawable/ic_power_saver.xml
@@ -15,14 +15,14 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" >
<size
- android:width="64dp"
- android:height="64dp"/>
+ android:width="24.0dp"
+ android:height="24.0dp"/>
<viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0"/>
<path
android:fill="#FFFFFFFF"
- android:pathData="M12.0,2.0C8.13,2.0 5.0,5.13 5.0,9.0c0.0,5.25 7.0,13.0 7.0,13.0s7.0,-7.75 7.0,-13.0C19.0,5.13 15.87,2.0 12.0,2.0zM12.0,11.5c-1.38,0.0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5c1.38,0.0 2.5,1.12 2.5,2.5S13.38,11.5 12.0,11.5z"/>
+ android:pathData="M30.0,6.0L30.0,2.0L18.0,2.0l0.0,4.0l-8.0,0.0l0.0,40.0l28.0,0.0L38.0,6.0L30.0,6.0zM32.0,28.0l-6.0,0.0l0.0,6.0l-4.0,0.0l0.0,-6.0l-6.0,0.0l0.0,-4.0l6.0,0.0l0.0,-6.0l4.0,0.0l0.0,6.0l6.0,0.0L32.0,28.0z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_color_inversion.xml b/packages/SystemUI/res/drawable/ic_qs_color_inversion.xml
deleted file mode 100644
index dc30a53..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_color_inversion.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
- <size
- android:width="64dp"
- android:height="64dp"/>
-
- <viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
-
- <path
- android:fill="#FFFFFFFF"
- android:pathData="M18.939,7.244c-5.887,-5.885 -6.214,-6.214 -6.222,-6.222l-0.707,-0.737L5.088,7.207c-2.914,2.915 -3.74,6.629 -2.266,10.19c1.541,3.719 5.312,6.316 9.174,6.317l0.0,0.0c3.861,-0.001 7.636,-2.603 9.179,-6.328C22.646,13.834 21.832,10.138 18.939,7.244zM4.67,16.632c-1.149,-2.776 -0.481,-5.696 1.832,-8.011l5.494,-5.492c0.0,0.002 0.002,0.003 0.003,0.004l0.0,18.582c-0.001,0.0 -0.002,0.0 -0.003,0.0C8.922,21.714 5.91,19.624 4.67,16.632z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
new file mode 100644
index 0000000..b6a5cad
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
@@ -0,0 +1,28 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0"/>
+
+ <path
+ android:fill="#4DFFFFFF"
+ android:pathData="M41.3,41.7L36.6,37.0L24.0,24.5l-7.1,-7.1L14.0,14.5L8.5,9.0L6.0,11.5l5.6,5.6c-5.1,6.3 -4.7,15.5 1.1,21.4c3.1,3.1 7.2,4.7 11.3,4.7c3.6,0.0 7.1,-1.2 10.1,-3.6l5.4,5.4l2.5,-2.5L41.3,41.7zM24.0,39.2c-3.2,0.0 -6.2,-1.2 -8.5,-3.5c-2.3,-2.3 -3.5,-5.3 -3.5,-8.5c0.0,-2.6 0.9,-5.1 2.4,-7.2l9.6,9.6L24.0,39.2zM24.0,10.2l0.0,9.2l14.5,14.5c2.7,-5.9 1.7,-13.1 -3.2,-18.0L24.0,4.5l0.0,0.0l0.0,0.0L16.6,12.0l2.8,2.8L24.0,10.2z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_05.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
similarity index 68%
rename from packages/SystemUI/res/drawable/ic_qs_location_05.xml
rename to packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
index 1a21e2f..e8d59e0 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_05.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
@@ -19,10 +19,10 @@
android:height="64dp"/>
<viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0"/>
<path
android:fill="#FFFFFFFF"
- android:pathData="M12.0,13.0c-1.74,0.0 -3.15,1.41 -3.15,3.15C8.85,18.51 12.0,22.0 12.0,22.0s3.15,-3.49 3.15,-5.85C15.15,14.41 13.74,13.0 12.0,13.0zM12.0,17.27c-0.62,0.0 -1.13,-0.5 -1.13,-1.12c0.0,-0.62 0.5,-1.12 1.13,-1.12c0.62,0.0 1.12,0.5 1.12,1.12C13.12,16.77 12.62,17.27 12.0,17.27z"/>
+ android:pathData="M35.3,15.9L24.0,4.5l0.0,0.0l0.0,0.0L12.7,15.9c-6.2,6.2 -6.2,16.4 0.0,22.6c3.1,3.1 7.2,4.7 11.3,4.7s8.2,-1.6 11.3,-4.7C41.6,32.2 41.6,22.1 35.3,15.9zM24.0,39.2L24.0,39.2c-3.2,0.0 -6.2,-1.2 -8.5,-3.5c-2.3,-2.3 -3.5,-5.3 -3.5,-8.5s1.2,-6.2 3.5,-8.5l8.5,-8.5L24.0,39.2z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_02.xml b/packages/SystemUI/res/drawable/ic_qs_location_02.xml
deleted file mode 100644
index bb4465f..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_02.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
- <size
- android:width="64dp"
- android:height="64dp"/>
-
- <viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
-
- <path
- android:fill="#FFFFFFFF"
- android:pathData="M12.0,4.0c-3.48,0.0 -6.3,2.82 -6.3,6.3C5.7,15.02 12.0,22.0 12.0,22.0s6.3,-6.98 6.3,-11.7C18.3,6.82 15.48,4.0 12.0,4.0zM12.0,12.55c-1.24,0.0 -2.25,-1.01 -2.25,-2.25S10.76,8.05 12.0,8.05c1.24,0.0 2.25,1.01 2.25,2.25S13.24,12.55 12.0,12.55z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_03.xml b/packages/SystemUI/res/drawable/ic_qs_location_03.xml
deleted file mode 100644
index 956a8c3..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_03.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
- <size
- android:width="64dp"
- android:height="64dp"/>
-
- <viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
-
- <path
- android:fill="#FFFFFFFF"
- android:pathData="M12.0,7.0c-2.9,0.0 -5.25,2.35 -5.25,5.25C6.75,16.19 12.0,22.0 12.0,22.0s5.25,-5.81 5.25,-9.75C17.25,9.35 14.9,7.0 12.0,7.0zM12.0,14.12c-1.04,0.0 -1.88,-0.84 -1.88,-1.88s0.84,-1.88 1.88,-1.88c1.04,0.0 1.87,0.84 1.87,1.88S13.04,14.12 12.0,14.12z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_04.xml b/packages/SystemUI/res/drawable/ic_qs_location_04.xml
deleted file mode 100644
index 0c0fb3b..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_04.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
- <size
- android:width="64dp"
- android:height="64dp"/>
-
- <viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
-
- <path
- android:fill="#FFFFFFFF"
- android:pathData="M12.0,10.0c-2.32,0.0 -4.2,1.88 -4.2,4.2C7.8,17.35 12.0,22.0 12.0,22.0s4.2,-4.65 4.2,-7.8C16.2,11.88 14.32,10.0 12.0,10.0zM12.0,15.7c-0.83,0.0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5c0.83,0.0 1.5,0.67 1.5,1.5S12.83,15.7 12.0,15.7z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_06.xml b/packages/SystemUI/res/drawable/ic_qs_location_06.xml
deleted file mode 100644
index 5642a8a2..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_06.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
- <size
- android:width="64dp"
- android:height="64dp"/>
-
- <viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
-
- <path
- android:fill="#FFFFFFFF"
- android:pathData="M12.0,16.0c-1.16,0.0 -2.1,0.94 -2.1,2.1C9.9,19.67 12.0,22.0 12.0,22.0s2.1,-2.33 2.1,-3.9C14.1,16.94 13.16,16.0 12.0,16.0zM12.0,18.85c-0.41,0.0 -0.75,-0.34 -0.75,-0.75s0.34,-0.75 0.75,-0.75c0.41,0.0 0.75,0.34 0.75,0.75S12.41,18.85 12.0,18.85z"/>
- <path
- android:pathData="M11.99,15c-1.35,0,-2.45,1.1,-2.45,2.45 c0,1.84,2.45,4.55,2.45,4.55s2.45,-2.71,2.45,-4.55C14.44,16.1,13.34,15,11.99,15z M11.99,18.33c-0.48,0,-0.88,-0.39,-0.88,-0.88 s0.39,-0.88,0.88,-0.88c0.48,0,0.87,0.39,0.87,0.88S12.47,18.33,11.99,18.33z"
- android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_07.xml b/packages/SystemUI/res/drawable/ic_qs_location_07.xml
deleted file mode 100644
index 1ad2ebc..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_07.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
- <size
- android:width="64dp"
- android:height="64dp"/>
-
- <viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
-
- <path
- android:pathData="M12,9c-2.51,0,-4.55,2.04,-4.55,4.55 C7.45,16.96,12,22,12,22s4.55,-5.04,4.55,-8.45C16.55,11.04,14.51,9,12,9z M12,15.18c-0.9,0,-1.63,-0.73,-1.63,-1.62 s0.73,-1.62,1.63,-1.62c0.9,0,1.62,0.73,1.62,1.62S12.9,15.18,12,15.18z"
- android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_08.xml b/packages/SystemUI/res/drawable/ic_qs_location_08.xml
deleted file mode 100644
index 179bc66..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_08.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
- <size
- android:width="64dp"
- android:height="64dp"/>
-
- <viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
-
- <path
- android:pathData="M12,6c-3.09,0,-5.6,2.51,-5.6,5.6 C6.4,15.8,12,22,12,22s5.6,-6.2,5.6,-10.4C17.6,8.51,15.09,6,12,6z M12,13.6c-1.1,0,-2,-0.9,-2,-2s0.9,-2,2,-2c1.1,0,2,0.9,2,2 S13.1,13.6,12,13.6z"
- android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_09.xml b/packages/SystemUI/res/drawable/ic_qs_location_09.xml
deleted file mode 100644
index 6169af5..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_09.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
- <size
- android:width="64dp"
- android:height="64dp"/>
-
- <viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
-
- <path
- android:pathData="M12,4c-3.48,0,-6.3,2.82,-6.3,6.3 C5.7,15.02,12,22,12,22s6.3,-6.98,6.3,-11.7C18.3,6.82,15.48,4,12,4z M12,12.55c-1.24,0,-2.25,-1.01,-2.25,-2.25S10.76,8.05,12,8.05 c1.24,0,2.25,1.01,2.25,2.25S13.24,12.55,12,12.55z"
- android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_10.xml b/packages/SystemUI/res/drawable/ic_qs_location_10.xml
deleted file mode 100644
index 93e2eb4..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_10.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
- <size
- android:width="64dp"
- android:height="64dp"/>
-
- <viewport
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"/>
-
- <path
- android:pathData="M12,3C8.33,3,5.35,5.98,5.35,9.65 C5.35,14.64,12,22,12,22s6.65,-7.36,6.65,-12.35C18.65,5.98,15.67,3,12,3z M12,12.02c-1.31,0,-2.38,-1.06,-2.38,-2.38 S10.69,7.28,12,7.28c1.31,0,2.37,1.06,2.37,2.37S13.31,12.02,12,12.02z"
- android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_off.xml b/packages/SystemUI/res/drawable/ic_qs_location_off.xml
index d28d347..26ebfbf 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_off.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_off.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 The Android Open Source Project
@@ -14,18 +13,19 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<animation-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="true">
- <item android:drawable="@drawable/ic_qs_location_01" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_02" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_03" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_04" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_05" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_06" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_07" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_08" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_09" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_10" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_11" android:duration="16" />
-</animation-list>
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0"/>
+
+ <path
+ android:fill="#4DFFFFFF"
+ android:pathData="M24.0,13.0c2.8,0.0 5.0,2.2 5.0,5.0c0.0,1.5 -0.7,2.8 -1.7,3.7l7.3,7.3c2.0,-3.7 3.4,-7.6 3.4,-11.0c0.0,-7.7 -6.3,-14.0 -14.0,-14.0c-4.0,0.0 -7.5,1.6 -10.1,4.3l6.4,6.4C21.2,13.6 22.5,13.0 24.0,13.0zM32.7,32.2l-9.3,-9.3l-0.2,-0.2L6.5,6.0L4.0,8.5l6.4,6.4c-0.2,1.0 -0.4,2.0 -0.4,3.1c0.0,10.5 14.0,26.0 14.0,26.0s3.3,-3.7 6.8,-8.7l6.7,6.7l2.5,-2.5L32.7,32.2z"/>
+ <path
+ android:pathData="M23.5,22.9l0.0,0.0 -0.20000076,-0.19999886z"
+ android:fill="#4DFFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_on.xml b/packages/SystemUI/res/drawable/ic_qs_location_on.xml
index 72512ac..bc73005 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_on.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 The Android Open Source Project
@@ -14,18 +13,16 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<animation-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="true">
- <item android:drawable="@drawable/ic_qs_location_11" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_10" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_09" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_08" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_07" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_06" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_05" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_04" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_03" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_02" android:duration="16" />
- <item android:drawable="@drawable/ic_qs_location_01" android:duration="16" />
-</animation-list>
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0"/>
+
+ <path
+ android:fill="#FFFFFFFF"
+ android:pathData="M24.0,4.0c-7.7,0.0 -14.0,6.3 -14.0,14.0c0.0,10.5 14.0,26.0 14.0,26.0s14.0,-15.5 14.0,-26.0C38.0,10.3 31.7,4.0 24.0,4.0zM24.0,23.0c-2.8,0.0 -5.0,-2.2 -5.0,-5.0s2.2,-5.0 5.0,-5.0c2.8,0.0 5.0,2.2 5.0,5.0S26.8,23.0 24.0,23.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_11.xml b/packages/SystemUI/res/drawable/stat_sys_no_sim.xml
similarity index 71%
rename from packages/SystemUI/res/drawable/ic_qs_location_11.xml
rename to packages/SystemUI/res/drawable/stat_sys_no_sim.xml
index 09a3e63..70948b7 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_11.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_no_sim.xml
@@ -15,14 +15,14 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" >
<size
- android:width="64dp"
- android:height="64dp"/>
+ android:width="18dp"
+ android:height="18dp"/>
<viewport
android:viewportWidth="24.0"
android:viewportHeight="24.0"/>
<path
- android:pathData="M12,2C8.13,2,5,5.13,5,9c0,5.25,7,13,7,13s7,-7.75,7,-13 C19,5.13,15.87,2,12,2z M12,11.5c-1.38,0,-2.5,-1.12,-2.5,-2.5s1.12,-2.5,2.5,-2.5c1.38,0,2.5,1.12,2.5,2.5S13.38,11.5,12,11.5z"
- android:fill="#4DFFFFFF"/>
+ android:fill="#4DFFFFFF"
+ android:pathData="M19.0,5.0c0.0,-1.1 -0.9,-2.0 -2.0,-2.0l-7.0,0.0L7.7,5.3L19.0,16.7L19.0,5.0zM3.7,3.9L2.4,5.2L5.0,7.8L5.0,19.0c0.0,1.1 0.9,2.0 2.0,2.0l10.0,0.0c0.4,0.0 0.7,-0.1 1.0,-0.3l1.9,1.9l1.3,-1.3L3.7,3.9z"/>
</vector>
diff --git a/packages/SystemUI/res/layout/battery_low.xml b/packages/SystemUI/res/layout/battery_low.xml
deleted file mode 100644
index 2373355..0000000
--- a/packages/SystemUI/res/layout/battery_low.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/layout/keyguard.xml
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/padding"
- android:orientation="vertical"
- android:gravity="center"
- android:padding="16dp"
- >
-
- <TextView android:id="@+id/subtitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:textColor="#ffffffff"
- android:gravity="start"
- android:text="@string/battery_low_subtitle"
- />
-
- <TextView android:id="@+id/level_percent"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:textColor="#ffffffff"
- android:gravity="start"
- android:paddingBottom="16dp"
- />
-
- <ImageView android:id="@+id/image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/battery_low_battery"
- />
-
-</LinearLayout>
-
-
diff --git a/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml b/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
index 84d64b9..e220a16 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
@@ -18,48 +18,13 @@
<com.android.systemui.statusbar.SpeedBumpView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:focusable="true"
- android:clickable="true"
+ android:layout_height="@dimen/speed_bump_height"
android:visibility="gone"
>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="@dimen/speed_bump_height_collapsed"
- android:layout_gravity="top"
- android:orientation="horizontal">
- <com.android.systemui.statusbar.AlphaOptimizedView
- android:id="@+id/speedbump_line_left"
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="1"
- android:background="#6fdddddd"
- android:layout_gravity="center_vertical"/>
- <com.android.systemui.statusbar.SpeedBumpDotsLayout
- android:id="@+id/speed_bump_dots_layout"
- android:layout_width="34dp"
- android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp"
- android:layout_height="match_parent"
- android:layout_weight="0"/>
- <com.android.systemui.statusbar.AlphaOptimizedView
- android:id="@+id/speedbump_line_right"
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="1"
- android:background="#6fdddddd"
- android:layout_gravity="center_vertical"/>
- </LinearLayout>
- <TextView
- android:id="@+id/speed_bump_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top|center_horizontal"
- android:fontFamily="sans-serif-condensed"
- android:textSize="15sp"
- android:singleLine="true"
- android:textColor="#eeeeee"
- android:visibility="invisible"
- android:text="@string/speed_bump_explanation"
- android:paddingTop="4dp" />
+ <com.android.systemui.statusbar.AlphaOptimizedView
+ android:id="@+id/speedbump_line"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="#6fdddddd"
+ android:layout_gravity="center_vertical"/>
</com.android.systemui.statusbar.SpeedBumpView>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
index 1ce4983..6628f3b 100644
--- a/packages/SystemUI/res/values/arrays.xml
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -42,13 +42,11 @@
<!-- BatteryMeterView parameters -->
<array name="batterymeter_color_levels">
- <item>4</item>
<item>15</item>
<item>100</item>
</array>
<array name="batterymeter_color_values">
<item>#FFFF3300</item>
- <item>#FFFF3300</item>
<item>#FFFFFFFF</item>
</array>
<array name="batterymeter_bolt_points">
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index bb6f1a9..8c1a9c7 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -45,18 +45,6 @@
<!-- Tint color for the content on the notification overflow card. -->
<color name="keyguard_overflow_content_color">#ff686868</color>
- <!-- The color of the red speed bump dot -->
- <color name="speed_bump_dot_red">#ffd50000</color>
-
- <!-- The color of the blue speed bump dot -->
- <color name="speed_bump_dot_blue">#ff2962ff</color>
-
- <!-- The color of the yellow speed bump dot -->
- <color name="speed_bump_dot_yellow">#ffffd600</color>
-
- <!-- The color of the green speed bump dot -->
- <color name="speed_bump_dot_green">#ff00c853</color>
-
<!-- The default recents task bar background color. -->
<color name="recents_task_bar_default_background_color">#e6444444</color>
<!-- The default recents task bar text color. -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3f52740..836cf82 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -275,14 +275,8 @@
<!-- The minimum amount of top overscroll to go to the quick settings. -->
<dimen name="min_top_overscroll_to_qs">36dp</dimen>
- <!-- The height of the collapsed speed bump view. -->
- <dimen name="speed_bump_height_collapsed">24dp</dimen>
-
- <!-- The padding inset the explanation text needs compared to the collapsed height -->
- <dimen name="speed_bump_text_padding_inset">10dp</dimen>
-
- <!-- The height of the speed bump dots. -->
- <dimen name="speed_bump_dots_height">5dp</dimen>
+ <!-- The height of the speed bump view. -->
+ <dimen name="speed_bump_height">16dp</dimen>
<!-- The total height of the stack in its collapsed size (i.e. when quick settings is open) -->
<dimen name="collapsed_stack_height">94dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index de297e5..260f59c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -59,25 +59,43 @@
<string name="status_bar_latest_events_title">Notifications</string>
<!-- When the battery is low, this is displayed to the user in a dialog. The title of the low battery alert. [CHAR LIMIT=NONE]-->
- <string name="battery_low_title">Connect charger</string>
-
- <!-- When the battery is low, this is displayed to the user in a dialog. The subtitle of the low battery alert. [CHAR LIMIT=NONE] -->
- <string name="battery_low_subtitle">The battery is getting low.</string>
+ <string name="battery_low_title">Battery is low</string>
<!-- A message that appears when the battery level is getting low in a dialog. This is
appened to the subtitle of the low battery alert. "number" is the percentage of battery
remaining [CHAR LIMIT=none]-->
<string name="battery_low_percent_format"><xliff:g id="number">%d%%</xliff:g> remaining</string>
+ <!-- Same as battery_low_percent_format, with a notice about battery saver if on. [CHAR LIMIT=none]-->
+ <string name="battery_low_percent_format_saver_started"><xliff:g id="number">%d%%</xliff:g> remaining. Battery saver is on.</string>
+
<!-- A message that appears when a USB charger is plugged in and the device does not
support charging on it. That is, a charger that fits into the USB port and goes into
a wall socket, not into a computer. (This happens because some devices require more
current than the USB spec allows. [CHAR LIMIT=NONE] -->
<string name="invalid_charger">USB charging not supported.\nUse only the supplied charger.</string>
+ <!-- First line of invalid_charger, used in the notification form. [CHAR LIMIT=NONE]-->
+ <string name="invalid_charger_title">USB charging not supported.</string>
+
+ <!-- Second line of invalid_charger, used in the notification form. [CHAR LIMIT=NONE]-->
+ <string name="invalid_charger_text">Use only the supplied charger.</string>
+
<!-- When the battery is low, this is the label of the button to go to the
power usage activity to find out what drained the battery. [CHAR LIMIT=30] -->
- <string name="battery_low_why">Battery use</string>
+ <string name="battery_low_why">Settings</string>
+
+ <!-- Battery saver confirmation dialog title [CHAR LIMIT=NONE]-->
+ <string name="battery_saver_confirmation_title">Start battery saver?</string>
+
+ <!-- Battery saver confirmation dialog ok text [CHAR LIMIT=40]-->
+ <string name="battery_saver_confirmation_ok">Start</string>
+
+ <!-- Battery saver notification action [CHAR LIMIT=NONE]-->
+ <string name="battery_saver_start_action">Start battery saver</string>
+
+ <!-- Battery saver confirmation dialog text [CHAR LIMIT=NONE]-->
+ <string name="battery_saver_confirmation_text">To help improve battery life, Battery saver will reduce your device’s performance.\n\nBattery saver will be disabled when your device is plugged in.</string>
<!-- Name of the button that links to the Settings app. [CHAR LIMIT=NONE] -->
<string name="status_bar_settings_settings_button">Settings</string>
@@ -595,4 +613,13 @@
<item quantity="one">For one hour</item>
<item quantity="other">For %d hours</item>
</plurals>
+
+ <!-- Battery saver notification title. [CHAR LIMIT=60]-->
+ <string name="battery_saver_notification_title">Battery saver is on</string>
+
+ <!-- Battery saver notification text. [CHAR LIMIT=60] -->
+ <string name="battery_saver_notification_text">Device performance is reduced.</string>
+
+ <!-- Battery saver notification action text. [CHAR LIMIT=60] -->
+ <string name="battery_saver_notification_action_text">Open battery saver settings</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 19d06be..5e48258 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -25,8 +25,6 @@
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.os.BatteryManager;
@@ -44,7 +42,6 @@
private static final boolean SHOW_100_PERCENT = false;
private static final int FULL = 96;
- private static final int EMPTY = 4;
private static final float SUBPIXEL = 0.4f; // inset rects for softer edges
private static final float BOLT_LEVEL_THRESHOLD = 0.3f; // opaque bolt below this fraction
@@ -58,6 +55,7 @@
private int mHeight;
private int mWidth;
private String mWarningString;
+ private final int mCriticalLevel;
private final int mChargeColor;
private final float[] mBoltPoints;
private final Path mBoltPath = new Path();
@@ -197,6 +195,8 @@
mShowPercent = ENABLE_PERCENT && 0 != Settings.System.getInt(
context.getContentResolver(), "status_bar_show_battery_percent", 0);
mWarningString = context.getString(R.string.battery_meter_very_low_overlay_symbol);
+ mCriticalLevel = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_criticalBatteryWarningLevel);
mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mFramePaint.setColor(frameColor);
@@ -303,7 +303,7 @@
if (level >= FULL) {
drawFrac = 1f;
- } else if (level <= EMPTY) {
+ } else if (level <= mCriticalLevel) {
drawFrac = 0f;
}
@@ -360,7 +360,7 @@
boolean pctOpaque = false;
float pctX = 0, pctY = 0;
String pctText = null;
- if (!tracker.plugged && level > EMPTY && mShowPercent
+ if (!tracker.plugged && level > mCriticalLevel && mShowPercent
&& !(tracker.level == 100 && !SHOW_100_PERCENT)) {
mTextPaint.setColor(getColorForLevel(level));
mTextPaint.setTextSize(height *
@@ -390,7 +390,7 @@
c.drawPath(mShapePath, mBatteryPaint);
if (!tracker.plugged) {
- if (level <= EMPTY) {
+ if (level <= mCriticalLevel) {
// draw the warning text
final float x = mWidth * 0.5f;
final float y = (mHeight + mWarningTextHeight) * 0.48f;
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
index feec87c..2943494 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
@@ -16,6 +16,7 @@
package com.android.systemui.power;
+import android.app.ActivityManagerNative;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.Context;
@@ -25,13 +26,13 @@
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
+import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
-import android.view.View;
+import android.view.ContextThemeWrapper;
import android.view.WindowManager;
-import android.widget.TextView;
import com.android.systemui.R;
@@ -46,13 +47,14 @@
private int mBatteryLevel;
private int mBucket;
private long mScreenOffTime;
+ private boolean mSaver;
+ private int mSaverTriggerLevel;
private AlertDialog mInvalidChargerDialog;
private AlertDialog mLowBatteryDialog;
- private TextView mBatteryLevelTextView;
public PowerDialogWarnings(Context context) {
- mContext = context;
+ mContext = new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light);
}
@Override
@@ -77,7 +79,7 @@
@Override
public void updateLowBatteryWarning() {
- if (mBatteryLevelTextView != null) {
+ if (mLowBatteryDialog != null) {
showLowBatteryWarning(false /*playSound*/);
}
}
@@ -93,27 +95,22 @@
@Override
public void showLowBatteryWarning(boolean playSound) {
Slog.i(TAG,
- ((mBatteryLevelTextView == null) ? "showing" : "updating")
+ ((mLowBatteryDialog == null) ? "showing" : "updating")
+ " low battery warning: level=" + mBatteryLevel
+ " [" + mBucket + "]");
- CharSequence levelText = mContext.getString(
- R.string.battery_low_percent_format, mBatteryLevel);
+ final int textRes = mSaver ? R.string.battery_low_percent_format_saver_started
+ : R.string.battery_low_percent_format;
+ final CharSequence levelText = mContext.getString(textRes, mBatteryLevel);
- if (mBatteryLevelTextView != null) {
- mBatteryLevelTextView.setText(levelText);
+ if (mLowBatteryDialog != null) {
+ mLowBatteryDialog.setMessage(levelText);
} else {
- View v = View.inflate(mContext, R.layout.battery_low, null);
- mBatteryLevelTextView = (TextView)v.findViewById(R.id.level_percent);
-
- mBatteryLevelTextView.setText(levelText);
-
AlertDialog.Builder b = new AlertDialog.Builder(mContext);
- b.setCancelable(true);
- b.setTitle(R.string.battery_low_title);
- b.setView(v);
- b.setIconAttribute(android.R.attr.alertDialogIcon);
- b.setPositiveButton(android.R.string.ok, null);
+ b.setCancelable(true);
+ b.setTitle(R.string.battery_low_title);
+ b.setMessage(levelText);
+ b.setPositiveButton(android.R.string.ok, null);
final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -125,6 +122,11 @@
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
+ try {
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } catch (RemoteException e) {
+ // we tried
+ }
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
dismissLowBatteryWarning();
}
@@ -136,10 +138,9 @@
@Override
public void onDismiss(DialogInterface dialog) {
mLowBatteryDialog = null;
- mBatteryLevelTextView = null;
}
});
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
d.getWindow().getAttributes().privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
d.show();
@@ -198,21 +199,32 @@
dismissLowBatteryWarning();
AlertDialog.Builder b = new AlertDialog.Builder(mContext);
- b.setCancelable(true);
- b.setMessage(R.string.invalid_charger);
- b.setIconAttribute(android.R.attr.alertDialogIcon);
- b.setPositiveButton(android.R.string.ok, null);
+ b.setCancelable(true);
+ b.setTitle(R.string.invalid_charger_title);
+ b.setMessage(R.string.invalid_charger_text);
+ b.setPositiveButton(android.R.string.ok, null);
AlertDialog d = b.create();
d.setOnDismissListener(new DialogInterface.OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
mInvalidChargerDialog = null;
- mBatteryLevelTextView = null;
}
});
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+ d.getWindow().getAttributes().privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
d.show();
mInvalidChargerDialog = d;
}
+
+ @Override
+ public void showSaverMode(boolean mode) {
+ mSaver = mode;
+ }
+
+ @Override
+ public void setSaverTrigger(int level) {
+ mSaverTriggerLevel = level;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
new file mode 100644
index 0000000..3fa8b99
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -0,0 +1,391 @@
+/*
+ * 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.power;
+
+import android.app.AlertDialog;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.Slog;
+import android.view.ContextThemeWrapper;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.R;
+
+import java.io.PrintWriter;
+
+public class PowerNotificationWarnings implements PowerUI.WarningsUI {
+ private static final String TAG = PowerUI.TAG + ".Notification";
+ private static final boolean DEBUG = PowerUI.DEBUG;
+
+ private static final String TAG_NOTIFICATION = "low_battery";
+ private static final int ID_NOTIFICATION = 100;
+ private static final int AUTO_DISMISS_MS = 10000;
+
+ private static final int SHOWING_NOTHING = 0;
+ private static final int SHOWING_WARNING = 1;
+ private static final int SHOWING_SAVER = 2;
+ private static final int SHOWING_INVALID_CHARGER = 3;
+ private static final String[] SHOWING_STRINGS = {
+ "SHOWING_NOTHING",
+ "SHOWING_WARNING",
+ "SHOWING_SAVER",
+ "SHOWING_INVALID_CHARGER",
+ };
+
+ private static final String ACTION_SHOW_FALLBACK_WARNING = "PNW.warningFallback";
+ private static final String ACTION_SHOW_FALLBACK_CHARGER = "PNW.chargerFallback";
+ private static final String ACTION_SHOW_BATTERY_SETTINGS = "PNW.batterySettings";
+ private static final String ACTION_START_SAVER = "PNW.startSaver";
+
+ private final Context mContext;
+ private final Context mLightContext;
+ private final NotificationManager mNoMan;
+ private final Handler mHandler = new Handler();
+ private final PowerDialogWarnings mFallbackDialogs;
+ private final Receiver mReceiver = new Receiver();
+ private final Intent mOpenBatterySettings = settings(Intent.ACTION_POWER_USAGE_SUMMARY);
+ private final Intent mOpenSaverSettings = settings(Settings.ACTION_BATTERY_SAVER_SETTINGS);
+
+ private int mBatteryLevel;
+ private int mBucket;
+ private long mScreenOffTime;
+ private int mShowing;
+
+ private boolean mSaver;
+ private int mSaverTriggerLevel;
+ private boolean mWarning;
+ private boolean mPlaySound;
+ private boolean mInvalidCharger;
+
+ public PowerNotificationWarnings(Context context) {
+ mContext = context;
+ mLightContext = new ContextThemeWrapper(mContext,
+ android.R.style.Theme_DeviceDefault_Light);
+ mNoMan = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ mFallbackDialogs = new PowerDialogWarnings(context);
+ mReceiver.init();
+ }
+
+ @Override
+ public void dump(PrintWriter pw) {
+ pw.print("mSaver="); pw.println(mSaver);
+ pw.print("mWarning="); pw.println(mWarning);
+ pw.print("mPlaySound="); pw.println(mPlaySound);
+ pw.print("mInvalidCharger="); pw.println(mInvalidCharger);
+ pw.print("mShowing="); pw.println(SHOWING_STRINGS[mShowing]);
+ }
+
+ @Override
+ public void update(int batteryLevel, int bucket, long screenOffTime) {
+ mBatteryLevel = batteryLevel;
+ mBucket = bucket;
+ mScreenOffTime = screenOffTime;
+ mFallbackDialogs.update(batteryLevel, bucket, screenOffTime);
+ }
+
+ @Override
+ public void showSaverMode(boolean mode) {
+ mSaver = mode;
+ updateNotification();
+ }
+
+ @Override
+ public void setSaverTrigger(int level) {
+ mSaverTriggerLevel = level;
+ updateNotification();
+ }
+
+ private void cancelOther(int showing) {
+ if (mShowing != SHOWING_NOTHING && mShowing != showing) {
+ mNoMan.cancel(TAG_NOTIFICATION, ID_NOTIFICATION); // workaround no HUN on updates
+ }
+ }
+
+ private void updateNotification() {
+ Slog.d(TAG, "updateNotification mWarning=" + mWarning
+ + " mSaver=" + mSaver + " mInvalidCharger=" + mInvalidCharger);
+ if (mInvalidCharger) {
+ cancelOther(SHOWING_INVALID_CHARGER);
+ showInvalidChargerNotification();
+ mShowing = SHOWING_INVALID_CHARGER;
+ } else if (mWarning) {
+ cancelOther(SHOWING_WARNING);
+ showWarningNotification();
+ mShowing = SHOWING_WARNING;
+ } else if (mSaver) {
+ cancelOther(SHOWING_SAVER);
+ showSaverNotification();
+ mShowing = SHOWING_SAVER;
+ } else {
+ mNoMan.cancel(TAG_NOTIFICATION, ID_NOTIFICATION);
+ mShowing = SHOWING_NOTHING;
+ }
+ }
+
+ private void showInvalidChargerNotification() {
+ final Notification.Builder nb = new Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.ic_power_low)
+ .setShowWhen(false)
+ .setOngoing(true)
+ .setContentTitle(mContext.getString(R.string.invalid_charger_title))
+ .setContentText(mContext.getString(R.string.invalid_charger_text))
+ .setPriority(Notification.PRIORITY_MAX)
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .setFullScreenIntent(pendingBroadcast(ACTION_SHOW_FALLBACK_CHARGER), true);
+ final Notification n = nb.build();
+ if (n.headsUpContentView != null) {
+ n.headsUpContentView.setViewVisibility(com.android.internal.R.id.right_icon, View.GONE);
+ }
+ mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, n, UserHandle.CURRENT);
+ }
+
+ private void showWarningNotification() {
+ final int textRes = mSaver ? R.string.battery_low_percent_format_saver_started
+ : R.string.battery_low_percent_format;
+ final Notification.Builder nb = new Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.ic_power_low)
+ .setShowWhen(false)
+ .setContentTitle(mContext.getString(R.string.battery_low_title))
+ .setContentText(mContext.getString(textRes, mBatteryLevel))
+ .setOngoing(true)
+ .setPriority(Notification.PRIORITY_MAX)
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .setFullScreenIntent(pendingBroadcast(ACTION_SHOW_FALLBACK_WARNING), true);
+ if (hasBatterySettings()) {
+ nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
+ }
+ if (!mSaver && mSaverTriggerLevel <= 0) {
+ nb.addAction(R.drawable.ic_power_saver,
+ mContext.getString(R.string.battery_saver_start_action),
+ pendingBroadcast(ACTION_START_SAVER));
+ }
+ if (mPlaySound) {
+ attachLowBatterySound(nb);
+ }
+ final Notification n = nb.build();
+ if (n.headsUpContentView != null) {
+ n.headsUpContentView.setViewVisibility(com.android.internal.R.id.right_icon, View.GONE);
+ }
+ mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, n, UserHandle.CURRENT);
+ }
+
+ private void showSaverNotification() {
+ final Notification.Builder nb = new Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.ic_power_saver)
+ .setContentTitle(mContext.getString(R.string.battery_saver_notification_title))
+ .setContentText(mContext.getString(R.string.battery_saver_notification_text))
+ .setOngoing(true)
+ .setShowWhen(false)
+ .setCategory(Notification.CATEGORY_SYSTEM);
+ if (hasSaverSettings()) {
+ nb.addAction(0,
+ mContext.getString(R.string.battery_saver_notification_action_text),
+ pendingActivity(mOpenSaverSettings));
+ nb.setContentIntent(pendingActivity(mOpenSaverSettings));
+ }
+ mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, nb.build(), UserHandle.CURRENT);
+ }
+
+ private PendingIntent pendingActivity(Intent intent) {
+ return PendingIntent.getActivityAsUser(mContext,
+ 0, intent, 0, null, UserHandle.CURRENT);
+ }
+
+ private PendingIntent pendingBroadcast(String action) {
+ return PendingIntent.getBroadcastAsUser(mContext,
+ 0, new Intent(action), 0, UserHandle.CURRENT);
+ }
+
+ private static Intent settings(String action) {
+ return new Intent(action).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_NO_HISTORY
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ }
+
+ @Override
+ public boolean isInvalidChargerWarningShowing() {
+ return mInvalidCharger;
+ }
+
+ @Override
+ public void updateLowBatteryWarning() {
+ updateNotification();
+ mFallbackDialogs.updateLowBatteryWarning();
+ }
+
+ @Override
+ public void dismissLowBatteryWarning() {
+ Slog.i(TAG, "dismissing low battery warning: level=" + mBatteryLevel);
+ dismissLowBatteryNotification();
+ mFallbackDialogs.dismissLowBatteryWarning();
+ }
+
+ private void dismissLowBatteryNotification() {
+ Slog.i(TAG, "dismissing low battery notification");
+ mWarning = false;
+ updateNotification();
+ }
+
+ private boolean hasBatterySettings() {
+ return mOpenBatterySettings.resolveActivity(mContext.getPackageManager()) != null;
+ }
+
+ private boolean hasSaverSettings() {
+ return mOpenSaverSettings.resolveActivity(mContext.getPackageManager()) != null;
+ }
+
+ @Override
+ public void showLowBatteryWarning(boolean playSound) {
+ Slog.i(TAG,
+ "show low battery warning: level=" + mBatteryLevel
+ + " [" + mBucket + "]");
+ mPlaySound = playSound;
+ mWarning = true;
+ updateNotification();
+ mHandler.removeCallbacks(mDismissLowBatteryNotification);
+ mHandler.postDelayed(mDismissLowBatteryNotification, AUTO_DISMISS_MS);
+ }
+
+ private void attachLowBatterySound(Notification.Builder b) {
+ final ContentResolver cr = mContext.getContentResolver();
+
+ final int silenceAfter = Settings.Global.getInt(cr,
+ Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0);
+ final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime;
+ if (silenceAfter > 0
+ && mScreenOffTime > 0
+ && offTime > silenceAfter) {
+ Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter
+ + "ms): not waking up the user with low battery sound");
+ return;
+ }
+
+ if (DEBUG) {
+ Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated
+ }
+
+ if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) {
+ final String soundPath = Settings.Global.getString(cr,
+ Settings.Global.LOW_BATTERY_SOUND);
+ if (soundPath != null) {
+ final Uri soundUri = Uri.parse("file://" + soundPath);
+ if (soundUri != null) {
+ b.setSound(soundUri, AudioManager.STREAM_SYSTEM);
+ Slog.d(TAG, "playing sound " + soundUri);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void dismissInvalidChargerWarning() {
+ mInvalidCharger = false;
+ updateNotification();
+ }
+
+ @Override
+ public void showInvalidChargerWarning() {
+ mInvalidCharger = true;
+ updateNotification();
+ }
+
+ private void showStartSaverConfirmation() {
+ final AlertDialog d = new AlertDialog.Builder(mLightContext)
+ .setTitle(R.string.battery_saver_confirmation_title)
+ .setMessage(R.string.battery_saver_confirmation_text)
+ .setNegativeButton(android.R.string.cancel, null)
+ .setPositiveButton(R.string.battery_saver_confirmation_ok, mStartSaverMode)
+ .create();
+
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+ d.getWindow().getAttributes().privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+ d.show();
+ }
+
+ private void setSaverSetting(boolean mode) {
+ final int val = mode ? 1 : 0;
+ Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.LOW_POWER_MODE, val);
+ }
+
+ private final class Receiver extends BroadcastReceiver {
+
+ public void init() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_SHOW_FALLBACK_WARNING);
+ filter.addAction(ACTION_SHOW_FALLBACK_CHARGER);
+ filter.addAction(ACTION_SHOW_BATTERY_SETTINGS);
+ filter.addAction(ACTION_START_SAVER);
+ mContext.registerReceiver(this, filter, null, mHandler);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ Log.d(TAG, "got " + action);
+ if (action.equals(ACTION_SHOW_FALLBACK_WARNING)) {
+ mFallbackDialogs.showLowBatteryWarning(false /*playSound*/);
+ } else if (action.equals(ACTION_SHOW_FALLBACK_CHARGER)) {
+ mFallbackDialogs.showInvalidChargerWarning();
+ } else if (action.equals(ACTION_SHOW_BATTERY_SETTINGS)) {
+ dismissLowBatteryNotification();
+ mContext.startActivityAsUser(mOpenBatterySettings, UserHandle.CURRENT);
+ } else if (action.equals(ACTION_START_SAVER)) {
+ dismissLowBatteryNotification();
+ showStartSaverConfirmation();
+ }
+ }
+ }
+
+ private final OnClickListener mStartSaverMode = new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ AsyncTask.execute(new Runnable() {
+ @Override
+ public void run() {
+ setSaverSetting(true);
+ }
+ });
+ }
+ };
+
+ private final Runnable mDismissLowBatteryNotification = new Runnable() {
+ @Override
+ public void run() {
+ dismissLowBatteryNotification();
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 0fb0f8b..1bb7edb 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -17,13 +17,17 @@
package com.android.systemui.power;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
@@ -35,13 +39,15 @@
public class PowerUI extends SystemUI {
static final String TAG = "PowerUI";
-
static final boolean DEBUG = false;
- private WarningsUI mWarnings;
private final Handler mHandler = new Handler();
+ private final SettingsObserver mObserver = new SettingsObserver(mHandler);
+ private final Receiver mReceiver = new Receiver();
+ private PowerManager mPowerManager;
+ private WarningsUI mWarnings;
private int mBatteryLevel = 100;
private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
private int mPlugType = 0;
@@ -53,24 +59,54 @@
private long mScreenOffTime = -1;
public void start() {
+ mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
+ mWarnings = new PowerNotificationWarnings(mContext);
- mLowBatteryAlertCloseLevel = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);
- mLowBatteryReminderLevels[0] = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_lowBatteryWarningLevel);
- mLowBatteryReminderLevels[1] = mContext.getResources().getInteger(
+ ContentObserver obs = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateBatteryWarningLevels();
+ }
+ };
+ final ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
+ false, obs, UserHandle.USER_ALL);
+ updateBatteryWarningLevels();
+ mReceiver.init();
+ mObserver.init();
+ }
+
+ private void setSaverMode(boolean mode) {
+ mWarnings.showSaverMode(mode);
+ }
+
+ private void setSaverTrigger(int level) {
+ mWarnings.setSaverTrigger(level);
+ }
+
+ void updateBatteryWarningLevels() {
+ int critLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_criticalBatteryWarningLevel);
- final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mScreenOffTime = pm.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
- mWarnings = new PowerDialogWarnings(mContext);
+ final ContentResolver resolver = mContext.getContentResolver();
+ int defWarnLevel = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_lowBatteryWarningLevel);
+ int warnLevel = Settings.Global.getInt(resolver,
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);
+ if (warnLevel == 0) {
+ warnLevel = defWarnLevel;
+ }
+ if (warnLevel < critLevel) {
+ warnLevel = critLevel;
+ }
- // Register for Intent broadcasts for...
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_BATTERY_CHANGED);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- filter.addAction(Intent.ACTION_SCREEN_ON);
- mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
+ mLowBatteryReminderLevels[0] = warnLevel;
+ mLowBatteryReminderLevels[1] = critLevel;
+ mLowBatteryAlertCloseLevel = mLowBatteryReminderLevels[0]
+ + mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
}
/**
@@ -87,7 +123,7 @@
if (level >= mLowBatteryAlertCloseLevel) {
return 1;
}
- if (level >= mLowBatteryReminderLevels[0]) {
+ if (level > mLowBatteryReminderLevels[0]) {
return 0;
}
final int N = mLowBatteryReminderLevels.length;
@@ -99,7 +135,23 @@
throw new RuntimeException("not possible!");
}
- private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ private final class Receiver extends BroadcastReceiver {
+
+ public void init() {
+ // Register for Intent broadcasts for...
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+ mContext.registerReceiver(this, filter, null, mHandler);
+ updateSaverMode();
+ }
+
+ private void updateSaverMode() {
+ setSaverMode(mPowerManager.isPowerSaveMode());
+ }
+
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -160,6 +212,8 @@
mScreenOffTime = SystemClock.elapsedRealtime();
} else if (Intent.ACTION_SCREEN_ON.equals(action)) {
mScreenOffTime = -1;
+ } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
+ updateSaverMode();
} else {
Slog.w(TAG, "unknown intent: " + intent);
}
@@ -197,6 +251,8 @@
public interface WarningsUI {
void update(int batteryLevel, int bucket, long screenOffTime);
+ void setSaverTrigger(int level);
+ void showSaverMode(boolean mode);
void dismissLowBatteryWarning();
void showLowBatteryWarning(boolean playSound);
void dismissInvalidChargerWarning();
@@ -205,5 +261,29 @@
boolean isInvalidChargerWarningShowing();
void dump(PrintWriter pw);
}
+
+ private final class SettingsObserver extends ContentObserver {
+ private final Uri LOW_POWER_MODE_TRIGGER_LEVEL_URI =
+ Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL);
+
+ public SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ public void init() {
+ onChange(true, LOW_POWER_MODE_TRIGGER_LEVEL_URI);
+ final ContentResolver cr = mContext.getContentResolver();
+ cr.registerContentObserver(LOW_POWER_MODE_TRIGGER_LEVEL_URI, false, this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (LOW_POWER_MODE_TRIGGER_LEVEL_URI.equals(uri)) {
+ final int level = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+ setSaverTrigger(level);
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index c76ee8c..786cd9e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -287,6 +287,7 @@
public boolean activityIn;
public boolean activityOut;
public int overlayIconId;
+ public boolean filter;
@Override
public boolean copyTo(State other) {
@@ -300,6 +301,7 @@
o.activityIn = activityIn;
o.activityOut = activityOut;
o.overlayIconId = overlayIconId;
+ o.filter = filter;
return super.copyTo(other) || changed;
}
@@ -311,6 +313,7 @@
rt.insert(rt.length() - 1, ",activityIn=" + activityIn);
rt.insert(rt.length() - 1, ",activityOut=" + activityOut);
rt.insert(rt.length() - 1, ",overlayIconId=" + overlayIconId);
+ rt.insert(rt.length() - 1, ",filter=" + filter);
return rt;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index 901cc10..d5fe033 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -93,12 +93,12 @@
final SignalState s = (SignalState) state;
mSignal.setImageDrawable(null); // force refresh
mSignal.setImageResource(s.iconId);
- mSignal.setColorFilter(FILTER);
+ mSignal.setColorFilter(s.filter ? FILTER : null);
if (s.overlayIconId > 0) {
mOverlay.setVisibility(VISIBLE);
mOverlay.setImageDrawable(null); // force refresh
mOverlay.setImageResource(s.overlayIconId);
- mOverlay.setColorFilter(FILTER);
+ mOverlay.setColorFilter(s.filter ? FILTER : null);
} else {
mOverlay.setVisibility(GONE);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 182a0ce..6d91d33 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -72,12 +72,15 @@
if (cb == null) return;
final Resources r = mContext.getResources();
- state.iconId = cb.enabled && (cb.mobileSignalIconId > 0)
+ state.iconId = cb.noSim
+ ? R.drawable.stat_sys_no_sim
+ : cb.enabled && (cb.mobileSignalIconId > 0)
? cb.mobileSignalIconId
: R.drawable.ic_qs_signal_no_signal;
state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiEnabled
? cb.dataTypeIconId
: 0;
+ state.filter = state.iconId != R.drawable.stat_sys_no_sim;
state.activityIn = cb.enabled && cb.activityIn;
state.activityOut = cb.enabled && cb.activityOut;
@@ -117,6 +120,7 @@
boolean activityIn;
boolean activityOut;
String enabledDesc;
+ boolean noSim;
}
private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() {
@@ -134,7 +138,7 @@
int mobileSignalIconId,
String mobileSignalContentDescriptionId, int dataTypeIconId,
boolean activityIn, boolean activityOut,
- String dataTypeContentDescriptionId, String description) {
+ String dataTypeContentDescriptionId, String description, boolean noSim) {
final CallbackInfo info = new CallbackInfo(); // TODO pool?
info.enabled = enabled;
info.wifiEnabled = mWifiEnabled;
@@ -145,6 +149,7 @@
info.activityIn = activityIn;
info.activityOut = activityOut;
info.enabledDesc = description;
+ info.noSim = noSim;
refreshState(info);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 5301362..7c2c7c3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -71,6 +71,6 @@
state.visible = mVisible;
state.value = enabled;
state.label = mContext.getString(R.string.quick_settings_inversion_label);
- state.iconId = R.drawable.ic_qs_color_inversion;
+ state.iconId = enabled ? R.drawable.ic_qs_inversion_on : R.drawable.ic_qs_inversion_off;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index db9b054..04f1eb5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -16,9 +16,6 @@
package com.android.systemui.qs.tiles;
-import android.content.res.Resources;
-import android.graphics.drawable.AnimationDrawable;
-
import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
import com.android.systemui.statusbar.policy.LocationController;
@@ -63,28 +60,15 @@
protected void handleUpdateState(BooleanState state, Object arg) {
final boolean locationEnabled = mController.isLocationEnabled();
state.visible = true;
- if (state.value != locationEnabled) {
- state.value = locationEnabled;
- final Resources res = mContext.getResources();
- final AnimationDrawable d = (AnimationDrawable) res.getDrawable(locationEnabled
- ? R.drawable.ic_qs_location_on
- : R.drawable.ic_qs_location_off);
- state.icon = d;
- mUiHandler.post(new Runnable() {
- @Override
- public void run() {
- d.start();
- }
- });
- }
+ state.value = locationEnabled;
if (locationEnabled) {
- if (state.icon == null) state.iconId = R.drawable.ic_qs_location_01;
+ state.iconId = R.drawable.ic_qs_location_on;
state.label = mContext.getString(R.string.quick_settings_location_label);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_location,
mContext.getString(R.string.accessibility_desc_on));
} else {
- if (state.icon == null) state.iconId = R.drawable.ic_qs_location_11;
+ state.iconId = R.drawable.ic_qs_location_off;
state.label = mContext.getString(R.string.quick_settings_location_label);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_location,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 6b73002..a236497 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -87,6 +87,7 @@
state.connected = wifiConnected;
state.activityIn = cb.enabled && cb.activityIn;
state.activityOut = cb.enabled && cb.activityOut;
+ state.filter = true;
final String signalContentDescription;
final Resources r = mContext.getResources();
if (wifiConnected) {
@@ -159,7 +160,7 @@
int mobileSignalIconId,
String mobileSignalContentDescriptionId, int dataTypeIconId,
boolean activityIn, boolean activityOut,
- String dataTypeContentDescriptionId, String description) {
+ String dataTypeContentDescriptionId, String description, boolean noSim) {
// noop
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
index 0c2c11d..113efe3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
@@ -121,6 +121,7 @@
// Send a broadcast to hide recents
Intent intent = new Intent(RecentsService.ACTION_HIDE_RECENTS_ACTIVITY);
intent.setPackage(context.getPackageName());
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
if (msg.arg1 != 0) {
intent.putExtra(RecentsService.EXTRA_TRIGGERED_FROM_ALT_TAB, true);
}
@@ -129,6 +130,7 @@
// Send a broadcast to toggle recents
Intent intent = new Intent(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
intent.setPackage(context.getPackageName());
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
context.sendBroadcast(intent);
// Time this path
@@ -140,6 +142,7 @@
// Send a broadcast to start the enter animation
Intent intent = new Intent(RecentsService.ACTION_START_ENTER_ANIMATION);
intent.setPackage(context.getPackageName());
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
context.sendBroadcast(intent);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index b91e129..8d19f50 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -158,7 +158,7 @@
private final Runnable mTapTimeoutRunnable = new Runnable() {
@Override
public void run() {
- makeInactive();
+ makeInactive(true /* animate */);
}
};
@@ -183,7 +183,7 @@
break;
case MotionEvent.ACTION_MOVE:
if (!isWithinTouchSlop(event)) {
- makeInactive();
+ makeInactive(true /* animate */);
return false;
}
break;
@@ -193,14 +193,17 @@
makeActive();
postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
} else {
- performClick();
+ boolean performed = performClick();
+ if (performed) {
+ removeCallbacks(mTapTimeoutRunnable);
+ }
}
} else {
- makeInactive();
+ makeInactive(true /* animate */);
}
break;
case MotionEvent.ACTION_CANCEL:
- makeInactive();
+ makeInactive(true /* animate */);
break;
default:
break;
@@ -257,10 +260,14 @@
/**
* Cancels the hotspot and makes the notification inactive.
*/
- private void makeInactive() {
+ public void makeInactive(boolean animate) {
if (mActivated) {
if (mDimmed) {
- startActivateAnimation(true /* reverse */);
+ if (animate) {
+ startActivateAnimation(true /* reverse */);
+ } else {
+ mBackgroundNormal.setVisibility(View.INVISIBLE);
+ }
}
mActivated = false;
}
@@ -351,6 +358,7 @@
mBackgroundDimmed.setVisibility(View.INVISIBLE);
mBackgroundNormal.setVisibility(View.VISIBLE);
mBackgroundNormal.setAlpha(1f);
+ removeCallbacks(mTapTimeoutRunnable);
}
}
@@ -581,7 +589,7 @@
}
public interface OnActivatedListener {
- void onActivated(View view);
- void onActivationReset(View view);
+ void onActivated(ActivatableNotificationView view);
+ void onActivationReset(ActivatableNotificationView view);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 508c34e..5a9fe91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -48,7 +48,7 @@
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.Log;
@@ -80,11 +80,10 @@
import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.NotificationData.Entry;
import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
+import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.Locale;
import static com.android.keyguard.KeyguardHostView.OnDismissAction;
@@ -106,6 +105,7 @@
protected static final int MSG_SHOW_HEADS_UP = 1026;
protected static final int MSG_HIDE_HEADS_UP = 1027;
protected static final int MSG_ESCALATE_HEADS_UP = 1028;
+ protected static final int MSG_DECAY_HEADS_UP = 1029;
protected static final boolean ENABLE_HEADS_UP = true;
// scores above this threshold should be displayed in heads up mode.
@@ -129,7 +129,9 @@
protected NotificationData mNotificationData = new NotificationData();
protected NotificationStackScrollLayout mStackScroller;
- protected NotificationData.Entry mInterruptingNotificationEntry;
+ // for heads up notifications
+ protected HeadsUpNotificationView mHeadsUpNotificationView;
+ protected int mHeadsUpNotificationDecay;
protected long mInterruptingNotificationTime;
// used to notify status bar for suppressing notification LED
@@ -291,7 +293,7 @@
public void onListenerConnected() {
if (DEBUG) Log.d(TAG, "onListenerConnected");
final StatusBarNotification[] notifications = getActiveNotifications();
- final Ranking currentRanking = getCurrentRanking();
+ final RankingMap currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -303,41 +305,40 @@
}
@Override
- public void onNotificationPosted(final StatusBarNotification sbn) {
+ public void onNotificationPosted(final StatusBarNotification sbn,
+ final RankingMap rankingMap) {
if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
- final Ranking currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
if (mNotificationData.findByKey(sbn.getKey()) != null) {
- updateNotificationInternal(sbn, currentRanking);
+ updateNotificationInternal(sbn, rankingMap);
} else {
- addNotificationInternal(sbn, currentRanking);
+ addNotificationInternal(sbn, rankingMap);
}
}
});
}
@Override
- public void onNotificationRemoved(final StatusBarNotification sbn) {
+ public void onNotificationRemoved(final StatusBarNotification sbn,
+ final RankingMap rankingMap) {
if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
- final Ranking currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
- removeNotificationInternal(sbn.getKey(), currentRanking);
+ removeNotificationInternal(sbn.getKey(), rankingMap);
}
});
}
@Override
- public void onNotificationRankingUpdate() {
+ public void onNotificationRankingUpdate(final RankingMap rankingMap) {
if (DEBUG) Log.d(TAG, "onRankingUpdate");
- final Ranking currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
- updateRankingInternal(currentRanking);
+ updateRankingInternal(rankingMap);
}
});
}
@@ -505,8 +506,8 @@
protected View updateNotificationVetoButton(View row, StatusBarNotification n) {
View vetoButton = row.findViewById(R.id.veto);
- if (n.isClearable() || (mInterruptingNotificationEntry != null
- && mInterruptingNotificationEntry.row == row)) {
+ if (n.isClearable() || (mHeadsUpNotificationView.getEntry() != null
+ && mHeadsUpNotificationView.getEntry().row == row)) {
final String _pkg = n.getPackageName();
final String _tag = n.getTag();
final int _id = n.getId();
@@ -765,6 +766,12 @@
public abstract void resetHeadsUpDecayTimer();
+ public abstract void scheduleHeadsUpOpen();
+
+ public abstract void scheduleHeadsUpClose();
+
+ public abstract void scheduleHeadsUpEscalation();
+
/**
* Save the current "public" (locked and secure) state of the lockscreen.
*/
@@ -796,6 +803,18 @@
return mUsersAllowingPrivateNotifications.get(userHandle);
}
+ public void onNotificationClear(StatusBarNotification notification) {
+ try {
+ mBarService.onNotificationClear(
+ notification.getPackageName(),
+ notification.getTag(),
+ notification.getId(),
+ notification.getUserId());
+ } catch (android.os.RemoteException ex) {
+ // oh well
+ }
+ }
+
protected class H extends Handler {
public void handleMessage(Message m) {
Intent intent;
@@ -1101,7 +1120,7 @@
try {
if (mIsHeadsUp) {
- mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+ mHeadsUpNotificationView.clear();
}
mBarService.onNotificationClick(mNotificationKey);
} catch (RemoteException ex) {
@@ -1157,7 +1176,7 @@
}
}
- protected StatusBarNotification removeNotificationViews(String key, Ranking ranking) {
+ protected StatusBarNotification removeNotificationViews(String key, RankingMap ranking) {
NotificationData.Entry entry = mNotificationData.remove(key, ranking);
if (entry == null) {
Log.w(TAG, "removeNotification for unknown key: " + key);
@@ -1197,7 +1216,7 @@
return entry;
}
- protected void addNotificationViews(Entry entry, Ranking ranking) {
+ protected void addNotificationViews(Entry entry, RankingMap ranking) {
if (entry == null) {
return;
}
@@ -1206,7 +1225,7 @@
updateNotifications();
}
- private void addNotificationViews(StatusBarNotification notification, Ranking ranking) {
+ private void addNotificationViews(StatusBarNotification notification, RankingMap ranking) {
addNotificationViews(createNotificationViews(notification), ranking);
}
@@ -1292,9 +1311,9 @@
}
public abstract void addNotificationInternal(StatusBarNotification notification,
- Ranking ranking);
+ RankingMap ranking);
- protected abstract void updateRankingInternal(Ranking ranking);
+ protected abstract void updateRankingInternal(RankingMap ranking);
@Override
public void removeNotification(String key) {
@@ -1303,7 +1322,7 @@
}
}
- public abstract void removeNotificationInternal(String key, Ranking ranking);
+ public abstract void removeNotificationInternal(String key, RankingMap ranking);
public void updateNotification(StatusBarNotification notification) {
if (!USE_NOTIFICATION_LISTENER) {
@@ -1311,7 +1330,7 @@
}
}
- public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+ public void updateNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
final NotificationData.Entry oldEntry = mNotificationData.findByKey(notification.getKey());
@@ -1394,15 +1413,15 @@
try {
updateNotificationViews(oldEntry, notification);
- if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null
- && oldNotification == mInterruptingNotificationEntry.notification) {
+ if (ENABLE_HEADS_UP && mHeadsUpNotificationView.getEntry() != null
+ && oldNotification == mHeadsUpNotificationView.getEntry().notification) {
if (!shouldInterrupt(notification)) {
if (DEBUG) Log.d(TAG, "no longer interrupts!");
- mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+ scheduleHeadsUpClose();
} else {
if (DEBUG) Log.d(TAG, "updating the current heads up:" + notification);
- mInterruptingNotificationEntry.notification = notification;
- updateHeadsUpViews(mInterruptingNotificationEntry, notification);
+ mHeadsUpNotificationView.getEntry().notification = notification;
+ updateHeadsUpViews(mHeadsUpNotificationView.getEntry(), notification);
}
}
@@ -1511,8 +1530,8 @@
}
protected void notifyHeadsUpScreenOn(boolean screenOn) {
- if (!screenOn && mInterruptingNotificationEntry != null) {
- mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP);
+ if (!screenOn) {
+ scheduleHeadsUpEscalation();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
index 4233ab8..bfa74fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
@@ -21,6 +21,7 @@
import android.os.Process;
import android.provider.Settings;
import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -58,17 +59,18 @@
updateSyntheticNotification();
}
- public boolean tryIntercept(StatusBarNotification notification, Ranking ranking) {
- if (ranking == null) return false;
+ public boolean tryIntercept(StatusBarNotification notification, RankingMap rankingMap) {
+ if (rankingMap == null) return false;
if (shouldDisplayIntercepted()) return false;
if (mReleased.contains(notification.getKey())) return false;
- if (!ranking.isInterceptedByDoNotDisturb(notification.getKey())) return false;
+ Ranking ranking = rankingMap.getRanking(notification.getKey());
+ if (!ranking.isInterceptedByDoNotDisturb()) return false;
mIntercepted.put(notification.getKey(), notification);
updateSyntheticNotification();
return true;
}
- public void retryIntercepts(Ranking ranking) {
+ public void retryIntercepts(RankingMap ranking) {
if (ranking == null) return;
final int N = mIntercepted.size();
@@ -111,7 +113,7 @@
return;
}
final Notification n = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_qs_zen_on)
+ .setSmallIcon(R.drawable.ic_notify_zen)
.setContentTitle(mContext.getResources().getQuantityString(
R.plurals.zen_mode_notification_title,
mIntercepted.size(), mIntercepted.size()))
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 631e19c..c313c58 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -18,6 +18,7 @@
import android.app.Notification;
import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.view.View;
@@ -70,12 +71,16 @@
}
private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
- private Ranking mRanking;
+ private RankingMap mRanking;
private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() {
@Override
public int compare(Entry a, Entry b) {
if (mRanking != null) {
- return mRanking.getRank(a.key) - mRanking.getRank(b.key);
+ Ranking aRanking = mRanking.getRanking(a.key);
+ Ranking bRanking = mRanking.getRanking(b.key);
+ int aRank = aRanking != null ? aRanking.getRank() : -1;
+ int bRank = bRanking != null ? bRanking.getRank() : -1;
+ return aRank - bRank;
}
final StatusBarNotification na = a.notification;
@@ -108,12 +113,12 @@
return null;
}
- public void add(Entry entry, Ranking ranking) {
+ public void add(Entry entry, RankingMap ranking) {
mEntries.add(entry);
updateRankingAndSort(ranking);
}
- public Entry remove(String key, Ranking ranking) {
+ public Entry remove(String key, RankingMap ranking) {
Entry e = findByKey(key);
if (e == null) {
return null;
@@ -123,7 +128,7 @@
return e;
}
- public void updateRanking(Ranking ranking) {
+ public void updateRanking(RankingMap ranking) {
updateRankingAndSort(ranking);
}
@@ -137,12 +142,13 @@
}
}
} else {
- return mRanking.isAmbient(key);
+ Ranking ranking = mRanking.getRanking(key);
+ return ranking != null && ranking.isAmbient();
}
return false;
}
- private void updateRankingAndSort(Ranking ranking) {
+ private void updateRankingAndSort(RankingMap ranking) {
if (ranking != null) {
mRanking = ranking;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java
deleted file mode 100644
index 1503072..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Outline;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * An single dot of the {@link com.android.systemui.statusbar.SpeedBumpDotsLayout}
- */
-public class SpeedBumpDotView extends View {
-
- private final Paint mPaint = new Paint();
-
- public SpeedBumpDotView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mPaint.setAntiAlias(true);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- float radius = getWidth() / 2.0f;
- canvas.drawCircle(radius, radius, radius, mPaint);
- }
-
- @Override
- public boolean hasOverlappingRendering() {
- return false;
- }
-
- public void setColor(int color) {
- mPaint.setColor(color);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java
deleted file mode 100644
index cac6327..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.content.Context;
-import android.view.View;
-import com.android.systemui.R;
-
-/**
- * The Algorithm of the {@link com.android.systemui.statusbar.SpeedBumpDotsLayout} which can be
- * queried for {@link * com.android.systemui.statusbar.SpeedBumpDotsState}
- */
-public class SpeedBumpDotsAlgorithm {
-
- private final float mDotRadius;
-
- public SpeedBumpDotsAlgorithm(Context context) {
- mDotRadius = context.getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height)
- / 2.0f;
- }
-
- public void getState(SpeedBumpDotsState resultState) {
-
- // First reset the current state and ensure that every View has a ViewState
- resultState.resetViewStates();
-
- SpeedBumpDotsLayout hostView = resultState.getHostView();
- boolean currentlyVisible = hostView.isCurrentlyVisible();
- resultState.setActiveState(currentlyVisible
- ? SpeedBumpDotsState.SHOWN
- : SpeedBumpDotsState.HIDDEN);
- int hostWidth = hostView.getWidth();
- float layoutWidth = hostWidth - 2 * mDotRadius;
- int childCount = hostView.getChildCount();
- float paddingBetween = layoutWidth / (childCount - 1);
- float centerY = hostView.getHeight() / 2.0f;
- for (int i = 0; i < childCount; i++) {
- View child = hostView.getChildAt(i);
- SpeedBumpDotsState.ViewState viewState = resultState.getViewStateForView(child);
- if (currentlyVisible) {
- float xTranslation = i * paddingBetween;
- viewState.xTranslation = xTranslation;
- viewState.yTranslation = calculateYTranslation(hostView, centerY, xTranslation,
- layoutWidth);
- } else {
- viewState.xTranslation = layoutWidth / 2;
- viewState.yTranslation = centerY - mDotRadius;
- }
- viewState.alpha = currentlyVisible ? 1.0f : 0.0f;
- viewState.scale = currentlyVisible ? 1.0f : 0.5f;
- }
- }
-
- private float calculateYTranslation(SpeedBumpDotsLayout hostView, float centerY,
- float xTranslation, float layoutWidth) {
- float t = hostView.getAnimationProgress();
- if (t == 0.0f || t == 1.0f) {
- return centerY - mDotRadius;
- }
- float damping = (0.5f -Math.abs(0.5f - t)) * 1.3f;
- float partialOffset = xTranslation / layoutWidth;
- float indentFactor = (float) (Math.sin((t + partialOffset * 1.5f) * - Math.PI) * damping);
- return (1.0f - indentFactor) * centerY - mDotRadius;
- }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java
deleted file mode 100644
index ddf5215..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.animation.TimeAnimator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import com.android.systemui.R;
-
-/**
- * A layout with a certain number of dots which are integrated in the
- * {@link com.android.systemui.statusbar.SpeedBumpView}
- */
-public class SpeedBumpDotsLayout extends ViewGroup {
-
- private static final float DOT_CLICK_ANIMATION_LENGTH = 300;
- private final int mDotSize;
- private final SpeedBumpDotsAlgorithm mAlgorithm = new SpeedBumpDotsAlgorithm(getContext());
- private final SpeedBumpDotsState mCurrentState = new SpeedBumpDotsState(this);
- private boolean mIsCurrentlyVisible = true;
- private final ValueAnimator mClickAnimator;
- private float mAnimationProgress;
- private ValueAnimator.AnimatorUpdateListener mClickUpdateListener
- = new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mAnimationProgress = animation.getAnimatedFraction();
- updateChildren();
- }
- };
-
- public SpeedBumpDotsLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- mDotSize = getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height);
- createDots(context, attrs);
- mClickAnimator = TimeAnimator.ofFloat(0, DOT_CLICK_ANIMATION_LENGTH);
- mClickAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
- mClickAnimator.addUpdateListener(mClickUpdateListener);
- }
-
- private void createDots(Context context, AttributeSet attrs) {
- SpeedBumpDotView blueDot = new SpeedBumpDotView(context, attrs);
- blueDot.setColor(getResources().getColor(R.color.speed_bump_dot_blue));
- addView(blueDot);
-
- SpeedBumpDotView redDot = new SpeedBumpDotView(context, attrs);
- redDot.setColor(getResources().getColor(R.color.speed_bump_dot_red));
- addView(redDot);
-
- SpeedBumpDotView yellowDot = new SpeedBumpDotView(context, attrs);
- yellowDot.setColor(getResources().getColor(R.color.speed_bump_dot_yellow));
- addView(yellowDot);
-
- SpeedBumpDotView greenDot = new SpeedBumpDotView(context, attrs);
- greenDot.setColor(getResources().getColor(R.color.speed_bump_dot_green));
- addView(greenDot);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int childWidthSpec = MeasureSpec.makeMeasureSpec(mDotSize,
- MeasureSpec.getMode(widthMeasureSpec));
- int childHeightSpec = MeasureSpec.makeMeasureSpec(mDotSize,
- MeasureSpec.getMode(heightMeasureSpec));
- measureChildren(childWidthSpec, childHeightSpec);
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- child.layout(0, 0, mDotSize, mDotSize);
- }
- if (changed) {
- updateChildren();
- }
- }
-
- private void updateChildren() {
- mAlgorithm.getState(mCurrentState);
- mCurrentState.apply();
- }
-
- public void performVisibilityAnimation(boolean visible) {
- if (mClickAnimator.isRunning()) {
- mClickAnimator.cancel();
- }
- mIsCurrentlyVisible = visible;
- mAlgorithm.getState(mCurrentState);
- mCurrentState.animateToState();
- }
-
- public void setInvisible() {
- mIsCurrentlyVisible = false;
- mAlgorithm.getState(mCurrentState);
- mCurrentState.apply();
- }
-
- public boolean isCurrentlyVisible() {
- return mIsCurrentlyVisible;
- }
-
- public void performDotClickAnimation() {
- if (mClickAnimator.isRunning()) {
- // don't perform an animation if it's running already
- return;
- }
- mClickAnimator.start();
- }
-
-
- public float getAnimationProgress() {
- return mAnimationProgress;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java
deleted file mode 100644
index 4febab1..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.view.View;
-import android.view.ViewPropertyAnimator;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A state of a {@link com.android.systemui.statusbar.SpeedBumpDotsLayout}
- */
-public class SpeedBumpDotsState {
-
- public static final int HIDDEN = 1;
- public static final int SHOWN = 2;
- private static final int VISIBILITY_ANIMATION_DELAY_PER_ELEMENT = 80;
-
- private final SpeedBumpDotsLayout mHostView;
- private final HashMap<View, ViewState> mStateMap = new HashMap<View, ViewState>();
- private final Interpolator mFastOutSlowInInterpolator;
- private int mActiveState = 0;
-
- public SpeedBumpDotsState(SpeedBumpDotsLayout hostLayout) {
- mHostView = hostLayout;
- mFastOutSlowInInterpolator = AnimationUtils
- .loadInterpolator(hostLayout.getContext(),
- android.R.interpolator.fast_out_slow_in);
- }
-
- public SpeedBumpDotsLayout getHostView() {
- return mHostView;
- }
-
- public void resetViewStates() {
- int numChildren = mHostView.getChildCount();
- for (int i = 0; i < numChildren; i++) {
- View child = mHostView.getChildAt(i);
- ViewState viewState = mStateMap.get(child);
- if (viewState == null) {
- viewState = new ViewState();
- mStateMap.put(child, viewState);
- }
- }
- }
-
- public ViewState getViewStateForView(View requestedView) {
- return mStateMap.get(requestedView);
- }
-
- public void apply() {
- int childCount = mHostView.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = mHostView.getChildAt(i);
- ViewState viewState = mStateMap.get(child);
-
- child.setTranslationX(viewState.xTranslation);
- child.setTranslationY(viewState.yTranslation);
- child.setScaleX(viewState.scale);
- child.setScaleY(viewState.scale);
- child.setAlpha(viewState.alpha);
- }
- }
-
- public void animateToState() {
- int childCount = mHostView.getChildCount();
- int middleIndex = (childCount - 1) / 2;
- long delayPerElement = VISIBILITY_ANIMATION_DELAY_PER_ELEMENT;
- boolean isAppearing = getActiveState() == SHOWN;
- boolean isDisappearing = getActiveState() == HIDDEN;
- for (int i = 0; i < childCount; i++) {
- int delayIndex;
- if (i <= middleIndex) {
- delayIndex = i * 2;
- } else {
- int distToMiddle = i - middleIndex;
- delayIndex = (childCount - 1) - (distToMiddle - 1) * 2;
- }
- long startDelay = 0;
- if (isAppearing || isDisappearing) {
- if (isDisappearing) {
- delayIndex = childCount - 1 - delayIndex;
- }
- startDelay = delayIndex * delayPerElement;
- }
- View child = mHostView.getChildAt(i);
- ViewState viewState = mStateMap.get(child);
- child.animate().setInterpolator(mFastOutSlowInInterpolator)
- .setStartDelay(startDelay)
- .alpha(viewState.alpha)
- .translationX(viewState.xTranslation)
- .translationY(viewState.yTranslation)
- .scaleX(viewState.scale).scaleY(viewState.scale);
- }
- }
-
- public int getActiveState() {
- return mActiveState;
- }
-
- public void setActiveState(int mActiveState) {
- this.mActiveState = mActiveState;
- }
-
- public static class ViewState {
- float xTranslation;
- float yTranslation;
- float alpha;
- float scale;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
index 689d0e9..f80f0fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
@@ -16,71 +16,26 @@
package com.android.systemui.statusbar;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
import android.content.Context;
-import android.graphics.Outline;
import android.util.AttributeSet;
-import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
-import android.widget.TextView;
import com.android.systemui.R;
/**
* The view representing the separation between important and less important notifications
*/
-public class SpeedBumpView extends ExpandableView implements View.OnClickListener {
+public class SpeedBumpView extends ExpandableView {
- private final int mCollapsedHeight;
- private final int mDotsHeight;
- private final int mTextPaddingInset;
- private SpeedBumpDotsLayout mDots;
- private AlphaOptimizedView mLineLeft;
- private AlphaOptimizedView mLineRight;
- private boolean mIsExpanded;
- private boolean mDividerVisible = true;
- private ValueAnimator mCurrentAnimator;
+ private final int mSpeedBumpHeight;
+ private AlphaOptimizedView mLine;
+ private boolean mIsVisible = true;
private final Interpolator mFastOutSlowInInterpolator;
- private float mCenterX;
- private TextView mExplanationText;
- private boolean mExplanationTextVisible = false;
- private AnimatorListenerAdapter mHideExplanationListener = new AnimatorListenerAdapter() {
- private boolean mCancelled;
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (!mCancelled) {
- mExplanationText.setVisibility(View.INVISIBLE);
- }
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mCancelled = true;
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- mCancelled = false;
- }
- };
- private Animator.AnimatorListener mAnimationFinishedListener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mCurrentAnimator = null;
- }
- };
public SpeedBumpView(Context context, AttributeSet attrs) {
super(context, attrs);
- mCollapsedHeight = getResources()
- .getDimensionPixelSize(R.dimen.speed_bump_height_collapsed);
- mTextPaddingInset = getResources().getDimensionPixelSize(
- R.dimen.speed_bump_text_padding_inset);
- mDotsHeight = getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height);
- setOnClickListener(this);
+ mSpeedBumpHeight = getResources()
+ .getDimensionPixelSize(R.dimen.speed_bump_height);
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
android.R.interpolator.fast_out_slow_in);
}
@@ -88,111 +43,41 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mDots = (SpeedBumpDotsLayout) findViewById(R.id.speed_bump_dots_layout);
- mLineLeft = (AlphaOptimizedView) findViewById(R.id.speedbump_line_left);
- mLineRight = (AlphaOptimizedView) findViewById(R.id.speedbump_line_right);
- mExplanationText = (TextView) findViewById(R.id.speed_bump_text);
- resetExplanationText();
-
+ mLine = (AlphaOptimizedView) findViewById(R.id.speedbump_line);
}
@Override
protected int getInitialHeight() {
- return mCollapsedHeight;
+ return mSpeedBumpHeight;
}
@Override
public int getIntrinsicHeight() {
- if (mCurrentAnimator != null) {
- // expand animation is running
- return getActualHeight();
- }
- return mIsExpanded ? getHeight() : mCollapsedHeight;
+ return mSpeedBumpHeight;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- Outline outline = new Outline();
- mCenterX = getWidth() / 2;
- float centerY = getHeight() / 2;
- // TODO: hide outline better
- // Temporary workaround to hide outline on a transparent view
- int outlineLeft = (int) (mCenterX - getResources().getDisplayMetrics().densityDpi * 8);
- int outlineTop = (int) (centerY - mDotsHeight / 2);
- outline.setOval(outlineLeft, outlineTop, outlineLeft + mDotsHeight,
- outlineTop + mDotsHeight);
- setOutline(outline);
- mLineLeft.setPivotX(mLineLeft.getWidth());
- mLineLeft.setPivotY(mLineLeft.getHeight() / 2);
- mLineRight.setPivotX(0);
- mLineRight.setPivotY(mLineRight.getHeight() / 2);
+ mLine.setPivotX(mLine.getWidth() / 2);
+ mLine.setPivotY(mLine.getHeight() / 2);
+ setOutline(null);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
- int height = mCollapsedHeight + mExplanationText.getMeasuredHeight() - mTextPaddingInset;
+ int height = mSpeedBumpHeight;
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height);
}
@Override
- public void onClick(View v) {
- if (mCurrentAnimator != null) {
- return;
- }
- int startValue = mIsExpanded ? getMaxHeight() : mCollapsedHeight;
- int endValue = mIsExpanded ? mCollapsedHeight : getMaxHeight();
- mCurrentAnimator = ValueAnimator.ofInt(startValue, endValue);
- mCurrentAnimator.setInterpolator(mFastOutSlowInInterpolator);
- mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- setActualHeight((int) animation.getAnimatedValue());
- }
- });
- mCurrentAnimator.addListener(mAnimationFinishedListener);
- mCurrentAnimator.start();
- mIsExpanded = !mIsExpanded;
- mDots.performDotClickAnimation();
- animateExplanationTextInternal(mIsExpanded);
- }
-
- private void animateExplanationTextInternal(boolean visible) {
- if (mExplanationTextVisible != visible) {
- float translationY = 0.0f;
- float scale = 0.5f;
- float alpha = 0.0f;
- boolean needsHideListener = true;
- if (visible) {
- mExplanationText.setVisibility(VISIBLE);
- translationY = mDots.getBottom() - mTextPaddingInset;
- scale = 1.0f;
- alpha = 1.0f;
- needsHideListener = false;
- }
- mExplanationText.animate().setInterpolator(mFastOutSlowInInterpolator)
- .alpha(alpha)
- .scaleX(scale)
- .scaleY(scale)
- .translationY(translationY)
- .setListener(needsHideListener ? mHideExplanationListener : null);
- mExplanationTextVisible = visible;
- }
- }
-
- @Override
public boolean isTransparent() {
return true;
}
public void performVisibilityAnimation(boolean nowVisible) {
animateDivider(nowVisible, null /* onFinishedRunnable */);
-
- // Animate explanation Text
- if (mIsExpanded) {
- animateExplanationTextInternal(nowVisible);
- }
}
/**
@@ -203,28 +88,16 @@
* finished.
*/
public void animateDivider(boolean nowVisible, Runnable onFinishedRunnable) {
- if (nowVisible != mDividerVisible) {
+ if (nowVisible != mIsVisible) {
// Animate dividers
float endValue = nowVisible ? 1.0f : 0.0f;
- float endTranslationXLeft = nowVisible ? 0.0f : mCenterX - mLineLeft.getRight();
- float endTranslationXRight = nowVisible ? 0.0f : mCenterX - mLineRight.getLeft();
- mLineLeft.animate()
+ mLine.animate()
.alpha(endValue)
.scaleX(endValue)
.scaleY(endValue)
- .translationX(endTranslationXLeft)
.setInterpolator(mFastOutSlowInInterpolator)
.withEndAction(onFinishedRunnable);
- mLineRight.animate()
- .alpha(endValue)
- .scaleX(endValue)
- .scaleY(endValue)
- .translationX(endTranslationXRight)
- .setInterpolator(mFastOutSlowInInterpolator);
-
- // Animate dots
- mDots.performVisibilityAnimation(nowVisible);
- mDividerVisible = nowVisible;
+ mIsVisible = nowVisible;
} else {
if (onFinishedRunnable != null) {
onFinishedRunnable.run();
@@ -233,34 +106,10 @@
}
public void setInvisible() {
- float endTranslationXLeft = mCenterX - mLineLeft.getRight();
- float endTranslationXRight = mCenterX - mLineRight.getLeft();
- mLineLeft.setAlpha(0.0f);
- mLineLeft.setScaleX(0.0f);
- mLineLeft.setScaleY(0.0f);
- mLineLeft.setTranslationX(endTranslationXLeft);
- mLineRight.setAlpha(0.0f);
- mLineRight.setScaleX(0.0f);
- mLineRight.setScaleY(0.0f);
- mLineRight.setTranslationX(endTranslationXRight);
- mDots.setInvisible();
- resetExplanationText();
-
- mDividerVisible = false;
- }
-
- public void collapse() {
- if (mIsExpanded) {
- setActualHeight(mCollapsedHeight);
- mIsExpanded = false;
- }
- resetExplanationText();
- }
-
- public void animateExplanationText(boolean nowVisible) {
- if (mIsExpanded) {
- animateExplanationTextInternal(nowVisible);
- }
+ mLine.setAlpha(0.0f);
+ mLine.setScaleX(0.0f);
+ mLine.setScaleY(0.0f);
+ mIsVisible = false;
}
@Override
@@ -272,17 +121,4 @@
public void performAddAnimation(long delay) {
performVisibilityAnimation(true);
}
-
- private void resetExplanationText() {
- mExplanationText.setTranslationY(0);
- mExplanationText.setVisibility(INVISIBLE);
- mExplanationText.setAlpha(0.0f);
- mExplanationText.setScaleX(0.5f);
- mExplanationText.setScaleY(0.5f);
- mExplanationTextVisible = false;
- }
-
- public boolean isExpanded() {
- return mIsExpanded;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
index e312d58..ca49408 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
@@ -246,7 +246,9 @@
private void startHintTranslationAnimations(float target, long duration,
Interpolator interpolator) {
ArrayList<View> targetViews = mCallback.getTranslationViews();
- for (View targetView : targetViews) {
+ int length = targetViews.size();
+ for (int i = 0; i < length; i++) {
+ View targetView = targetViews.get(i);
targetView.animate()
.setDuration(duration)
.setInterpolator(interpolator)
@@ -259,8 +261,16 @@
}
private void cancelAnimations() {
- ArrayList<View> targetViews = mCallback.getTranslationViews();
- for (View target : targetViews) {
+ ArrayList<View> translatingViews = mCallback.getTranslationViews();
+ int length = translatingViews.size();
+ for (int i = 0; i < length; i++) {
+ View target = translatingViews.get(i);
+ target.animate().cancel();
+ }
+ ArrayList<View> fadingViews = mCallback.getFadingViews();
+ length = fadingViews.size();
+ for (int i = 0; i < length; i++) {
+ View target = fadingViews.get(i);
target.animate().cancel();
}
View targetView = mTranslation > 0 ? mLeftIcon : mRightIcon;
@@ -291,6 +301,11 @@
// translation Animation
startTranslationAnimations(vel, target);
+ // fade animations
+ if (snapBack) {
+ startFadeInAnimations();
+ }
+
// animate left / right icon
startIconAnimation(vel, snapBack, target);
@@ -346,9 +361,20 @@
mSwipeAnimator = animator;
}
+ private void startFadeInAnimations() {
+ ArrayList<View> fadingViews = mCallback.getFadingViews();
+ int length = fadingViews.size();
+ for (int i = 0; i < length; i++) {
+ View targetView = fadingViews.get(i);
+ targetView.animate().alpha(1.0f);
+ }
+ }
+
private void startTranslationAnimations(float vel, float target) {
ArrayList<View> targetViews = mCallback.getTranslationViews();
- for (View targetView : targetViews) {
+ int length = targetViews.size();
+ for (int i = 0; i < length; i++) {
+ View targetView = targetViews.get(i);
ViewPropertyAnimator animator = targetView.animate();
mFlingAnimationUtils.apply(animator, mTranslation, target, vel);
animator.translationX(target);
@@ -375,8 +401,18 @@
translation = leftSwipePossible() ? translation : Math.min(0, translation);
if (translation != mTranslation || isReset) {
ArrayList<View> translatedViews = mCallback.getTranslationViews();
- for (View view : translatedViews) {
- view.setTranslationX(translation);
+ int length = translatedViews.size();
+ for (int i = 0; i < length; i++) {
+ View target = translatedViews.get(i);
+ target.setTranslationX(translation);
+ }
+ float targetAlpha = 1.0f - Math.abs(translation / mMinTranslationAmount);
+ targetAlpha = Math.max(0.0f, targetAlpha);
+ ArrayList<View> fadingViews = mCallback.getFadingViews();
+ length = fadingViews.size();
+ for (int i = 0; i < length; i++) {
+ View view = fadingViews.get(i);
+ view.setAlpha(targetAlpha);
}
if (translation == 0.0f) {
boolean animate = !isReset;
@@ -494,6 +530,8 @@
ArrayList<View> getTranslationViews();
+ ArrayList<View> getFadingViews();
+
View getLeftIcon();
View getCenterIcon();
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 45d208e..5c686fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -108,6 +108,7 @@
private KeyguardBottomAreaView mKeyguardBottomArea;
private boolean mBlockTouches;
private ArrayList<View> mSwipeTranslationViews = new ArrayList<>();
+ private ArrayList<View> mSwipeFadingViews = new ArrayList<>();
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -152,7 +153,7 @@
android.R.interpolator.fast_out_linear_in);
mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
mSwipeTranslationViews.add(mNotificationStackScroller);
- mSwipeTranslationViews.add(mKeyguardStatusView);
+ mSwipeFadingViews.add(mKeyguardStatusView);
mPageSwiper = new KeyguardPageSwipeHelper(this, getContext());
}
@@ -963,6 +964,11 @@
}
@Override
+ public ArrayList<View> getFadingViews() {
+ return mSwipeFadingViews;
+ }
+
+ @Override
public View getLeftIcon() {
return getLayoutDirection() == LAYOUT_DIRECTION_RTL
? mKeyguardBottomArea.getCameraImageView()
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 d7b1d35..d413f63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -64,7 +64,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings.Global;
-import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.DisplayMetrics;
@@ -103,6 +103,7 @@
import com.android.systemui.qs.CircularClipper;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.qs.QSTile;
+import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper;
@@ -278,10 +279,6 @@
// the date view
DateView mDateView;
- // for heads up notifications
- private HeadsUpNotificationView mHeadsUpNotificationView;
- private int mHeadsUpNotificationDecay;
-
// on-screen navigation buttons
private NavigationBarView mNavigationBarView = null;
private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
@@ -367,7 +364,7 @@
if (!mUseHeadsUp) {
Log.d(TAG, "dismissing any existing heads up notification on disable event");
setHeadsUpVisibility(false);
- mHeadsUpNotificationView.setNotification(null);
+ mHeadsUpNotificationView.release();
removeHeadsUpView();
} else {
addHeadsUpView();
@@ -1067,7 +1064,7 @@
}
@Override
- public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+ public void addNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
if (mZenMode != Global.ZEN_MODE_OFF && mIntercepted.tryIntercept(notification, ranking)) {
// Forward the ranking so we can sort the new notification.
@@ -1078,31 +1075,28 @@
displayNotification(notification, ranking);
}
- public void displayNotification(StatusBarNotification notification,
- Ranking ranking) {
- Entry shadeEntry = createNotificationViews(notification);
- if (shadeEntry == null) {
- return;
- }
+ public void displayNotification(StatusBarNotification notification, RankingMap ranking) {
if (mUseHeadsUp && shouldInterrupt(notification)) {
if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
Entry interruptionCandidate = new Entry(notification, null);
ViewGroup holder = mHeadsUpNotificationView.getHolder();
if (inflateViewsForHeadsUp(interruptionCandidate, holder)) {
mInterruptingNotificationTime = System.currentTimeMillis();
- mInterruptingNotificationEntry = interruptionCandidate;
- shadeEntry.setInterruption();
// 1. Populate mHeadsUpNotificationView
- mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
+ mHeadsUpNotificationView.showNotification(interruptionCandidate);
- // 2. Animate mHeadsUpNotificationView in
- mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
-
- // 3. Set alarm to age the notification off
- resetHeadsUpDecayTimer();
+ // do not show the notification in the shade, yet.
+ return;
}
- } else if (notification.getNotification().fullScreenIntent != null) {
+ }
+
+ Entry shadeEntry = createNotificationViews(notification);
+ if (shadeEntry == null) {
+ return;
+ }
+
+ if (notification.getNotification().fullScreenIntent != null) {
// Stop screensaver if the notification has a full-screen intent.
// (like an incoming phone call)
awakenDreams();
@@ -1117,7 +1111,7 @@
// usual case: status bar visible & not immersive
// show the ticker if there isn't already a heads up
- if (mInterruptingNotificationEntry == null) {
+ if (mHeadsUpNotificationView.getEntry() == null) {
tick(notification, true);
}
}
@@ -1127,31 +1121,64 @@
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
}
+ public void displayNotificationFromHeadsUp(StatusBarNotification notification) {
+ NotificationData.Entry shadeEntry = createNotificationViews(notification);
+ if (shadeEntry == null) {
+ return;
+ }
+ shadeEntry.setInterruption();
+
+ addNotificationViews(shadeEntry, null);
+ // Recalculate the position of the sliding windows and the titles.
+ setAreThereNotifications();
+ updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+ }
+
@Override
public void resetHeadsUpDecayTimer() {
- mHandler.removeMessages(MSG_HIDE_HEADS_UP);
+ mHandler.removeMessages(MSG_DECAY_HEADS_UP);
if (mUseHeadsUp && mHeadsUpNotificationDecay > 0
&& mHeadsUpNotificationView.isClearable()) {
- mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, mHeadsUpNotificationDecay);
+ mHandler.sendEmptyMessageDelayed(MSG_DECAY_HEADS_UP, mHeadsUpNotificationDecay);
}
}
@Override
- public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+ public void scheduleHeadsUpOpen() {
+ mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
+ }
+
+ @Override
+ public void scheduleHeadsUpClose() {
+ mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+ }
+
+ @Override
+ public void scheduleHeadsUpEscalation() {
+ mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP);
+ }
+
+ @Override
+ public void updateNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
super.updateNotificationInternal(notification, ranking);
// if we're here, then the notification is already in the shade
mIntercepted.remove(notification.getKey());
}
@Override
- protected void updateRankingInternal(Ranking ranking) {
+ protected void updateRankingInternal(RankingMap ranking) {
mNotificationData.updateRanking(ranking);
mIntercepted.retryIntercepts(ranking);
updateNotifications();
}
@Override
- public void removeNotificationInternal(String key, Ranking ranking) {
+ public void removeNotificationInternal(String key, RankingMap ranking) {
+ if (ENABLE_HEADS_UP && mHeadsUpNotificationView.getEntry() != null
+ && key.equals(mHeadsUpNotificationView.getEntry().notification.getKey())) {
+ mHeadsUpNotificationView.clear();
+ }
+
StatusBarNotification old = removeNotificationViews(key, ranking);
if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
@@ -1164,11 +1191,6 @@
// Recalculate the position of the sliding windows and the titles.
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
- if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null
- && old == mInterruptingNotificationEntry.notification) {
- mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
- }
-
if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0
&& !mNotificationPanel.isTracking() && mState != StatusBarState.KEYGUARD) {
animateCollapsePanels();
@@ -1590,7 +1612,12 @@
case MSG_SHOW_HEADS_UP:
setHeadsUpVisibility(true);
break;
+ case MSG_DECAY_HEADS_UP:
+ mHeadsUpNotificationView.release();
+ setHeadsUpVisibility(false);
+ break;
case MSG_HIDE_HEADS_UP:
+ mHeadsUpNotificationView.release();
setHeadsUpVisibility(false);
break;
case MSG_ESCALATE_HEADS_UP:
@@ -1603,8 +1630,9 @@
/** if the interrupting notification had a fullscreen intent, fire it now. */
private void escalateHeadsUp() {
- if (mInterruptingNotificationEntry != null) {
- final StatusBarNotification sbn = mInterruptingNotificationEntry.notification;
+ if (mHeadsUpNotificationView.getEntry() != null) {
+ final StatusBarNotification sbn = mHeadsUpNotificationView.getEntry().notification;
+ mHeadsUpNotificationView.release();
final Notification notification = sbn.getNotification();
if (notification.fullScreenIntent != null) {
if (DEBUG)
@@ -2259,7 +2287,7 @@
pw.print(" mUseHeadsUp=");
pw.println(mUseHeadsUp);
pw.print(" interrupting package: ");
- pw.println(hunStateToString(mInterruptingNotificationEntry));
+ pw.println(hunStateToString(mHeadsUpNotificationView.getEntry()));
dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
if (mNavigationBarView != null) {
pw.print(" mNavigationBarWindowState=");
@@ -2533,26 +2561,10 @@
if (!ENABLE_HEADS_UP) return;
if (DEBUG) Log.v(TAG, (vis ? "showing" : "hiding") + " heads up window");
mHeadsUpNotificationView.setVisibility(vis ? View.VISIBLE : View.GONE);
- if (!vis) {
- if (DEBUG) Log.d(TAG, "setting heads up entry to null");
- mInterruptingNotificationEntry = null;
- }
}
public void onHeadsUpDismissed() {
- if (mInterruptingNotificationEntry == null) return;
- mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
- if (mHeadsUpNotificationView.isClearable()) {
- try {
- mBarService.onNotificationClear(
- mInterruptingNotificationEntry.notification.getPackageName(),
- mInterruptingNotificationEntry.notification.getTag(),
- mInterruptingNotificationEntry.notification.getId(),
- mInterruptingNotificationEntry.notification.getUserId());
- } catch (android.os.RemoteException ex) {
- // oh well
- }
- }
+ mHeadsUpNotificationView.dismiss();
}
/**
@@ -2921,7 +2933,6 @@
mNotificationPanel.setKeyguardShowing(false);
mScrimController.setKeyguardShowing(false);
}
-
updateStackScrollerState();
updatePublicMode();
updateNotifications();
@@ -2937,6 +2948,11 @@
? View.INVISIBLE : View.VISIBLE);
mStackScroller.setScrollingEnabled(!onKeyguard);
mStackScroller.setExpandingEnabled(!onKeyguard);
+ ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
+ mStackScroller.setActivatedChild(null);
+ if (activatedChild != null) {
+ activatedChild.makeInactive(false /* animate */);
+ }
}
public void userActivity() {
@@ -2980,9 +2996,13 @@
}
@Override
- public void onActivated(View view) {
+ public void onActivated(ActivatableNotificationView view) {
userActivity();
mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
+ ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
+ if (previousView != null) {
+ previousView.makeInactive(true /* animate */);
+ }
mStackScroller.setActivatedChild(view);
}
@@ -2995,7 +3015,7 @@
}
@Override
- public void onActivationReset(View view) {
+ public void onActivationReset(ActivatableNotificationView view) {
if (view == mStackScroller.getActivatedChild()) {
mKeyguardIndicationController.hideTransientIndication();
mStackScroller.setActivatedChild(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index df01c12..d778ccb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -33,9 +33,9 @@
import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
import com.android.systemui.SwipeHelper;
-import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.Callback, ExpandHelper.Callback,
ViewTreeObserver.OnComputeInternalInsetsListener {
@@ -51,7 +51,7 @@
private SwipeHelper mSwipeHelper;
private EdgeSwipeHelper mEdgeSwipeHelper;
- private BaseStatusBar mBar;
+ private PhoneStatusBar mBar;
private ExpandHelper mExpandHelper;
private long mStartTouchTime;
@@ -69,7 +69,7 @@
if (DEBUG) Log.v(TAG, "create() " + mTouchSensitivityDelay);
}
- public void setBar(BaseStatusBar bar) {
+ public void setBar(PhoneStatusBar bar) {
mBar = bar;
}
@@ -77,7 +77,10 @@
return mContentHolder;
}
- public boolean setNotification(NotificationData.Entry headsUp) {
+ public boolean showNotification(NotificationData.Entry headsUp) {
+ // bump any previous heads up back to the shade
+ release();
+
mHeadsUp = headsUp;
if (mContentHolder != null) {
mContentHolder.removeAllViews();
@@ -97,10 +100,46 @@
mSwipeHelper.snapChild(mContentHolder, 1f);
mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
+
+ // 2. Animate mHeadsUpNotificationView in
+ mBar.scheduleHeadsUpOpen();
+
+ // 3. Set alarm to age the notification off
+ mBar.resetHeadsUpDecayTimer();
}
return true;
}
+ /** Discard the Heads Up notification. */
+ public void clear() {
+ mHeadsUp = null;
+ mBar.scheduleHeadsUpClose();
+ }
+
+ /** Respond to dismissal of the Heads Up window. */
+ public void dismiss() {
+ if (mHeadsUp == null) return;
+ if (mHeadsUp.notification.isClearable()) {
+ mBar.onNotificationClear(mHeadsUp.notification);
+ } else {
+ release();
+ }
+ mHeadsUp = null;
+ mBar.scheduleHeadsUpClose();
+ }
+
+ /** Push any current Heads Up notification down into the shade. */
+ public void release() {
+ if (mHeadsUp != null) {
+ mBar.displayNotificationFromHeadsUp(mHeadsUp.notification);
+ }
+ mHeadsUp = null;
+ }
+
+ public NotificationData.Entry getEntry() {
+ return mHeadsUp;
+ }
+
public boolean isClearable() {
return mHeadsUp == null || mHeadsUp.notification.isClearable();
}
@@ -125,7 +164,7 @@
if (mHeadsUp != null) {
// whoops, we're on already!
- setNotification(mHeadsUp);
+ showNotification(mHeadsUp);
}
getViewTreeObserver().addOnComputeInternalInsetsListener(this);
@@ -282,6 +321,10 @@
mTmpTwoArray[1] + mContentHolder.getHeight());
}
+ public void escalate() {
+ mBar.scheduleHeadsUpEscalation();
+ }
+
private class EdgeSwipeHelper implements Gefingerpoken {
private static final boolean DEBUG_EDGE_SWIPE = false;
private final float mTouchSlop;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index dc8f315..1f68860 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -30,7 +30,7 @@
void onMobileDataSignalChanged(boolean enabled, int mobileSignalIconId,
String mobileSignalContentDescriptionId, int dataTypeIconId,
boolean activityIn, boolean activityOut,
- String dataTypeContentDescriptionId, String description);
+ String dataTypeContentDescriptionId, String description, boolean noSim);
void onAirplaneModeChanged(boolean enabled);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 56402a5..254a0e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -87,6 +87,7 @@
int mQSDataTypeIconId;
int mAirplaneIconId;
boolean mDataActive;
+ boolean mNoSim;
int mLastSignalLevel;
boolean mShowPhoneRSSIForData = false;
boolean mShowAtLeastThreeGees = false;
@@ -349,18 +350,18 @@
if (isEmergencyOnly()) {
cb.onMobileDataSignalChanged(false, mQSPhoneSignalIconId,
mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
- mContentDescriptionDataType, null);
+ mContentDescriptionDataType, null, mNoSim);
} else {
if (mIsWimaxEnabled && mWimaxConnected) {
// Wimax is special
cb.onMobileDataSignalChanged(true, mQSPhoneSignalIconId,
mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
- mContentDescriptionDataType, mNetworkName);
+ mContentDescriptionDataType, mNetworkName, mNoSim);
} else {
// Normal mobile data
cb.onMobileDataSignalChanged(mHasMobileDataFeature, mQSPhoneSignalIconId,
mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
- mContentDescriptionDataType, mNetworkName);
+ mContentDescriptionDataType, mNetworkName, mNoSim);
}
}
cb.onAirplaneModeChanged(mAirplaneMode);
@@ -736,6 +737,7 @@
// GSM case, we have to check also the sim state
if (mSimState == IccCardConstants.State.READY ||
mSimState == IccCardConstants.State.UNKNOWN) {
+ mNoSim = false;
if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
switch (mDataActivity) {
case TelephonyManager.DATA_ACTIVITY_IN:
@@ -758,6 +760,7 @@
}
} else {
iconId = R.drawable.stat_sys_no_sim;
+ mNoSim = true;
visible = false; // no SIM? no data
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index b21e12c..6d92b05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.stack;
import android.view.View;
+import com.android.systemui.statusbar.ActivatableNotificationView;
import java.util.ArrayList;
@@ -27,7 +28,7 @@
private ArrayList<View> mDraggedViews = new ArrayList<View>();
private int mScrollY;
private boolean mDimmed;
- private View mActivatedChild;
+ private ActivatableNotificationView mActivatedChild;
private float mOverScrollTopAmount;
private float mOverScrollBottomAmount;
private int mSpeedBumpIndex = -1;
@@ -64,7 +65,7 @@
* In dimmed mode, a child can be activated, which happens on the first tap of the double-tap
* interaction. This child is then scaled normally and its background is fully opaque.
*/
- public void setActivatedChild(View activatedChild) {
+ public void setActivatedChild(ActivatableNotificationView activatedChild) {
mActivatedChild = activatedChild;
}
@@ -72,7 +73,7 @@
return mDimmed;
}
- public View getActivatedChild() {
+ public ActivatableNotificationView getActivatedChild() {
return mActivatedChild;
}
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 5ace89f..94472a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -33,6 +33,7 @@
import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
import com.android.systemui.SwipeHelper;
+import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.SpeedBumpView;
@@ -1722,7 +1723,6 @@
mStackScrollAlgorithm.setIsExpanded(isExpanded);
if (!isExpanded) {
mOwnScrollY = 0;
- mSpeedBumpView.collapse();
}
}
@@ -1760,7 +1760,7 @@
/**
* See {@link AmbientState#setActivatedChild}.
*/
- public void setActivatedChild(View activatedChild) {
+ public void setActivatedChild(ActivatableNotificationView activatedChild) {
mAmbientState.setActivatedChild(activatedChild);
if (mAnimationsEnabled) {
mActivateNeedsAnimation = true;
@@ -1769,7 +1769,7 @@
requestChildrenUpdate();
}
- public View getActivatedChild() {
+ public ActivatableNotificationView getActivatedChild() {
return mAmbientState.getActivatedChild();
}
@@ -1791,7 +1791,6 @@
int newVisibility = visible ? VISIBLE : GONE;
mSpeedBumpView.setVisibility(newVisibility);
if (visible) {
- mSpeedBumpView.collapse();
// Make invisible to ensure that the appear animation is played.
mSpeedBumpView.setInvisible();
if (!mIsExpansionChanging) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index 94cb16d..1ad4acc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -160,9 +160,8 @@
}
if(child instanceof SpeedBumpView) {
- float speedBumpEnd = newYTranslation + newHeight;
- performSpeedBumpAnimation(i, (SpeedBumpView) child, speedBumpEnd,
- newYTranslation);
+ float lineEnd = newYTranslation + newHeight / 2;
+ performSpeedBumpAnimation(i, (SpeedBumpView) child, lineEnd);
}
}
}
@@ -183,20 +182,12 @@
child.setClipBounds(mClipRect);
}
- private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd,
- float speedBumpStart) {
+ private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd) {
View nextChild = getNextChildNotGone(i);
if (nextChild != null) {
ViewState nextState = getViewStateForView(nextChild);
- boolean startIsAboveNext = nextState.yTranslation > speedBumpStart;
+ boolean startIsAboveNext = nextState.yTranslation > speedBumpEnd;
speedBump.animateDivider(startIsAboveNext, null /* onFinishedRunnable */);
-
- // handle expanded case
- if (speedBump.isExpanded()) {
- boolean endIsAboveNext = nextState.yTranslation > speedBumpEnd;
- speedBump.animateExplanationText(endIsAboveNext);
- }
-
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index faea8de..9260aac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -17,14 +17,14 @@
package com.android.systemui.statusbar.tv;
import android.os.IBinder;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.BaseStatusBar;
/*
@@ -51,11 +51,11 @@
}
@Override
- public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+ public void addNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
}
@Override
- protected void updateRankingInternal(Ranking ranking) {
+ protected void updateRankingInternal(RankingMap ranking) {
}
@Override
@@ -63,7 +63,7 @@
}
@Override
- public void removeNotificationInternal(String key, Ranking ranking) {
+ public void removeNotificationInternal(String key, RankingMap ranking) {
}
@Override
@@ -147,6 +147,18 @@
}
@Override
+ public void scheduleHeadsUpOpen() {
+ }
+
+ @Override
+ public void scheduleHeadsUpEscalation() {
+ }
+
+ @Override
+ public void scheduleHeadsUpClose() {
+ }
+
+ @Override
protected int getMaxKeyguardNotifications() {
return 0;
}
@@ -164,10 +176,10 @@
}
@Override
- public void onActivated(View view) {
+ public void onActivated(ActivatableNotificationView view) {
}
@Override
- public void onActivationReset(View view) {
+ public void onActivationReset(ActivatableNotificationView view) {
}
}
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index fe5c2ef..aeb195f 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import android.database.ContentObserver;
import android.os.BatteryStats;
import com.android.internal.app.IBatteryStats;
import com.android.server.am.BatteryStatsService;
@@ -149,8 +150,8 @@
com.android.internal.R.integer.config_criticalBatteryWarningLevel);
mLowBatteryWarningLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryWarningLevel);
- mLowBatteryCloseWarningLevel = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);
+ mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
mShutdownBatteryTemperature = mContext.getResources().getInteger(
com.android.internal.R.integer.config_shutdownBatteryTemperature);
@@ -173,11 +174,39 @@
void systemReady() {
// check our power situation now that it is safe to display the shutdown dialog.
synchronized (mLock) {
- shutdownIfNoPowerLocked();
- shutdownIfOverTempLocked();
+ ContentObserver obs = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ synchronized (mLock) {
+ updateBatteryWarningLevelLocked();
+ }
+ }
+ };
+ final ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
+ false, obs, UserHandle.USER_ALL);
+ updateBatteryWarningLevelLocked();
}
}
+ void updateBatteryWarningLevelLocked() {
+ final ContentResolver resolver = mContext.getContentResolver();
+ int defWarnLevel = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_lowBatteryWarningLevel);
+ mLowBatteryWarningLevel = Settings.Global.getInt(resolver,
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);
+ if (mLowBatteryWarningLevel == 0) {
+ mLowBatteryWarningLevel = defWarnLevel;
+ }
+ if (mLowBatteryWarningLevel < mCriticalBatteryLevel) {
+ mLowBatteryWarningLevel = mCriticalBatteryLevel;
+ }
+ mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
+ processValuesLocked(true);
+ }
+
/**
* Returns true if the device is plugged into any of the specified plug types.
*/
@@ -232,7 +261,7 @@
}
}
- public boolean isBatteryLowLocked() {
+ public boolean shouldSendBatteryLowLocked() {
final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE;
final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE;
@@ -299,14 +328,14 @@
if (!mUpdatesStopped) {
mBatteryProps = props;
// Process the new values.
- processValuesLocked();
+ processValuesLocked(false);
} else {
mLastBatteryProps.set(props);
}
}
}
- private void processValuesLocked() {
+ private void processValuesLocked(boolean force) {
boolean logOutlier = false;
long dischargeDuration = 0;
@@ -349,14 +378,14 @@
shutdownIfNoPowerLocked();
shutdownIfOverTempLocked();
- if (mBatteryProps.batteryStatus != mLastBatteryStatus ||
+ if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus ||
mBatteryProps.batteryHealth != mLastBatteryHealth ||
mBatteryProps.batteryPresent != mLastBatteryPresent ||
mBatteryProps.batteryLevel != mLastBatteryLevel ||
mPlugType != mLastPlugType ||
mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
- mInvalidCharger != mLastInvalidCharger) {
+ mInvalidCharger != mLastInvalidCharger)) {
if (mPlugType != mLastPlugType) {
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -400,7 +429,24 @@
logOutlier = true;
}
- mBatteryLevelLow = isBatteryLowLocked();
+ if (!mBatteryLevelLow) {
+ // Should we now switch in to low battery mode?
+ if (mPlugType == BATTERY_PLUGGED_NONE
+ && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel) {
+ mBatteryLevelLow = true;
+ }
+ } else {
+ // Should we now switch out of low battery mode?
+ if (mPlugType != BATTERY_PLUGGED_NONE) {
+ mBatteryLevelLow = false;
+ } else if (mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel) {
+ mBatteryLevelLow = false;
+ } else if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) {
+ // If being forced, the previous state doesn't matter, we will just
+ // absolutely check to see if we are now above the warning level.
+ mBatteryLevelLow = false;
+ }
+ }
sendIntentLocked();
@@ -428,7 +474,7 @@
});
}
- if (mBatteryLevelLow) {
+ if (shouldSendBatteryLowLocked()) {
mSentLowBatteryBroadcast = true;
mHandler.post(new Runnable() {
@Override
@@ -650,7 +696,7 @@
long ident = Binder.clearCallingIdentity();
try {
mUpdatesStopped = true;
- processValuesLocked();
+ processValuesLocked(false);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -664,7 +710,7 @@
if (mUpdatesStopped) {
mUpdatesStopped = false;
mBatteryProps.set(mLastBatteryProps);
- processValuesLocked();
+ processValuesLocked(false);
}
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index bd45761..f66f7ac 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -630,8 +630,8 @@
if (DBG) log("ConnectivityService starting up");
NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
- netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+ netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
mDefaultRequest = new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId());
NetworkRequestInfo nri = new NetworkRequestInfo(null, mDefaultRequest, new Binder(),
NetworkRequestInfo.REQUEST);
@@ -1669,7 +1669,7 @@
continue;
}
- int prefix = destination.getNetworkPrefixLength();
+ int prefix = destination.getPrefixLength();
InetAddress addrMasked = NetworkUtils.getNetworkPart(address, prefix);
InetAddress destMasked = NetworkUtils.getNetworkPart(destination.getAddress(),
prefix);
@@ -1871,7 +1871,7 @@
mNetd.addRoute(netId, r);
}
if (exempt) {
- LinkAddress dest = r.getDestination();
+ LinkAddress dest = r.getDestinationLinkAddress();
if (!mExemptAddresses.contains(dest)) {
mNetd.setHostExemption(dest);
mExemptAddresses.add(dest);
@@ -1904,7 +1904,7 @@
} else {
mNetd.removeRoute(netId, r);
}
- LinkAddress dest = r.getDestination();
+ LinkAddress dest = r.getDestinationLinkAddress();
if (mExemptAddresses.contains(dest)) {
mNetd.clearHostExemption(dest);
mExemptAddresses.remove(dest);
@@ -2691,7 +2691,7 @@
dnsDiff = curLp.compareDnses(newLp);
} else if (newLp != null) {
routeDiff.added = newLp.getAllRoutes();
- dnsDiff.added = newLp.getDnses();
+ dnsDiff.added = newLp.getDnsServers();
}
boolean routesChanged = (routeDiff.removed.size() != 0 || routeDiff.added.size() != 0);
@@ -2915,7 +2915,7 @@
if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
LinkProperties p = nt.getLinkProperties();
if (p == null) return;
- Collection<InetAddress> dnses = p.getDnses();
+ Collection<InetAddress> dnses = p.getDnsServers();
int netId = nt.getNetwork().netId;
if (mNetConfigs[netType].isDefault()) {
String network = nt.getNetworkInfo().getTypeName();
@@ -5625,7 +5625,7 @@
}
private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
- Collection<InetAddress> dnses = newLp.getDnses();
+ Collection<InetAddress> dnses = newLp.getDnsServers();
if (dnses.size() == 0 && mDefaultDns != null) {
dnses = new ArrayList();
dnses.add(mDefaultDns);
@@ -5790,7 +5790,8 @@
isNewDefault = true;
updateActiveDefaultNetwork(newNetwork);
if (newNetwork.linkProperties != null) {
- setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnses());
+ setDefaultDnsSystemProperties(
+ newNetwork.linkProperties.getDnsServers());
} else {
setDefaultDnsSystemProperties(new ArrayList<InetAddress>());
}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index eefe8da..362061e 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -795,7 +795,7 @@
final Command cmd = new Command("interface", "setcfg", iface,
linkAddr.getAddress().getHostAddress(),
- linkAddr.getNetworkPrefixLength());
+ linkAddr.getPrefixLength());
for (String flag : cfg.getFlags()) {
cmd.appendArg(flag);
}
@@ -882,9 +882,9 @@
final Command cmd = new Command("network", "route", action, netId);
// create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
- final LinkAddress la = route.getDestination();
+ final LinkAddress la = route.getDestinationLinkAddress();
cmd.appendArg(route.getInterface());
- cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getNetworkPrefixLength());
+ cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getPrefixLength());
if (route.hasGateway()) {
cmd.appendArg(route.getGateway().getHostAddress());
}
@@ -1697,9 +1697,9 @@
public void setMarkedForwardingRoute(String iface, RouteInfo route) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- LinkAddress dest = route.getDestination();
+ LinkAddress dest = route.getDestinationLinkAddress();
mConnector.execute("interface", "fwmark", "route", "add", iface,
- dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
+ dest.getAddress().getHostAddress(), dest.getPrefixLength());
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
@@ -1709,9 +1709,9 @@
public void clearMarkedForwardingRoute(String iface, RouteInfo route) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- LinkAddress dest = route.getDestination();
+ LinkAddress dest = route.getDestinationLinkAddress();
mConnector.execute("interface", "fwmark", "route", "remove", iface,
- dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
+ dest.getAddress().getHostAddress(), dest.getPrefixLength());
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
@@ -1998,9 +1998,9 @@
final Command cmd = new Command("network", "route", "legacy", uid, action, netId);
// create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
- final LinkAddress la = routeInfo.getDestination();
+ final LinkAddress la = routeInfo.getDestinationLinkAddress();
cmd.appendArg(routeInfo.getInterface());
- cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getNetworkPrefixLength());
+ cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getPrefixLength());
if (routeInfo.hasGateway()) {
cmd.appendArg(routeInfo.getGateway().getHostAddress());
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 70327a6..bd1baac 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6030,6 +6030,9 @@
IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
if (DEBUG_URI_PERMISSION) Slog.v(TAG,
"checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
+ if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
+ return false;
+ }
if (pi.applicationInfo.uid == uid) {
return true;
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index b429b93..fe49371 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -906,6 +906,9 @@
}
startTime = 0;
finishLaunchTickingLocked();
+ if (task != null) {
+ task.hasBeenVisible = true;
+ }
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 35f8f31..196e860 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -45,6 +45,7 @@
import android.app.ActivityManager.RunningTaskInfo;
import android.app.IActivityManager.WaitResult;
import android.app.ResultInfo;
+import android.app.StatusBarManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.IIntentSender;
@@ -73,6 +74,7 @@
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.service.voice.IVoiceInteractionSession;
@@ -88,11 +90,13 @@
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.os.TransferPipe;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.server.LocalServices;
import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
import com.android.server.am.ActivityStack.ActivityState;
import com.android.server.wm.WindowManagerService;
+
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
@@ -128,9 +132,15 @@
static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
+ static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9;
+ static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10;
private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
+ /** Status Bar Service **/
+ private IBinder mToken = new Binder();
+ private IStatusBarService mStatusBarService;
+
// For debugging to make sure the caller when acquiring/releasing our
// wake lock is the system process.
static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
@@ -253,6 +263,21 @@
mLaunchingActivity.setReferenceCounted(false);
}
+ // This function returns a IStatusBarService. The value is from ServiceManager.
+ // getService and is cached.
+ private IStatusBarService getStatusBarService() {
+ synchronized (mService) {
+ if (mStatusBarService == null) {
+ mStatusBarService = IStatusBarService.Stub.asInterface(
+ ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
+ if (mStatusBarService == null) {
+ Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
+ }
+ }
+ return mStatusBarService;
+ }
+ }
+
void setWindowManager(WindowManagerService wm) {
synchronized (mService) {
mWindowManager = wm;
@@ -2953,9 +2978,12 @@
}
void setLockTaskModeLocked(TaskRecord task) {
+ final Message lockTaskMsg = Message.obtain();
if (task == null) {
// Take out of lock task mode.
mLockTaskModeTask = null;
+ lockTaskMsg.what = LOCK_TASK_END_MSG;
+ mHandler.sendMessage(lockTaskMsg);
return;
}
if (isLockTaskModeViolation(task)) {
@@ -2965,6 +2993,8 @@
mLockTaskModeTask = task;
findTaskToMoveToFrontLocked(task, 0, null);
resumeTopActivitiesLocked();
+ lockTaskMsg.what = LOCK_TASK_START_MSG;
+ mHandler.sendMessage(lockTaskMsg);
}
boolean isLockTaskModeViolation(TaskRecord task) {
@@ -3061,6 +3091,32 @@
} catch (RemoteException e) {
}
}
+ case LOCK_TASK_START_MSG: {
+ // When lock task starts, we disable the status bars.
+ try {
+ if (getStatusBarService() != null) {
+ getStatusBarService().disable
+ (StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK,
+ mToken, mService.mContext.getPackageName());
+ }
+ } catch (RemoteException ex) {
+ throw new RuntimeException(ex);
+ }
+ break;
+ }
+ case LOCK_TASK_END_MSG: {
+ // When lock task ends, we enable the status bars.
+ try {
+ if (getStatusBarService() != null) {
+ getStatusBarService().disable
+ (StatusBarManager.DISABLE_NONE,
+ mToken, mService.mContext.getPackageName());
+ }
+ } catch (RemoteException ex) {
+ throw new RuntimeException(ex);
+ }
+ break;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 79e2d9d..81a0b36 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -73,6 +73,7 @@
boolean rootWasReset; // True if the intent at the root of the task had
// the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
boolean askedCompatMode;// Have asked the user about compat mode for this task.
+ boolean hasBeenVisible; // Set if any activities in the task have been visible to the user.
String stringName; // caching of toString() result.
int userId; // user for which this task was created
@@ -328,8 +329,12 @@
}
boolean autoRemoveFromRecents() {
- return intent != null &&
- (intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) != 0;
+ // We will automatically remove the task either if it has explicitly asked for
+ // this, or it is empty and has never contained an activity that got shown to
+ // the user.
+ return (intent != null &&
+ (intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) != 0) ||
+ (mActivities.isEmpty() && !hasBeenVisible);
}
/**
@@ -800,7 +805,8 @@
}
pw.print(prefix); pw.print("lastThumbnail="); pw.print(lastThumbnail);
pw.print(" lastDescription="); pw.println(lastDescription);
- pw.print(prefix); pw.print("lastActiveTime="); pw.print(lastActiveTime);
+ pw.print(prefix); pw.print("hasBeenVisible="); pw.print(hasBeenVisible);
+ pw.print(" lastActiveTime="); pw.print(lastActiveTime);
pw.print(" (inactive for ");
pw.print((getInactiveDuration()/1000)); pw.println("s)");
}
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 92b5f52..bdf4708 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -1344,7 +1344,7 @@
if (iface != null) {
String[] dnsServers = mDefaultDnsServers;
- Collection<InetAddress> dnses = linkProperties.getDnses();
+ Collection<InetAddress> dnses = linkProperties.getDnsServers();
if (dnses != null) {
// we currently only handle IPv4
ArrayList<InetAddress> v4Dnses =
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 835b094..9ae8aed 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -949,6 +949,11 @@
}
@Override
+ public long getFlags() {
+ return mFlags;
+ }
+
+ @Override
public void play() throws RemoteException {
mSessionCb.play();
}
diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java
index aee7679..907eeb2 100644
--- a/services/core/java/com/android/server/net/IpConfigStore.java
+++ b/services/core/java/com/android/server/net/IpConfigStore.java
@@ -81,15 +81,15 @@
for (LinkAddress linkAddr : linkProperties.getLinkAddresses()) {
out.writeUTF(LINK_ADDRESS_KEY);
out.writeUTF(linkAddr.getAddress().getHostAddress());
- out.writeInt(linkAddr.getNetworkPrefixLength());
+ out.writeInt(linkAddr.getPrefixLength());
}
for (RouteInfo route : linkProperties.getRoutes()) {
out.writeUTF(GATEWAY_KEY);
- LinkAddress dest = route.getDestination();
+ LinkAddress dest = route.getDestinationLinkAddress();
if (dest != null) {
out.writeInt(1);
out.writeUTF(dest.getAddress().getHostAddress());
- out.writeInt(dest.getNetworkPrefixLength());
+ out.writeInt(dest.getPrefixLength());
} else {
out.writeInt(0);
}
@@ -100,7 +100,7 @@
out.writeInt(0);
}
}
- for (InetAddress inetAddr : linkProperties.getDnses()) {
+ for (InetAddress inetAddr : linkProperties.getDnsServers()) {
out.writeUTF(DNS_KEY);
out.writeUTF(inetAddr.getHostAddress());
}
@@ -232,7 +232,7 @@
}
linkProperties.addRoute(new RouteInfo(dest, gateway));
} else if (key.equals(DNS_KEY)) {
- linkProperties.addDns(
+ linkProperties.addDnsServer(
NetworkUtils.numericToInetAddress(in.readUTF()));
} else if (key.equals(PROXY_SETTINGS_KEY)) {
proxySettings = ProxySettings.valueOf(in.readUTF());
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 50a32c4..b95db9c 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -18,6 +18,7 @@
import android.app.AlarmManager;
import android.app.AppOpsManager;
+import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -88,6 +89,10 @@
private static final Set<String> ALARM_PACKAGES = new HashSet<String>(Arrays.asList(
"com.google.android.deskclock"
));
+ private static final Set<String> SYSTEM_PACKAGES = new HashSet<String>(Arrays.asList(
+ "android",
+ "com.android.systemui"
+ ));
public ZenModeHelper(Context context, Handler handler) {
mContext = context;
@@ -130,6 +135,9 @@
// notifications never transition from not intercepted to intercepted
return false;
}
+ if (isSystem(record)) {
+ return false;
+ }
if (isAlarm(record)) {
return false;
}
@@ -239,6 +247,11 @@
}
}
+ private boolean isSystem(NotificationRecord record) {
+ return SYSTEM_PACKAGES.contains(record.sbn.getPackageName())
+ && Notification.CATEGORY_SYSTEM.equals(record.getNotification().category);
+ }
+
private boolean isAlarm(NotificationRecord record) {
return ALARM_PACKAGES.contains(record.sbn.getPackageName());
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0c094e8..407ecb8 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4988,6 +4988,7 @@
mResolveActivity.packageName = mAndroidApplication.packageName;
mResolveActivity.processName = "system:ui";
mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+ mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
mResolveActivity.exported = true;
@@ -10203,7 +10204,7 @@
synchronized (mPackages) {
// Check whether the newly-scanned package wants to define an already-defined perm
int N = pkg.permissions.size();
- for (int i = 0; i < N; i++) {
+ for (int i = N-1; i >= 0; i--) {
PackageParser.Permission perm = pkg.permissions.get(i);
BasePermission bp = mSettings.mPermissions.get(perm.info.name);
if (bp != null) {
@@ -10211,13 +10212,23 @@
// also includes the "updating the same package" case, of course.
if (compareSignatures(bp.packageSetting.signatures.mSignatures,
pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
- Slog.w(TAG, "Package " + pkg.packageName
- + " attempting to redeclare permission " + perm.info.name
- + " already owned by " + bp.sourcePackage);
- res.returnCode = PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
- res.origPermission = perm.info.name;
- res.origPackage = bp.sourcePackage;
- return;
+ // If the owning package is the system itself, we log but allow
+ // install to proceed; we fail the install on all other permission
+ // redefinitions.
+ if (!bp.sourcePackage.equals("android")) {
+ Slog.w(TAG, "Package " + pkg.packageName
+ + " attempting to redeclare permission " + perm.info.name
+ + " already owned by " + bp.sourcePackage);
+ res.returnCode = PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
+ res.origPermission = perm.info.name;
+ res.origPackage = bp.sourcePackage;
+ return;
+ } else {
+ Slog.w(TAG, "Package " + pkg.packageName
+ + " attempting to redeclare system permission "
+ + perm.info.name + "; ignoring new declaration");
+ pkg.permissions.remove(i);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index d8671d9..fb4b8f0 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -409,6 +409,9 @@
// Current state of the low power mode setting.
private boolean mLowPowerModeSetting;
+ // Current state of whether the settings are allowing auto low power mode.
+ private boolean mAutoLowPowerModeEnabled;
+
// True if the battery level is currently considered low.
private boolean mBatteryLevelLow;
@@ -558,6 +561,9 @@
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE),
false, mSettingsObserver, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
+ false, mSettingsObserver, UserHandle.USER_ALL);
// Go.
readConfigurationLocked();
updateSettingsLocked();
@@ -645,8 +651,12 @@
final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
Settings.Global.LOW_POWER_MODE, 0) != 0;
- if (lowPowerModeEnabled != mLowPowerModeSetting) {
+ final boolean autoLowPowerModeEnabled = Settings.Global.getInt(resolver,
+ Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 15) != 0;
+ if (lowPowerModeEnabled != mLowPowerModeSetting
+ || autoLowPowerModeEnabled != mAutoLowPowerModeEnabled) {
mLowPowerModeSetting = lowPowerModeEnabled;
+ mAutoLowPowerModeEnabled = autoLowPowerModeEnabled;
updateLowPowerModeLocked();
}
@@ -654,7 +664,8 @@
}
void updateLowPowerModeLocked() {
- final boolean lowPowerModeEnabled = mLowPowerModeSetting || mBatteryLevelLow;
+ final boolean lowPowerModeEnabled = !mIsPowered
+ && (mLowPowerModeSetting || (mAutoLowPowerModeEnabled && mBatteryLevelLow));
if (mLowPowerModeEnabled != lowPowerModeEnabled) {
mLowPowerModeEnabled = lowPowerModeEnabled;
powerHintInternal(POWER_HINT_LOW_POWER_MODE, lowPowerModeEnabled ? 1 : 0);
@@ -1197,7 +1208,7 @@
}
}
- if (oldLevelLow != mBatteryLevelLow) {
+ if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) {
updateLowPowerModeLocked();
}
}
@@ -2168,6 +2179,8 @@
pw.println(" mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
pw.println(" mSandmanScheduled=" + mSandmanScheduled);
pw.println(" mSandmanSummoned=" + mSandmanSummoned);
+ pw.println(" mLowPowerModeEnabled=" + mLowPowerModeEnabled);
+ pw.println(" mBatteryLevelLow=" + mBatteryLevelLow);
pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
pw.println(" mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
@@ -2204,6 +2217,8 @@
pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting);
pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
pw.println(" mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
+ pw.println(" mLowPowerModeSetting=" + mLowPowerModeSetting);
+ pw.println(" mAutoLowPowerModeEnabled=" + mAutoLowPowerModeEnabled);
pw.println(" mMinimumScreenOffTimeoutConfig=" + mMinimumScreenOffTimeoutConfig);
pw.println(" mMaximumScreenDimDurationConfig=" + mMaximumScreenDimDurationConfig);
pw.println(" mMaximumScreenDimRatioConfig=" + mMaximumScreenDimRatioConfig);