Merge "Workaround to avoid polygon flashing DO NOT MERGE" into lmp-preview-dev
diff --git a/api/current.txt b/api/current.txt
index 8b230b6..52b6de3 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
@@ -16017,19 +16019,25 @@
field public int serverAddress;
}
+ public final class IpPrefix implements android.os.Parcelable {
+ method public int describeContents();
+ method public java.net.InetAddress getAddress();
+ 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 class LinkAddress 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 getPrefixLength();
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);
+ 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();
@@ -16119,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
@@ -16207,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 {
@@ -16236,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 {
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/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 cff9025..8eefa0f 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -44,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>();
@@ -77,9 +77,15 @@
}
}
+ /**
+ * @hide
+ */
public LinkProperties() {
}
+ /**
+ * @hide
+ */
public LinkProperties(LinkProperties source) {
if (source != null) {
mIfaceName = source.getInterfaceName();
@@ -267,7 +273,7 @@
}
/**
- * 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 List} of {@link InetAddress} for DNS servers on
* this link.
@@ -457,7 +463,6 @@
/**
* Implement the Parcelable interface
- * @hide
*/
public int describeContents() {
return 0;
@@ -477,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) {
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/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/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/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/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..a959913 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/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/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/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/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/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/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/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 70b9d44..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);
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/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 bb0d5fe..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);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c7dd849..407ecb8 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -10204,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) {
@@ -10212,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);
+ }
}
}
}