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 &gt;= 0 and &lt;= (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);
+                        }
                     }
                 }
             }