Merge "Improve unlock motion." into lmp-preview-dev
diff --git a/api/current.txt b/api/current.txt
index 8953d7e..06acbf4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1858,28 +1858,28 @@
     field public static final int TextAppearance_Large = 16973890; // 0x1030042
     field public static final int TextAppearance_Large_Inverse = 16973891; // 0x1030043
     field public static final int TextAppearance_Material = 16974350; // 0x103020e
-    field public static final int TextAppearance_Material_Body1 = 16974550; // 0x10302d6
-    field public static final int TextAppearance_Material_Body2 = 16974549; // 0x10302d5
-    field public static final int TextAppearance_Material_Button = 16974553; // 0x10302d9
-    field public static final int TextAppearance_Material_Caption = 16974551; // 0x10302d7
+    field public static final int TextAppearance_Material_Body1 = 16974552; // 0x10302d8
+    field public static final int TextAppearance_Material_Body2 = 16974551; // 0x10302d7
+    field public static final int TextAppearance_Material_Button = 16974555; // 0x10302db
+    field public static final int TextAppearance_Material_Caption = 16974553; // 0x10302d9
     field public static final int TextAppearance_Material_DialogWindowTitle = 16974351; // 0x103020f
-    field public static final int TextAppearance_Material_Display1 = 16974545; // 0x10302d1
-    field public static final int TextAppearance_Material_Display2 = 16974544; // 0x10302d0
-    field public static final int TextAppearance_Material_Display3 = 16974543; // 0x10302cf
-    field public static final int TextAppearance_Material_Display4 = 16974542; // 0x10302ce
-    field public static final int TextAppearance_Material_Headline = 16974546; // 0x10302d2
+    field public static final int TextAppearance_Material_Display1 = 16974547; // 0x10302d3
+    field public static final int TextAppearance_Material_Display2 = 16974546; // 0x10302d2
+    field public static final int TextAppearance_Material_Display3 = 16974545; // 0x10302d1
+    field public static final int TextAppearance_Material_Display4 = 16974544; // 0x10302d0
+    field public static final int TextAppearance_Material_Headline = 16974548; // 0x10302d4
     field public static final int TextAppearance_Material_Inverse = 16974352; // 0x1030210
     field public static final int TextAppearance_Material_Large = 16974353; // 0x1030211
     field public static final int TextAppearance_Material_Large_Inverse = 16974354; // 0x1030212
     field public static final int TextAppearance_Material_Medium = 16974355; // 0x1030213
     field public static final int TextAppearance_Material_Medium_Inverse = 16974356; // 0x1030214
-    field public static final int TextAppearance_Material_Menu = 16974552; // 0x10302d8
+    field public static final int TextAppearance_Material_Menu = 16974554; // 0x10302da
     field public static final int TextAppearance_Material_SearchResult_Subtitle = 16974357; // 0x1030215
     field public static final int TextAppearance_Material_SearchResult_Title = 16974358; // 0x1030216
     field public static final int TextAppearance_Material_Small = 16974359; // 0x1030217
     field public static final int TextAppearance_Material_Small_Inverse = 16974360; // 0x1030218
-    field public static final int TextAppearance_Material_Subhead = 16974548; // 0x10302d4
-    field public static final int TextAppearance_Material_Title = 16974547; // 0x10302d3
+    field public static final int TextAppearance_Material_Subhead = 16974550; // 0x10302d6
+    field public static final int TextAppearance_Material_Title = 16974549; // 0x10302d5
     field public static final int TextAppearance_Material_Widget = 16974362; // 0x103021a
     field public static final int TextAppearance_Material_Widget_ActionBar_Menu = 16974363; // 0x103021b
     field public static final int TextAppearance_Material_Widget_ActionBar_Subtitle = 16974364; // 0x103021c
@@ -1928,12 +1928,12 @@
     field public static final int TextAppearance_Widget_TextView_SpinnerItem = 16973906; // 0x1030052
     field public static final int TextAppearance_WindowTitle = 16973907; // 0x1030053
     field public static final int Theme = 16973829; // 0x1030005
-    field public static final int ThemeOverlay = 16974414; // 0x103024e
-    field public static final int ThemeOverlay_Material = 16974415; // 0x103024f
-    field public static final int ThemeOverlay_Material_ActionBar = 16974416; // 0x1030250
-    field public static final int ThemeOverlay_Material_Dark = 16974418; // 0x1030252
-    field public static final int ThemeOverlay_Material_Dark_ActionBar = 16974419; // 0x1030253
-    field public static final int ThemeOverlay_Material_Light = 16974417; // 0x1030251
+    field public static final int ThemeOverlay = 16974416; // 0x1030250
+    field public static final int ThemeOverlay_Material = 16974417; // 0x1030251
+    field public static final int ThemeOverlay_Material_ActionBar = 16974418; // 0x1030252
+    field public static final int ThemeOverlay_Material_Dark = 16974420; // 0x1030254
+    field public static final int ThemeOverlay_Material_Dark_ActionBar = 16974421; // 0x1030255
+    field public static final int ThemeOverlay_Material_Light = 16974419; // 0x1030253
     field public static final int Theme_Black = 16973832; // 0x1030008
     field public static final int Theme_Black_NoTitleBar = 16973833; // 0x1030009
     field public static final int Theme_Black_NoTitleBar_Fullscreen = 16973834; // 0x103000a
@@ -1963,6 +1963,7 @@
     field public static final int Theme_DeviceDefault_NoActionBar_Overscan = 16974303; // 0x10301df
     field public static final int Theme_DeviceDefault_NoActionBar_TranslucentDecor = 16974307; // 0x10301e3
     field public static final int Theme_DeviceDefault_Panel = 16974138; // 0x103013a
+    field public static final int Theme_DeviceDefault_Settings = 16974384; // 0x1030230
     field public static final int Theme_DeviceDefault_Wallpaper = 16974140; // 0x103013c
     field public static final int Theme_DeviceDefault_Wallpaper_NoTitleBar = 16974141; // 0x103013d
     field public static final int Theme_Dialog = 16973835; // 0x103000b
@@ -2000,36 +2001,37 @@
     field public static final int Theme_Light_NoTitleBar_Fullscreen = 16973838; // 0x103000e
     field public static final int Theme_Light_Panel = 16973914; // 0x103005a
     field public static final int Theme_Light_WallpaperSettings = 16973922; // 0x1030062
-    field public static final int Theme_Material = 16974384; // 0x1030230
-    field public static final int Theme_Material_Dialog = 16974385; // 0x1030231
-    field public static final int Theme_Material_DialogWhenLarge = 16974389; // 0x1030235
-    field public static final int Theme_Material_DialogWhenLarge_NoActionBar = 16974390; // 0x1030236
-    field public static final int Theme_Material_Dialog_MinWidth = 16974386; // 0x1030232
-    field public static final int Theme_Material_Dialog_NoActionBar = 16974387; // 0x1030233
-    field public static final int Theme_Material_Dialog_NoActionBar_MinWidth = 16974388; // 0x1030234
-    field public static final int Theme_Material_InputMethod = 16974391; // 0x1030237
-    field public static final int Theme_Material_Light = 16974400; // 0x1030240
-    field public static final int Theme_Material_Light_DarkActionBar = 16974401; // 0x1030241
-    field public static final int Theme_Material_Light_Dialog = 16974402; // 0x1030242
-    field public static final int Theme_Material_Light_DialogWhenLarge = 16974406; // 0x1030246
-    field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974407; // 0x1030247
-    field public static final int Theme_Material_Light_Dialog_MinWidth = 16974403; // 0x1030243
-    field public static final int Theme_Material_Light_Dialog_NoActionBar = 16974404; // 0x1030244
-    field public static final int Theme_Material_Light_Dialog_NoActionBar_MinWidth = 16974405; // 0x1030245
-    field public static final int Theme_Material_Light_NoActionBar = 16974408; // 0x1030248
-    field public static final int Theme_Material_Light_NoActionBar_Fullscreen = 16974409; // 0x1030249
-    field public static final int Theme_Material_Light_NoActionBar_Overscan = 16974410; // 0x103024a
-    field public static final int Theme_Material_Light_NoActionBar_TranslucentDecor = 16974411; // 0x103024b
-    field public static final int Theme_Material_Light_Panel = 16974412; // 0x103024c
-    field public static final int Theme_Material_Light_Voice = 16974413; // 0x103024d
-    field public static final int Theme_Material_NoActionBar = 16974392; // 0x1030238
-    field public static final int Theme_Material_NoActionBar_Fullscreen = 16974393; // 0x1030239
-    field public static final int Theme_Material_NoActionBar_Overscan = 16974394; // 0x103023a
-    field public static final int Theme_Material_NoActionBar_TranslucentDecor = 16974395; // 0x103023b
-    field public static final int Theme_Material_Panel = 16974396; // 0x103023c
-    field public static final int Theme_Material_Voice = 16974397; // 0x103023d
-    field public static final int Theme_Material_Wallpaper = 16974398; // 0x103023e
-    field public static final int Theme_Material_Wallpaper_NoTitleBar = 16974399; // 0x103023f
+    field public static final int Theme_Material = 16974385; // 0x1030231
+    field public static final int Theme_Material_Dialog = 16974386; // 0x1030232
+    field public static final int Theme_Material_DialogWhenLarge = 16974390; // 0x1030236
+    field public static final int Theme_Material_DialogWhenLarge_NoActionBar = 16974391; // 0x1030237
+    field public static final int Theme_Material_Dialog_MinWidth = 16974387; // 0x1030233
+    field public static final int Theme_Material_Dialog_NoActionBar = 16974388; // 0x1030234
+    field public static final int Theme_Material_Dialog_NoActionBar_MinWidth = 16974389; // 0x1030235
+    field public static final int Theme_Material_InputMethod = 16974392; // 0x1030238
+    field public static final int Theme_Material_Light = 16974402; // 0x1030242
+    field public static final int Theme_Material_Light_DarkActionBar = 16974403; // 0x1030243
+    field public static final int Theme_Material_Light_Dialog = 16974404; // 0x1030244
+    field public static final int Theme_Material_Light_DialogWhenLarge = 16974408; // 0x1030248
+    field public static final int Theme_Material_Light_DialogWhenLarge_NoActionBar = 16974409; // 0x1030249
+    field public static final int Theme_Material_Light_Dialog_MinWidth = 16974405; // 0x1030245
+    field public static final int Theme_Material_Light_Dialog_NoActionBar = 16974406; // 0x1030246
+    field public static final int Theme_Material_Light_Dialog_NoActionBar_MinWidth = 16974407; // 0x1030247
+    field public static final int Theme_Material_Light_NoActionBar = 16974410; // 0x103024a
+    field public static final int Theme_Material_Light_NoActionBar_Fullscreen = 16974411; // 0x103024b
+    field public static final int Theme_Material_Light_NoActionBar_Overscan = 16974412; // 0x103024c
+    field public static final int Theme_Material_Light_NoActionBar_TranslucentDecor = 16974413; // 0x103024d
+    field public static final int Theme_Material_Light_Panel = 16974414; // 0x103024e
+    field public static final int Theme_Material_Light_Voice = 16974415; // 0x103024f
+    field public static final int Theme_Material_NoActionBar = 16974393; // 0x1030239
+    field public static final int Theme_Material_NoActionBar_Fullscreen = 16974394; // 0x103023a
+    field public static final int Theme_Material_NoActionBar_Overscan = 16974395; // 0x103023b
+    field public static final int Theme_Material_NoActionBar_TranslucentDecor = 16974396; // 0x103023c
+    field public static final int Theme_Material_Panel = 16974397; // 0x103023d
+    field public static final int Theme_Material_Settings = 16974398; // 0x103023e
+    field public static final int Theme_Material_Voice = 16974399; // 0x103023f
+    field public static final int Theme_Material_Wallpaper = 16974400; // 0x1030240
+    field public static final int Theme_Material_Wallpaper_NoTitleBar = 16974401; // 0x1030241
     field public static final int Theme_NoDisplay = 16973909; // 0x1030055
     field public static final int Theme_NoTitleBar = 16973830; // 0x1030006
     field public static final int Theme_NoTitleBar_Fullscreen = 16973831; // 0x1030007
@@ -2314,128 +2316,128 @@
     field public static final int Widget_ListView_DropDown = 16973872; // 0x1030030
     field public static final int Widget_ListView_Menu = 16973873; // 0x1030031
     field public static final int Widget_ListView_White = 16973871; // 0x103002f
-    field public static final int Widget_Material = 16974420; // 0x1030254
-    field public static final int Widget_Material_ActionBar = 16974421; // 0x1030255
-    field public static final int Widget_Material_ActionBar_Solid = 16974422; // 0x1030256
-    field public static final int Widget_Material_ActionBar_TabBar = 16974423; // 0x1030257
-    field public static final int Widget_Material_ActionBar_TabText = 16974424; // 0x1030258
-    field public static final int Widget_Material_ActionBar_TabView = 16974425; // 0x1030259
-    field public static final int Widget_Material_ActionButton = 16974426; // 0x103025a
-    field public static final int Widget_Material_ActionButton_CloseMode = 16974427; // 0x103025b
-    field public static final int Widget_Material_ActionButton_Overflow = 16974428; // 0x103025c
-    field public static final int Widget_Material_ActionMode = 16974429; // 0x103025d
-    field public static final int Widget_Material_AutoCompleteTextView = 16974430; // 0x103025e
-    field public static final int Widget_Material_Button = 16974431; // 0x103025f
-    field public static final int Widget_Material_ButtonBar = 16974437; // 0x1030265
-    field public static final int Widget_Material_ButtonBar_AlertDialog = 16974438; // 0x1030266
-    field public static final int Widget_Material_Button_Borderless = 16974432; // 0x1030260
-    field public static final int Widget_Material_Button_Borderless_Small = 16974433; // 0x1030261
-    field public static final int Widget_Material_Button_Inset = 16974434; // 0x1030262
-    field public static final int Widget_Material_Button_Small = 16974435; // 0x1030263
-    field public static final int Widget_Material_Button_Toggle = 16974436; // 0x1030264
-    field public static final int Widget_Material_CalendarView = 16974439; // 0x1030267
-    field public static final int Widget_Material_CheckedTextView = 16974440; // 0x1030268
-    field public static final int Widget_Material_CompoundButton_CheckBox = 16974441; // 0x1030269
-    field public static final int Widget_Material_CompoundButton_RadioButton = 16974442; // 0x103026a
-    field public static final int Widget_Material_CompoundButton_Star = 16974443; // 0x103026b
-    field public static final int Widget_Material_DatePicker = 16974444; // 0x103026c
-    field public static final int Widget_Material_DropDownItem = 16974445; // 0x103026d
-    field public static final int Widget_Material_DropDownItem_Spinner = 16974446; // 0x103026e
-    field public static final int Widget_Material_EditText = 16974447; // 0x103026f
-    field public static final int Widget_Material_ExpandableListView = 16974448; // 0x1030270
-    field public static final int Widget_Material_FastScroll = 16974449; // 0x1030271
-    field public static final int Widget_Material_GridView = 16974450; // 0x1030272
-    field public static final int Widget_Material_HorizontalScrollView = 16974451; // 0x1030273
-    field public static final int Widget_Material_ImageButton = 16974452; // 0x1030274
-    field public static final int Widget_Material_Light = 16974481; // 0x1030291
-    field public static final int Widget_Material_Light_ActionBar = 16974482; // 0x1030292
-    field public static final int Widget_Material_Light_ActionBar_Solid = 16974483; // 0x1030293
-    field public static final int Widget_Material_Light_ActionBar_TabBar = 16974484; // 0x1030294
-    field public static final int Widget_Material_Light_ActionBar_TabText = 16974485; // 0x1030295
-    field public static final int Widget_Material_Light_ActionBar_TabView = 16974486; // 0x1030296
-    field public static final int Widget_Material_Light_ActionButton = 16974487; // 0x1030297
-    field public static final int Widget_Material_Light_ActionButton_CloseMode = 16974488; // 0x1030298
-    field public static final int Widget_Material_Light_ActionButton_Overflow = 16974489; // 0x1030299
-    field public static final int Widget_Material_Light_ActionMode = 16974490; // 0x103029a
-    field public static final int Widget_Material_Light_AutoCompleteTextView = 16974491; // 0x103029b
-    field public static final int Widget_Material_Light_Button = 16974492; // 0x103029c
-    field public static final int Widget_Material_Light_ButtonBar = 16974498; // 0x10302a2
-    field public static final int Widget_Material_Light_ButtonBar_AlertDialog = 16974499; // 0x10302a3
-    field public static final int Widget_Material_Light_Button_Borderless = 16974493; // 0x103029d
-    field public static final int Widget_Material_Light_Button_Borderless_Small = 16974494; // 0x103029e
-    field public static final int Widget_Material_Light_Button_Inset = 16974495; // 0x103029f
-    field public static final int Widget_Material_Light_Button_Small = 16974496; // 0x10302a0
-    field public static final int Widget_Material_Light_Button_Toggle = 16974497; // 0x10302a1
-    field public static final int Widget_Material_Light_CalendarView = 16974500; // 0x10302a4
-    field public static final int Widget_Material_Light_CheckedTextView = 16974501; // 0x10302a5
-    field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974502; // 0x10302a6
-    field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974503; // 0x10302a7
-    field public static final int Widget_Material_Light_CompoundButton_Star = 16974504; // 0x10302a8
-    field public static final int Widget_Material_Light_DropDownItem = 16974505; // 0x10302a9
-    field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974506; // 0x10302aa
-    field public static final int Widget_Material_Light_EditText = 16974507; // 0x10302ab
-    field public static final int Widget_Material_Light_ExpandableListView = 16974508; // 0x10302ac
-    field public static final int Widget_Material_Light_FastScroll = 16974509; // 0x10302ad
-    field public static final int Widget_Material_Light_GridView = 16974510; // 0x10302ae
-    field public static final int Widget_Material_Light_HorizontalScrollView = 16974511; // 0x10302af
-    field public static final int Widget_Material_Light_ImageButton = 16974512; // 0x10302b0
-    field public static final int Widget_Material_Light_ListPopupWindow = 16974513; // 0x10302b1
-    field public static final int Widget_Material_Light_ListView = 16974514; // 0x10302b2
-    field public static final int Widget_Material_Light_ListView_DropDown = 16974515; // 0x10302b3
-    field public static final int Widget_Material_Light_MediaRouteButton = 16974516; // 0x10302b4
-    field public static final int Widget_Material_Light_PopupMenu = 16974517; // 0x10302b5
-    field public static final int Widget_Material_Light_PopupMenu_Overflow = 16974518; // 0x10302b6
-    field public static final int Widget_Material_Light_PopupWindow = 16974519; // 0x10302b7
-    field public static final int Widget_Material_Light_ProgressBar = 16974520; // 0x10302b8
-    field public static final int Widget_Material_Light_ProgressBar_Horizontal = 16974521; // 0x10302b9
-    field public static final int Widget_Material_Light_ProgressBar_Inverse = 16974522; // 0x10302ba
-    field public static final int Widget_Material_Light_ProgressBar_Large = 16974523; // 0x10302bb
-    field public static final int Widget_Material_Light_ProgressBar_Large_Inverse = 16974524; // 0x10302bc
-    field public static final int Widget_Material_Light_ProgressBar_Small = 16974525; // 0x10302bd
-    field public static final int Widget_Material_Light_ProgressBar_Small_Inverse = 16974526; // 0x10302be
-    field public static final int Widget_Material_Light_ProgressBar_Small_Title = 16974527; // 0x10302bf
-    field public static final int Widget_Material_Light_RatingBar = 16974528; // 0x10302c0
-    field public static final int Widget_Material_Light_RatingBar_Indicator = 16974529; // 0x10302c1
-    field public static final int Widget_Material_Light_RatingBar_Small = 16974530; // 0x10302c2
-    field public static final int Widget_Material_Light_ScrollView = 16974531; // 0x10302c3
-    field public static final int Widget_Material_Light_SeekBar = 16974532; // 0x10302c4
-    field public static final int Widget_Material_Light_SegmentedButton = 16974533; // 0x10302c5
-    field public static final int Widget_Material_Light_Spinner = 16974535; // 0x10302c7
-    field public static final int Widget_Material_Light_StackView = 16974534; // 0x10302c6
-    field public static final int Widget_Material_Light_Tab = 16974536; // 0x10302c8
-    field public static final int Widget_Material_Light_TabWidget = 16974537; // 0x10302c9
-    field public static final int Widget_Material_Light_TextView = 16974538; // 0x10302ca
-    field public static final int Widget_Material_Light_TextView_SpinnerItem = 16974539; // 0x10302cb
-    field public static final int Widget_Material_Light_WebTextView = 16974540; // 0x10302cc
-    field public static final int Widget_Material_Light_WebView = 16974541; // 0x10302cd
-    field public static final int Widget_Material_ListPopupWindow = 16974453; // 0x1030275
-    field public static final int Widget_Material_ListView = 16974454; // 0x1030276
-    field public static final int Widget_Material_ListView_DropDown = 16974455; // 0x1030277
-    field public static final int Widget_Material_MediaRouteButton = 16974456; // 0x1030278
-    field public static final int Widget_Material_PopupMenu = 16974457; // 0x1030279
-    field public static final int Widget_Material_PopupMenu_Overflow = 16974458; // 0x103027a
-    field public static final int Widget_Material_PopupWindow = 16974459; // 0x103027b
-    field public static final int Widget_Material_ProgressBar = 16974460; // 0x103027c
-    field public static final int Widget_Material_ProgressBar_Horizontal = 16974461; // 0x103027d
-    field public static final int Widget_Material_ProgressBar_Large = 16974462; // 0x103027e
-    field public static final int Widget_Material_ProgressBar_Small = 16974463; // 0x103027f
-    field public static final int Widget_Material_ProgressBar_Small_Title = 16974464; // 0x1030280
-    field public static final int Widget_Material_RatingBar = 16974465; // 0x1030281
-    field public static final int Widget_Material_RatingBar_Indicator = 16974466; // 0x1030282
-    field public static final int Widget_Material_RatingBar_Small = 16974467; // 0x1030283
-    field public static final int Widget_Material_ScrollView = 16974468; // 0x1030284
-    field public static final int Widget_Material_SeekBar = 16974469; // 0x1030285
-    field public static final int Widget_Material_SegmentedButton = 16974470; // 0x1030286
-    field public static final int Widget_Material_Spinner = 16974472; // 0x1030288
-    field public static final int Widget_Material_StackView = 16974471; // 0x1030287
-    field public static final int Widget_Material_Tab = 16974473; // 0x1030289
-    field public static final int Widget_Material_TabWidget = 16974474; // 0x103028a
-    field public static final int Widget_Material_TextView = 16974475; // 0x103028b
-    field public static final int Widget_Material_TextView_SpinnerItem = 16974476; // 0x103028c
-    field public static final int Widget_Material_Toolbar = 16974477; // 0x103028d
-    field public static final int Widget_Material_Toolbar_Button_Navigation = 16974478; // 0x103028e
-    field public static final int Widget_Material_WebTextView = 16974479; // 0x103028f
-    field public static final int Widget_Material_WebView = 16974480; // 0x1030290
+    field public static final int Widget_Material = 16974422; // 0x1030256
+    field public static final int Widget_Material_ActionBar = 16974423; // 0x1030257
+    field public static final int Widget_Material_ActionBar_Solid = 16974424; // 0x1030258
+    field public static final int Widget_Material_ActionBar_TabBar = 16974425; // 0x1030259
+    field public static final int Widget_Material_ActionBar_TabText = 16974426; // 0x103025a
+    field public static final int Widget_Material_ActionBar_TabView = 16974427; // 0x103025b
+    field public static final int Widget_Material_ActionButton = 16974428; // 0x103025c
+    field public static final int Widget_Material_ActionButton_CloseMode = 16974429; // 0x103025d
+    field public static final int Widget_Material_ActionButton_Overflow = 16974430; // 0x103025e
+    field public static final int Widget_Material_ActionMode = 16974431; // 0x103025f
+    field public static final int Widget_Material_AutoCompleteTextView = 16974432; // 0x1030260
+    field public static final int Widget_Material_Button = 16974433; // 0x1030261
+    field public static final int Widget_Material_ButtonBar = 16974439; // 0x1030267
+    field public static final int Widget_Material_ButtonBar_AlertDialog = 16974440; // 0x1030268
+    field public static final int Widget_Material_Button_Borderless = 16974434; // 0x1030262
+    field public static final int Widget_Material_Button_Borderless_Small = 16974435; // 0x1030263
+    field public static final int Widget_Material_Button_Inset = 16974436; // 0x1030264
+    field public static final int Widget_Material_Button_Small = 16974437; // 0x1030265
+    field public static final int Widget_Material_Button_Toggle = 16974438; // 0x1030266
+    field public static final int Widget_Material_CalendarView = 16974441; // 0x1030269
+    field public static final int Widget_Material_CheckedTextView = 16974442; // 0x103026a
+    field public static final int Widget_Material_CompoundButton_CheckBox = 16974443; // 0x103026b
+    field public static final int Widget_Material_CompoundButton_RadioButton = 16974444; // 0x103026c
+    field public static final int Widget_Material_CompoundButton_Star = 16974445; // 0x103026d
+    field public static final int Widget_Material_DatePicker = 16974446; // 0x103026e
+    field public static final int Widget_Material_DropDownItem = 16974447; // 0x103026f
+    field public static final int Widget_Material_DropDownItem_Spinner = 16974448; // 0x1030270
+    field public static final int Widget_Material_EditText = 16974449; // 0x1030271
+    field public static final int Widget_Material_ExpandableListView = 16974450; // 0x1030272
+    field public static final int Widget_Material_FastScroll = 16974451; // 0x1030273
+    field public static final int Widget_Material_GridView = 16974452; // 0x1030274
+    field public static final int Widget_Material_HorizontalScrollView = 16974453; // 0x1030275
+    field public static final int Widget_Material_ImageButton = 16974454; // 0x1030276
+    field public static final int Widget_Material_Light = 16974483; // 0x1030293
+    field public static final int Widget_Material_Light_ActionBar = 16974484; // 0x1030294
+    field public static final int Widget_Material_Light_ActionBar_Solid = 16974485; // 0x1030295
+    field public static final int Widget_Material_Light_ActionBar_TabBar = 16974486; // 0x1030296
+    field public static final int Widget_Material_Light_ActionBar_TabText = 16974487; // 0x1030297
+    field public static final int Widget_Material_Light_ActionBar_TabView = 16974488; // 0x1030298
+    field public static final int Widget_Material_Light_ActionButton = 16974489; // 0x1030299
+    field public static final int Widget_Material_Light_ActionButton_CloseMode = 16974490; // 0x103029a
+    field public static final int Widget_Material_Light_ActionButton_Overflow = 16974491; // 0x103029b
+    field public static final int Widget_Material_Light_ActionMode = 16974492; // 0x103029c
+    field public static final int Widget_Material_Light_AutoCompleteTextView = 16974493; // 0x103029d
+    field public static final int Widget_Material_Light_Button = 16974494; // 0x103029e
+    field public static final int Widget_Material_Light_ButtonBar = 16974500; // 0x10302a4
+    field public static final int Widget_Material_Light_ButtonBar_AlertDialog = 16974501; // 0x10302a5
+    field public static final int Widget_Material_Light_Button_Borderless = 16974495; // 0x103029f
+    field public static final int Widget_Material_Light_Button_Borderless_Small = 16974496; // 0x10302a0
+    field public static final int Widget_Material_Light_Button_Inset = 16974497; // 0x10302a1
+    field public static final int Widget_Material_Light_Button_Small = 16974498; // 0x10302a2
+    field public static final int Widget_Material_Light_Button_Toggle = 16974499; // 0x10302a3
+    field public static final int Widget_Material_Light_CalendarView = 16974502; // 0x10302a6
+    field public static final int Widget_Material_Light_CheckedTextView = 16974503; // 0x10302a7
+    field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974504; // 0x10302a8
+    field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974505; // 0x10302a9
+    field public static final int Widget_Material_Light_CompoundButton_Star = 16974506; // 0x10302aa
+    field public static final int Widget_Material_Light_DropDownItem = 16974507; // 0x10302ab
+    field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974508; // 0x10302ac
+    field public static final int Widget_Material_Light_EditText = 16974509; // 0x10302ad
+    field public static final int Widget_Material_Light_ExpandableListView = 16974510; // 0x10302ae
+    field public static final int Widget_Material_Light_FastScroll = 16974511; // 0x10302af
+    field public static final int Widget_Material_Light_GridView = 16974512; // 0x10302b0
+    field public static final int Widget_Material_Light_HorizontalScrollView = 16974513; // 0x10302b1
+    field public static final int Widget_Material_Light_ImageButton = 16974514; // 0x10302b2
+    field public static final int Widget_Material_Light_ListPopupWindow = 16974515; // 0x10302b3
+    field public static final int Widget_Material_Light_ListView = 16974516; // 0x10302b4
+    field public static final int Widget_Material_Light_ListView_DropDown = 16974517; // 0x10302b5
+    field public static final int Widget_Material_Light_MediaRouteButton = 16974518; // 0x10302b6
+    field public static final int Widget_Material_Light_PopupMenu = 16974519; // 0x10302b7
+    field public static final int Widget_Material_Light_PopupMenu_Overflow = 16974520; // 0x10302b8
+    field public static final int Widget_Material_Light_PopupWindow = 16974521; // 0x10302b9
+    field public static final int Widget_Material_Light_ProgressBar = 16974522; // 0x10302ba
+    field public static final int Widget_Material_Light_ProgressBar_Horizontal = 16974523; // 0x10302bb
+    field public static final int Widget_Material_Light_ProgressBar_Inverse = 16974524; // 0x10302bc
+    field public static final int Widget_Material_Light_ProgressBar_Large = 16974525; // 0x10302bd
+    field public static final int Widget_Material_Light_ProgressBar_Large_Inverse = 16974526; // 0x10302be
+    field public static final int Widget_Material_Light_ProgressBar_Small = 16974527; // 0x10302bf
+    field public static final int Widget_Material_Light_ProgressBar_Small_Inverse = 16974528; // 0x10302c0
+    field public static final int Widget_Material_Light_ProgressBar_Small_Title = 16974529; // 0x10302c1
+    field public static final int Widget_Material_Light_RatingBar = 16974530; // 0x10302c2
+    field public static final int Widget_Material_Light_RatingBar_Indicator = 16974531; // 0x10302c3
+    field public static final int Widget_Material_Light_RatingBar_Small = 16974532; // 0x10302c4
+    field public static final int Widget_Material_Light_ScrollView = 16974533; // 0x10302c5
+    field public static final int Widget_Material_Light_SeekBar = 16974534; // 0x10302c6
+    field public static final int Widget_Material_Light_SegmentedButton = 16974535; // 0x10302c7
+    field public static final int Widget_Material_Light_Spinner = 16974537; // 0x10302c9
+    field public static final int Widget_Material_Light_StackView = 16974536; // 0x10302c8
+    field public static final int Widget_Material_Light_Tab = 16974538; // 0x10302ca
+    field public static final int Widget_Material_Light_TabWidget = 16974539; // 0x10302cb
+    field public static final int Widget_Material_Light_TextView = 16974540; // 0x10302cc
+    field public static final int Widget_Material_Light_TextView_SpinnerItem = 16974541; // 0x10302cd
+    field public static final int Widget_Material_Light_WebTextView = 16974542; // 0x10302ce
+    field public static final int Widget_Material_Light_WebView = 16974543; // 0x10302cf
+    field public static final int Widget_Material_ListPopupWindow = 16974455; // 0x1030277
+    field public static final int Widget_Material_ListView = 16974456; // 0x1030278
+    field public static final int Widget_Material_ListView_DropDown = 16974457; // 0x1030279
+    field public static final int Widget_Material_MediaRouteButton = 16974458; // 0x103027a
+    field public static final int Widget_Material_PopupMenu = 16974459; // 0x103027b
+    field public static final int Widget_Material_PopupMenu_Overflow = 16974460; // 0x103027c
+    field public static final int Widget_Material_PopupWindow = 16974461; // 0x103027d
+    field public static final int Widget_Material_ProgressBar = 16974462; // 0x103027e
+    field public static final int Widget_Material_ProgressBar_Horizontal = 16974463; // 0x103027f
+    field public static final int Widget_Material_ProgressBar_Large = 16974464; // 0x1030280
+    field public static final int Widget_Material_ProgressBar_Small = 16974465; // 0x1030281
+    field public static final int Widget_Material_ProgressBar_Small_Title = 16974466; // 0x1030282
+    field public static final int Widget_Material_RatingBar = 16974467; // 0x1030283
+    field public static final int Widget_Material_RatingBar_Indicator = 16974468; // 0x1030284
+    field public static final int Widget_Material_RatingBar_Small = 16974469; // 0x1030285
+    field public static final int Widget_Material_ScrollView = 16974470; // 0x1030286
+    field public static final int Widget_Material_SeekBar = 16974471; // 0x1030287
+    field public static final int Widget_Material_SegmentedButton = 16974472; // 0x1030288
+    field public static final int Widget_Material_Spinner = 16974474; // 0x103028a
+    field public static final int Widget_Material_StackView = 16974473; // 0x1030289
+    field public static final int Widget_Material_Tab = 16974475; // 0x103028b
+    field public static final int Widget_Material_TabWidget = 16974476; // 0x103028c
+    field public static final int Widget_Material_TextView = 16974477; // 0x103028d
+    field public static final int Widget_Material_TextView_SpinnerItem = 16974478; // 0x103028e
+    field public static final int Widget_Material_Toolbar = 16974479; // 0x103028f
+    field public static final int Widget_Material_Toolbar_Button_Navigation = 16974480; // 0x1030290
+    field public static final int Widget_Material_WebTextView = 16974481; // 0x1030291
+    field public static final int Widget_Material_WebView = 16974482; // 0x1030292
     field public static final int Widget_PopupMenu = 16973958; // 0x1030086
     field public static final int Widget_PopupWindow = 16973878; // 0x1030036
     field public static final int Widget_ProgressBar = 16973852; // 0x103001c
@@ -3335,6 +3337,7 @@
     method public void openContextMenu(android.view.View);
     method public void openOptionsMenu();
     method public void overridePendingTransition(int, int);
+    method public void postponeEnterTransition();
     method public void recreate();
     method public void registerForContextMenu(android.view.View);
     method public final deprecated void removeDialog(int);
@@ -3390,6 +3393,7 @@
     method public deprecated void startManagingCursor(android.database.Cursor);
     method public boolean startNextMatchingActivity(android.content.Intent);
     method public boolean startNextMatchingActivity(android.content.Intent, android.os.Bundle);
+    method public void startPostponedEnterTransition();
     method public void startSearch(java.lang.String, boolean, android.os.Bundle, boolean);
     method public void stopLockTask();
     method public deprecated void stopManagingCursor(android.database.Cursor);
@@ -16015,46 +16019,34 @@
     field public int serverAddress;
   }
 
-  public class LinkAddress implements android.os.Parcelable {
+  public final class IpPrefix implements android.os.Parcelable {
     method public int describeContents();
     method public java.net.InetAddress getAddress();
-    method public int getFlags();
-    method public int getNetworkPrefixLength();
-    method public int getScope();
-    method public boolean isSameAddressAs(android.net.LinkAddress);
-    method public void writeToParcel(android.os.Parcel, int);
-  }
-
-  public class LinkProperties implements android.os.Parcelable {
-    ctor public LinkProperties();
-    ctor public LinkProperties(android.net.LinkProperties);
-    method public void addDns(java.net.InetAddress);
-    method public boolean addLinkAddress(android.net.LinkAddress);
-    method public void addRoute(android.net.RouteInfo);
-    method public void clear();
-    method public int describeContents();
-    method public java.util.Collection<java.lang.String> getAllInterfaceNames();
-    method public java.util.Collection<java.net.InetAddress> getDnses();
-    method public java.lang.String getDomains();
-    method public android.net.ProxyInfo getHttpProxy();
-    method public java.lang.String getInterfaceName();
-    method public java.util.Collection<android.net.LinkAddress> getLinkAddresses();
-    method public java.util.Collection<android.net.RouteInfo> getRoutes();
-    method public boolean hasIPv4Address();
-    method public boolean hasIPv6Address();
-    method public boolean removeLinkAddress(android.net.LinkAddress);
-    method public void setDomains(java.lang.String);
-    method public void setHttpProxy(android.net.ProxyInfo);
-    method public void setInterfaceName(java.lang.String);
-    method public void setLinkAddresses(java.util.Collection<android.net.LinkAddress>);
+    method public int getPrefixLength();
+    method public byte[] getRawAddress();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public static class LinkProperties.CompareResult {
-    ctor public LinkProperties.CompareResult();
-    field public java.util.Collection added;
-    field public java.util.Collection removed;
+  public class LinkAddress implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.net.InetAddress getAddress();
+    method public int getFlags();
+    method public int getPrefixLength();
+    method public int getScope();
+    method public void writeToParcel(android.os.Parcel, int);
+  }
+
+  public final class LinkProperties implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.util.List<java.net.InetAddress> getDnsServers();
+    method public java.lang.String getDomains();
+    method public android.net.ProxyInfo getHttpProxy();
+    method public java.lang.String getInterfaceName();
+    method public java.util.List<android.net.LinkAddress> getLinkAddresses();
+    method public java.util.List<android.net.RouteInfo> getRoutes();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
   }
 
   public class LocalServerSocket {
@@ -16135,21 +16127,12 @@
   }
 
   public final class NetworkCapabilities implements android.os.Parcelable {
-    ctor public NetworkCapabilities();
     ctor public NetworkCapabilities(android.net.NetworkCapabilities);
-    method public void addNetworkCapability(int);
-    method public void addTransportType(int);
     method public int describeContents();
     method public int getLinkDownstreamBandwidthKbps();
     method public int getLinkUpstreamBandwidthKbps();
-    method public java.util.Collection<java.lang.Integer> getNetworkCapabilities();
-    method public java.util.Collection<java.lang.Integer> getTransportTypes();
     method public boolean hasCapability(int);
     method public boolean hasTransport(int);
-    method public void removeNetworkCapability(int);
-    method public void removeTransportType(int);
-    method public void setLinkDownstreamBandwidthKbps(int);
-    method public void setLinkUpstreamBandwidthKbps(int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int NET_CAPABILITY_CBS = 5; // 0x5
@@ -16223,7 +16206,15 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
-    field public final android.net.NetworkCapabilities networkCapabilities;
+  }
+
+  public static class NetworkRequest.Builder {
+    ctor public NetworkRequest.Builder();
+    method public android.net.NetworkRequest.Builder addCapability(int);
+    method public android.net.NetworkRequest.Builder addTransportType(int);
+    method public android.net.NetworkRequest build();
+    method public android.net.NetworkRequest.Builder removeCapability(int);
+    method public android.net.NetworkRequest.Builder removeTransportType(int);
   }
 
   public class ParseException extends java.lang.RuntimeException {
@@ -16252,18 +16243,15 @@
     method public void writeToParcel(android.os.Parcel, int);
   }
 
-  public class RouteInfo implements android.os.Parcelable {
-    ctor public RouteInfo(android.net.LinkAddress, java.net.InetAddress, java.lang.String);
-    ctor public RouteInfo(android.net.LinkAddress, java.net.InetAddress);
-    ctor public RouteInfo(java.net.InetAddress);
-    ctor public RouteInfo(android.net.LinkAddress);
+  public final class RouteInfo implements android.os.Parcelable {
     method public int describeContents();
-    method public android.net.LinkAddress getDestination();
+    method public android.net.IpPrefix getDestination();
     method public java.net.InetAddress getGateway();
     method public java.lang.String getInterface();
     method public boolean isDefaultRoute();
     method public boolean matches(java.net.InetAddress);
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
   }
 
   public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
@@ -25827,21 +25815,28 @@
     method public final void cancelNotification(java.lang.String);
     method public final void cancelNotifications(java.lang.String[]);
     method public android.service.notification.StatusBarNotification[] getActiveNotifications();
-    method public android.service.notification.NotificationListenerService.Ranking getCurrentRanking();
+    method public android.service.notification.NotificationListenerService.RankingMap getCurrentRanking();
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onListenerConnected();
-    method public abstract void onNotificationPosted(android.service.notification.StatusBarNotification);
-    method public void onNotificationRankingUpdate();
-    method public abstract void onNotificationRemoved(android.service.notification.StatusBarNotification);
+    method public void onNotificationPosted(android.service.notification.StatusBarNotification);
+    method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
+    method public void onNotificationRankingUpdate(android.service.notification.NotificationListenerService.RankingMap);
+    method public void onNotificationRemoved(android.service.notification.StatusBarNotification);
+    method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
   }
 
-  public static class NotificationListenerService.Ranking implements android.os.Parcelable {
+  public static class NotificationListenerService.Ranking {
+    method public java.lang.String getKey();
+    method public int getRank();
+    method public boolean isAmbient();
+    method public boolean isInterceptedByDoNotDisturb();
+  }
+
+  public static class NotificationListenerService.RankingMap implements android.os.Parcelable {
     method public int describeContents();
     method public java.lang.String[] getOrderedKeys();
-    method public int getRank(java.lang.String);
-    method public boolean isAmbient(java.lang.String);
-    method public boolean isInterceptedByDoNotDisturb(java.lang.String);
+    method public android.service.notification.NotificationListenerService.Ranking getRanking(java.lang.String);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
@@ -33903,15 +33898,15 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public static final class CursorAnchorInfo.CursorAnchorInfoBuilder {
-    ctor public CursorAnchorInfo.CursorAnchorInfoBuilder();
-    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder addCharacterRect(int, float, float, float, float);
+  public static final class CursorAnchorInfo.Builder {
+    ctor public CursorAnchorInfo.Builder();
+    method public android.view.inputmethod.CursorAnchorInfo.Builder addCharacterRect(int, float, float, float, float);
     method public android.view.inputmethod.CursorAnchorInfo build();
     method public void reset();
-    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setComposingText(int, java.lang.CharSequence);
-    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setInsertionMarkerLocation(float, float, float, float);
-    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setMatrix(android.graphics.Matrix);
-    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setSelectionRange(int, int);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setComposingText(int, java.lang.CharSequence);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setMatrix(android.graphics.Matrix);
+    method public android.view.inputmethod.CursorAnchorInfo.Builder setSelectionRange(int, int);
   }
 
   public class EditorInfo implements android.text.InputType android.os.Parcelable {
diff --git a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
index dce0a75..e6847a9 100644
--- a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
+++ b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
@@ -20,6 +20,7 @@
 import android.app.IActivityManager;
 import android.app.IActivityManager.ContentProviderHolder;
 import android.content.IContentProvider;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -33,7 +34,8 @@
     enum CommandVerb {
         UNSPECIFIED,
         GET,
-        PUT
+        PUT,
+        DELETE
     }
 
     static String[] mArgs;
@@ -74,6 +76,8 @@
                         mVerb = CommandVerb.GET;
                     } else if ("put".equalsIgnoreCase(arg)) {
                         mVerb = CommandVerb.PUT;
+                    } else if ("delete".equalsIgnoreCase(arg)) {
+                        mVerb = CommandVerb.DELETE;
                     } else {
                         // invalid
                         System.err.println("Invalid command: " + arg);
@@ -87,7 +91,7 @@
                         break;  // invalid
                     }
                     mTable = arg.toLowerCase();
-                } else if (mVerb == CommandVerb.GET) {
+                } else if (mVerb == CommandVerb.GET || mVerb == CommandVerb.DELETE) {
                     mKey = arg;
                     if (mNextArg >= mArgs.length) {
                         valid = true;
@@ -136,6 +140,10 @@
                         case PUT:
                             putForUser(provider, mUser, mTable, mKey, mValue);
                             break;
+                        case DELETE:
+                            System.out.println("Deleted "
+                                    + deleteForUser(provider, mUser, mTable, mKey) + " rows");
+                            break;
                         default:
                             System.err.println("Unspecified command");
                             break;
@@ -211,9 +219,31 @@
         }
     }
 
+    int deleteForUser(IContentProvider provider, int userHandle,
+            final String table, final String key) {
+        Uri targetUri;
+        if ("system".equals(table)) targetUri = Settings.System.getUriFor(key);
+        else if ("secure".equals(table)) targetUri = Settings.Secure.getUriFor(key);
+        else if ("global".equals(table)) targetUri = Settings.Global.getUriFor(key);
+        else {
+            System.err.println("Invalid table; no delete performed");
+            throw new IllegalArgumentException("Invalid table " + table);
+        }
+
+        int num = 0;
+        try {
+            num = provider.delete(null, targetUri, null, null);
+        } catch (RemoteException e) {
+            System.err.println("Can't clear key " + key + " in " + table + " for user "
+                    + userHandle);
+        }
+        return num;
+    }
+
     private static void printUsage() {
         System.err.println("usage:  settings [--user NUM] get namespace key");
         System.err.println("        settings [--user NUM] put namespace key value");
+        System.err.println("        settings [--user NUM] delete namespace key");
         System.err.println("\n'namespace' is one of {system, secure, global}, case-insensitive");
         System.err.println("If '--user NUM' is not given, the operations are performed on the owner user.");
     }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 946555f..f6883e2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5616,6 +5616,34 @@
         mExitTransitionListener = listener;
     }
 
+    /**
+     * Postpone the entering activity transition when Activity was started with
+     * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
+     * android.util.Pair[])}.
+     * <p>This method gives the Activity the ability to delay starting the entering and
+     * shared element transitions until all data is loaded. Until then, the Activity won't
+     * draw into its window, leaving the window transparent. This may also cause the
+     * returning animation to be delayed until data is ready. This method should be
+     * called in {@link #onCreate(android.os.Bundle)} or in
+     * {@link #onActivityReenter(int, android.content.Intent)}.
+     * {@link #startPostponedEnterTransition()} must be called to allow the Activity to
+     * start the transitions. If the Activity did not use
+     * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
+     * android.util.Pair[])}, then this method does nothing.</p>
+     */
+    public void postponeEnterTransition() {
+        mActivityTransitionState.postponeEnterTransition();
+    }
+
+    /**
+     * Begin postponed transitions after {@link #postponeEnterTransition()} was called.
+     * If postponeEnterTransition() was called, you must call startPostponedEnterTransition()
+     * to have your Activity start drawing.
+     */
+    public void startPostponedEnterTransition() {
+        mActivityTransitionState.startPostponedEnterTransition();
+    }
+
     // ------------------ Internal API ------------------
     
     final void setParent(Activity parent) {
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index b658597..703df51 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -214,11 +214,21 @@
             ArrayList<String> allSharedElementNames,
             ArrayList<String> accepted, ArrayList<String> localNames,
             SharedElementListener listener, boolean isReturning) {
+        this(window, allSharedElementNames, listener, isReturning);
+        viewsReady(accepted, localNames);
+    }
+
+    public ActivityTransitionCoordinator(Window window,
+            ArrayList<String> allSharedElementNames,
+            SharedElementListener listener, boolean isReturning) {
         super(new Handler());
         mWindow = window;
         mListener = listener;
         mAllSharedElementNames = allSharedElementNames;
         mIsReturning = isReturning;
+    }
+
+    protected void viewsReady(ArrayList<String> accepted, ArrayList<String> localNames) {
         setSharedElements(accepted, localNames);
         if (getViewsTransition() != null) {
             getDecor().captureTransitioningViews(mTransitioningViews);
@@ -274,6 +284,8 @@
         return names;
     }
 
+    public ArrayList<String> getAllSharedElementNames() { return mAllSharedElementNames; }
+
     public static void setViewVisibility(Collection<View> views, int visibility) {
         if (views != null) {
             for (View view : views) {
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index b32e9ad..d94dadda 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -87,6 +87,11 @@
      */
     private boolean mHasExited;
 
+    /**
+     * Postpone painting and starting the enter transition until this is false.
+     */
+    private boolean mIsEnterPostponed;
+
     public ActivityTransitionState() {
     }
 
@@ -140,15 +145,38 @@
         if (mEnterActivityOptions.isReturning()) {
             restoreExitedViews();
             activity.getWindow().getDecorView().setVisibility(View.VISIBLE);
-            mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
-                    resultReceiver, sharedElementNames, mExitingFrom, mExitingTo);
+        }
+        mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
+                resultReceiver, sharedElementNames, mEnterActivityOptions.isReturning());
+
+        if (!mIsEnterPostponed) {
+            startEnter();
+        }
+    }
+
+    public void postponeEnterTransition() {
+        mIsEnterPostponed = true;
+    }
+
+    public void startPostponedEnterTransition() {
+        if (mIsEnterPostponed) {
+            mIsEnterPostponed = false;
+            if (mEnterTransitionCoordinator != null) {
+                startEnter();
+            }
+        }
+    }
+
+    private void startEnter() {
+        if (mEnterActivityOptions.isReturning()) {
+            mEnterTransitionCoordinator.viewsReady(mExitingFrom, mExitingTo);
         } else {
-            mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
-                    resultReceiver, sharedElementNames, null, null);
-            mEnteringNames = sharedElementNames;
+            mEnterTransitionCoordinator.viewsReady(null, null);
+            mEnteringNames = mEnterTransitionCoordinator.getAllSharedElementNames();
             mEnteringFrom = mEnterTransitionCoordinator.getAcceptedNames();
             mEnteringTo = mEnterTransitionCoordinator.getMappedNames();
         }
+
         mExitingFrom = null;
         mExitingTo = null;
         mEnterActivityOptions = null;
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 4b052e7..779e3de 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -53,18 +53,37 @@
     private boolean mIsCanceled;
     private ObjectAnimator mBackgroundAnimator;
     private boolean mIsExitTransitionComplete;
+    private boolean mIsReadyForTransition;
+    private Bundle mSharedElementsBundle;
 
     public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
-            ArrayList<String> sharedElementNames,
-            ArrayList<String> acceptedNames, ArrayList<String> mappedNames) {
-        super(activity.getWindow(), sharedElementNames, acceptedNames, mappedNames,
-                getListener(activity, acceptedNames), acceptedNames != null);
+            ArrayList<String> sharedElementNames, boolean isReturning) {
+        super(activity.getWindow(), sharedElementNames,
+                getListener(activity, isReturning), isReturning);
         mActivity = activity;
         setResultReceiver(resultReceiver);
         prepareEnter();
         Bundle resultReceiverBundle = new Bundle();
         resultReceiverBundle.putParcelable(KEY_REMOTE_RECEIVER, this);
         mResultReceiver.send(MSG_SET_REMOTE_RECEIVER, resultReceiverBundle);
+        getDecor().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+            @Override
+            public boolean onPreDraw() {
+                if (mIsReadyForTransition) {
+                    getDecor().getViewTreeObserver().removeOnPreDrawListener(this);
+                }
+                return mIsReadyForTransition;
+            }
+        });
+    }
+
+    public void viewsReady(ArrayList<String> accepted, ArrayList<String> localNames) {
+        if (mIsReadyForTransition) {
+            return;
+        }
+        super.viewsReady(accepted, localNames);
+
+        mIsReadyForTransition = true;
         if (mIsReturning) {
             mHandler = new Handler() {
                 @Override
@@ -75,6 +94,13 @@
             mHandler.sendEmptyMessageDelayed(MSG_CANCEL, MAX_WAIT_MS);
             send(MSG_SEND_SHARED_ELEMENT_DESTINATION, null);
         }
+        setViewVisibility(mSharedElements, View.INVISIBLE);
+        if (getViewsTransition() != null) {
+            setViewVisibility(mTransitioningViews, View.INVISIBLE);
+        }
+        if (mSharedElementsBundle != null) {
+            onTakeSharedElements();
+        }
     }
 
     private void sendSharedElementDestination() {
@@ -94,9 +120,7 @@
         }
     }
 
-    private static SharedElementListener getListener(Activity activity,
-            ArrayList<String> acceptedNames) {
-        boolean isReturning = acceptedNames != null;
+    private static SharedElementListener getListener(Activity activity, boolean isReturning) {
         return isReturning ? activity.mExitTransitionListener : activity.mEnterTransitionListener;
     }
 
@@ -108,7 +132,8 @@
                     if (mHandler != null) {
                         mHandler.removeMessages(MSG_CANCEL);
                     }
-                    onTakeSharedElements(resultData);
+                    mSharedElementsBundle = resultData;
+                    onTakeSharedElements();
                 }
                 break;
             case MSG_EXIT_TRANSITION_COMPLETE:
@@ -139,7 +164,7 @@
             mSharedElementNames.clear();
             mSharedElements.clear();
             mAllSharedElementNames.clear();
-            onTakeSharedElements(null);
+            startSharedElementTransition(null);
             onRemoteExitTransitionComplete();
         }
     }
@@ -149,10 +174,6 @@
     }
 
     protected void prepareEnter() {
-        setViewVisibility(mSharedElements, View.INVISIBLE);
-        if (getViewsTransition() != null) {
-            setViewVisibility(mTransitioningViews, View.INVISIBLE);
-        }
         mActivity.overridePendingTransition(0, 0);
         if (!mIsReturning) {
             mActivity.convertToTranslucent(null, null);
@@ -185,7 +206,25 @@
         }
     }
 
-    protected void onTakeSharedElements(Bundle sharedElementState) {
+    protected void onTakeSharedElements() {
+        if (!mIsReadyForTransition || mSharedElementsBundle == null) {
+            return;
+        }
+        final Bundle sharedElementState = mSharedElementsBundle;
+        mSharedElementsBundle = null;
+        getDecor().getViewTreeObserver()
+                .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+                    @Override
+                    public boolean onPreDraw() {
+                        getDecor().getViewTreeObserver().removeOnPreDrawListener(this);
+                        startSharedElementTransition(sharedElementState);
+                        return false;
+                    }
+                });
+        getDecor().invalidate();
+    }
+
+    private void startSharedElementTransition(Bundle sharedElementState) {
         setEpicenter();
         // Remove rejected shared elements
         ArrayList<String> rejectedNames = new ArrayList<String>(mAllSharedElementNames);
@@ -299,8 +338,8 @@
     }
 
     public void stop() {
+        makeOpaque();
         mHasStopped = true;
-        mActivity = null;
         mIsCanceled = true;
         mResultReceiver = null;
         if (mBackgroundAnimator != null) {
@@ -310,7 +349,7 @@
     }
 
     private void makeOpaque() {
-        if (!mHasStopped) {
+        if (!mHasStopped && mActivity != null) {
             mActivity.convertFromTranslucent();
             mActivity = null;
         }
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
index 85e970c..0d947217 100644
--- a/core/java/android/app/VoiceInteractor.java
+++ b/core/java/android/app/VoiceInteractor.java
@@ -293,7 +293,7 @@
 
         IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName,
                 IVoiceInteractorCallback callback) throws RemoteException {
-            return interactor.startConfirmation(packageName, callback, mCommand, mArgs);
+            return interactor.startCommand(packageName, callback, mCommand, mArgs);
         }
    }
 
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index ff56720..9eea545 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -30,7 +30,7 @@
  *
  * <p>These properties are fixed for a given CameraDevice, and can be queried
  * through the {@link CameraManager CameraManager}
- * interface in addition to through the CameraDevice interface.</p>
+ * interface with {@link CameraManager#getCameraCharacteristics}.</p>
  *
  * <p>{@link CameraCharacteristics} objects are immutable.</p>
  *
@@ -555,7 +555,7 @@
      * <p>List containing a subset of the optical image
      * stabilization (OIS) modes specified in
      * {@link CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE android.lens.opticalStabilizationMode}.</p>
-     * <p>If OIS is not implemented for a given camera device, this should
+     * <p>If OIS is not implemented for a given camera device, this will
      * contain only OFF.</p>
      *
      * @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
@@ -612,7 +612,7 @@
 
     /**
      * <p>Direction the camera faces relative to
-     * device screen</p>
+     * device screen.</p>
      * @see #LENS_FACING_FRONT
      * @see #LENS_FACING_BACK
      */
@@ -622,7 +622,7 @@
     /**
      * <p>The set of noise reduction modes supported by this camera device.</p>
      * <p>This tag lists the valid modes for {@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode}.</p>
-     * <p>Full-capability camera devices must laways support OFF and FAST.</p>
+     * <p>Full-capability camera devices must always support OFF and FAST.</p>
      *
      * @see CaptureRequest#NOISE_REDUCTION_MODE
      */
@@ -778,18 +778,20 @@
             new Key<Byte>("android.request.pipelineMaxDepth", byte.class);
 
     /**
-     * <p>Optional. Defaults to 1. Defines how many sub-components
+     * <p>Defines how many sub-components
      * a result will be composed of.</p>
      * <p>In order to combat the pipeline latency, partial results
      * may be delivered to the application layer from the camera device as
      * soon as they are available.</p>
-     * <p>A value of 1 means that partial results are not supported.</p>
+     * <p>Optional; defaults to 1. A value of 1 means that partial
+     * results are not supported, and only the final TotalCaptureResult will
+     * be produced by the camera device.</p>
      * <p>A typical use case for this might be: after requesting an
      * auto-focus (AF) lock the new AF state might be available 50%
      * of the way through the pipeline.  The camera device could
      * then immediately dispatch this state via a partial result to
-     * the framework/application layer, and the rest of the
-     * metadata via later partial results.</p>
+     * the application, and the rest of the metadata via later
+     * partial results.</p>
      */
     public static final Key<Integer> REQUEST_PARTIAL_RESULT_COUNT =
             new Key<Integer>("android.request.partialResultCount", int.class);
@@ -806,8 +808,6 @@
      * to do this query each of android.request.availableRequestKeys,
      * android.request.availableResultKeys,
      * android.request.availableCharacteristicsKeys.</p>
-     * <p>XX: Maybe these should go into {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel}
-     * as a table instead?</p>
      * <p>The following capabilities are guaranteed to be available on
      * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} <code>==</code> FULL devices:</p>
      * <ul>
@@ -815,14 +815,11 @@
      * <li>MANUAL_POST_PROCESSING</li>
      * </ul>
      * <p>Other capabilities may be available on either FULL or LIMITED
-     * devices, but the app. should query this field to be sure.</p>
+     * devices, but the application should query this field to be sure.</p>
      *
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
-     * @see #REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
-     * @see #REQUEST_AVAILABLE_CAPABILITIES_OPTIONAL
      * @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR
      * @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING
-     * @see #REQUEST_AVAILABLE_CAPABILITIES_ZSL
      * @see #REQUEST_AVAILABLE_CAPABILITIES_DNG
      */
     public static final Key<int[]> REQUEST_AVAILABLE_CAPABILITIES =
@@ -838,7 +835,6 @@
      * at a more granular level than capabilities. This is especially
      * important for optional keys that are not listed under any capability
      * in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}.</p>
-     * <p>TODO: This should be used by #getAvailableCaptureRequestKeys.</p>
      *
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
      * @hide
@@ -863,7 +859,6 @@
      * at a more granular level than capabilities. This is especially
      * important for optional keys that are not listed under any capability
      * in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}.</p>
-     * <p>TODO: This should be used by #getAvailableCaptureResultKeys.</p>
      *
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
      * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
@@ -879,7 +874,6 @@
      * android.request.availableResultKeys (except that it applies for
      * CameraCharacteristics instead of CaptureResult). See above for more
      * details.</p>
-     * <p>TODO: This should be used by CameraCharacteristics#getKeys.</p>
      * @hide
      */
     public static final Key<int[]> REQUEST_AVAILABLE_CHARACTERISTICS_KEYS =
@@ -927,10 +921,15 @@
             new Key<android.util.Size[]>("android.scaler.availableJpegSizes", android.util.Size[].class);
 
     /**
-     * <p>The maximum ratio between active area width
-     * and crop region width, or between active area height and
-     * crop region height, if the crop region height is larger
-     * than width</p>
+     * <p>The maximum ratio between both active area width
+     * and crop region width, and active area height and
+     * crop region height.</p>
+     * <p>This represents the maximum amount of zooming possible by
+     * the camera device, or equivalently, the minimum cropping
+     * window size.</p>
+     * <p>Crop regions that have a width or height that is smaller
+     * than this ratio allows will be rounded up to the minimum
+     * allowed size by the camera device.</p>
      */
     public static final Key<Float> SCALER_AVAILABLE_MAX_DIGITAL_ZOOM =
             new Key<Float>("android.scaler.availableMaxDigitalZoom", float.class);
@@ -1339,9 +1338,9 @@
             new Key<android.util.Range<Integer>>("android.sensor.info.sensitivityRange", new TypeReference<android.util.Range<Integer>>() {{ }});
 
     /**
-     * <p>Arrangement of color filters on sensor;
+     * <p>The arrangement of color filters on sensor;
      * represents the colors in the top-left 2x2 section of
-     * the sensor, in reading order</p>
+     * the sensor, in reading order.</p>
      * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB
      * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG
      * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG
@@ -1666,10 +1665,9 @@
             new Key<int[]>("android.sensor.availableTestPatternModes", int[].class);
 
     /**
-     * <p>Which face detection modes are available,
-     * if any.</p>
-     * <p>OFF means face detection is disabled, it must
-     * be included in the list.</p>
+     * <p>The face detection modes that are available
+     * for this camera device.</p>
+     * <p>OFF is always supported.</p>
      * <p>SIMPLE means the device supports the
      * android.statistics.faceRectangles and
      * android.statistics.faceScores outputs.</p>
@@ -1681,8 +1679,8 @@
             new Key<int[]>("android.statistics.info.availableFaceDetectModes", int[].class);
 
     /**
-     * <p>Maximum number of simultaneously detectable
-     * faces</p>
+     * <p>The maximum number of simultaneously detectable
+     * faces.</p>
      */
     public static final Key<Integer> STATISTICS_INFO_MAX_FACE_COUNT =
             new Key<Integer>("android.statistics.info.maxFaceCount", int.class);
@@ -1691,7 +1689,7 @@
      * <p>The set of hot pixel map output modes supported by this camera device.</p>
      * <p>This tag lists valid output modes for {@link CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE android.statistics.hotPixelMapMode}.</p>
      * <p>If no hotpixel map is available for this camera device, this will contain
-     * only OFF.  If the hotpixel map is available, this should include both
+     * only OFF.  If the hotpixel map is available, this will include both
      * the ON and OFF options.</p>
      *
      * @see CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 90e5e4e..33e1915 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -157,8 +157,8 @@
 
     /**
      * <p>The lens focus distance is not accurate, and the units used for
-     * {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} do not correspond to any physical units.
-     * Setting the lens to the same focus distance on separate occasions may
+     * {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} do not correspond to any physical units.</p>
+     * <p>Setting the lens to the same focus distance on separate occasions may
      * result in a different real focus distance, depending on factors such
      * as the orientation of the device, the age of the focusing mechanism,
      * and the device temperature. The focus distance value will still be
@@ -172,20 +172,24 @@
     public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED = 0;
 
     /**
-     * <p>The lens focus distance is measured in diopters. However, setting the lens
-     * to the same focus distance on separate occasions may result in a
-     * different real focus distance, depending on factors such as the
-     * orientation of the device, the age of the focusing mechanism, and
-     * the device temperature.</p>
+     * <p>The lens focus distance is measured in diopters.</p>
+     * <p>However, setting the lens to the same focus distance
+     * on separate occasions may result in a different real
+     * focus distance, depending on factors such as the
+     * orientation of the device, the age of the focusing
+     * mechanism, and the device temperature.</p>
      * @see CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
      */
     public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE = 1;
 
     /**
-     * <p>The lens focus distance is measured in diopters. The lens mechanism is
-     * calibrated so that setting the same focus distance is repeatable on
-     * multiple occasions with good accuracy, and the focus distance corresponds
-     * to the real physical distance to the plane of best focus.</p>
+     * <p>The lens focus distance is measured in diopters, and
+     * is calibrated.</p>
+     * <p>The lens mechanism is calibrated so that setting the
+     * same focus distance is repeatable on multiple
+     * occasions with good accuracy, and the focus distance
+     * corresponds to the real physical distance to the plane
+     * of best focus.</p>
      * @see CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
      */
     public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED = 2;
@@ -195,11 +199,13 @@
     //
 
     /**
+     * <p>The camera device faces the same direction as the device's screen.</p>
      * @see CameraCharacteristics#LENS_FACING
      */
     public static final int LENS_FACING_FRONT = 0;
 
     /**
+     * <p>The camera device faces the opposite direction as the device's screen.</p>
      * @see CameraCharacteristics#LENS_FACING
      */
     public static final int LENS_FACING_BACK = 1;
@@ -215,11 +221,10 @@
      * <p>The full set of features supported by this capability makes
      * the camera2 api backwards compatible with the camera1
      * (android.hardware.Camera) API.</p>
-     * <p>TODO: @hide this. Doesn't really mean anything except
-     * act as a catch-all for all the 'base' functionality.</p>
      *
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     * @hide
      */
     public static final int REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0;
 
@@ -228,15 +233,14 @@
      * tags or functionality not encapsulated by one of the other
      * capabilities.</p>
      * <p>A typical example is all tags marked 'optional'.</p>
-     * <p>TODO: @hide. We may not need this if we @hide all the optional
-     * tags not belonging to a capability.</p>
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     * @hide
      */
     public static final int REQUEST_AVAILABLE_CAPABILITIES_OPTIONAL = 1;
 
     /**
      * <p>The camera device can be manually controlled (3A algorithms such
-     * as auto exposure, and auto focus can be bypassed).
+     * as auto-exposure, and auto-focus can be bypassed).
      * The camera device supports basic manual control of the sensor image
      * acquisition related stages. This means the following controls are
      * guaranteed to be supported:</p>
@@ -257,11 +261,11 @@
      * <li>{@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange}</li>
      * </ul>
      * </li>
-     * <li>Manual lens control<ul>
+     * <li>Manual lens control (if the lens is adjustable)<ul>
      * <li>android.lens.*</li>
      * </ul>
      * </li>
-     * <li>Manual flash control<ul>
+     * <li>Manual flash control (if a flash unit is present)<ul>
      * <li>android.flash.*</li>
      * </ul>
      * </li>
@@ -312,8 +316,6 @@
      * </ul>
      * <p>If auto white balance is enabled, then the camera device
      * will accurately report the values applied by AWB in the result.</p>
-     * <p>The camera device will also support everything in MANUAL_SENSOR
-     * except manual lens control and manual flash control.</p>
      * <p>A given camera device may also support additional post-processing
      * controls, but this capability only covers the above list of controls.</p>
      *
@@ -340,8 +342,8 @@
      * (both input/output) will match the maximum available
      * resolution of JPEG streams.</li>
      * </ul>
-     * <p>@hide this, TODO: remove it when input related APIs are ready.</p>
      * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     * @hide
      */
     public static final int REQUEST_AVAILABLE_CAPABILITIES_ZSL = 4;
 
@@ -355,7 +357,7 @@
      * <li>RAW16 is reprocessable into both YUV_420_888 and JPEG
      * formats.</li>
      * <li>The maximum available resolution for RAW16 streams (both
-     * input/output) will match the either value in
+     * input/output) will match either the value in
      * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize} or
      * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</li>
      * <li>All DNG-related optional metadata entries are provided
@@ -373,13 +375,13 @@
     //
 
     /**
-     * <p>The camera device will only support centered crop regions.</p>
+     * <p>The camera device only supports centered crop regions.</p>
      * @see CameraCharacteristics#SCALER_CROPPING_TYPE
      */
     public static final int SCALER_CROPPING_TYPE_CENTER_ONLY = 0;
 
     /**
-     * <p>The camera device will support arbitrarily chosen crop regions.</p>
+     * <p>The camera device supports arbitrarily chosen crop regions.</p>
      * @see CameraCharacteristics#SCALER_CROPPING_TYPE
      */
     public static final int SCALER_CROPPING_TYPE_FREEFORM = 1;
@@ -525,7 +527,7 @@
     //
 
     /**
-     * <p>android.led.transmit control is used</p>
+     * <p>android.led.transmit control is used.</p>
      * @see CameraCharacteristics#LED_AVAILABLE_LEDS
      * @hide
      */
@@ -536,11 +538,14 @@
     //
 
     /**
+     * <p>This camera device has only limited capabilities.</p>
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      */
     public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0;
 
     /**
+     * <p>This camera device is capable of supporting advanced imaging
+     * applications.</p>
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      */
     public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1;
@@ -550,9 +555,9 @@
     //
 
     /**
-     * <p>Every frame has the requests immediately applied.
-     * (and furthermore for all results,
-     * <code>android.sync.frameNumber == android.request.frameCount</code>)</p>
+     * <p>Every frame has the requests immediately applied.</p>
+     * <p>Furthermore for all results,
+     * <code>android.sync.frameNumber == android.request.frameCount</code></p>
      * <p>Changing controls over multiple requests one after another will
      * produce results that have those controls applied atomically
      * each frame.</p>
@@ -592,8 +597,8 @@
     public static final int COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0;
 
     /**
-     * <p>Must not slow down capture rate relative to sensor raw
-     * output.</p>
+     * <p>Color correction processing must not slow down
+     * capture rate relative to sensor raw output.</p>
      * <p>Advanced white balance adjustments above and beyond
      * the specified white balance pipeline may be applied.</p>
      * <p>If AWB is enabled with <code>{@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} != OFF</code>, then
@@ -606,8 +611,9 @@
     public static final int COLOR_CORRECTION_MODE_FAST = 1;
 
     /**
-     * <p>Capture rate (relative to sensor raw output)
-     * may be reduced by high quality.</p>
+     * <p>Color correction processing operates at improved
+     * quality but reduced capture rate (relative to sensor raw
+     * output).</p>
      * <p>Advanced white balance adjustments above and beyond
      * the specified white balance pipeline may be applied.</p>
      * <p>If AWB is enabled with <code>{@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} != OFF</code>, then
@@ -658,8 +664,8 @@
     //
 
     /**
-     * <p>The camera device's autoexposure routine is disabled;
-     * the application-selected {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
+     * <p>The camera device's autoexposure routine is disabled.</p>
+     * <p>The application-selected {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
      * {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} and
      * {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} are used by the camera
      * device, along with android.flash.* fields, if there's
@@ -674,7 +680,8 @@
 
     /**
      * <p>The camera device's autoexposure routine is active,
-     * with no flash control. The application's values for
+     * with no flash control.</p>
+     * <p>The application's values for
      * {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
      * {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, and
      * {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} are ignored. The
@@ -691,10 +698,10 @@
     /**
      * <p>Like ON, except that the camera device also controls
      * the camera's flash unit, firing it in low-light
-     * conditions. The flash may be fired during a
-     * precapture sequence (triggered by
-     * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}) and may be fired
-     * for captures for which the
+     * conditions.</p>
+     * <p>The flash may be fired during a precapture sequence
+     * (triggered by {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}) and
+     * may be fired for captures for which the
      * {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} field is set to
      * STILL_CAPTURE</p>
      *
@@ -707,10 +714,10 @@
     /**
      * <p>Like ON, except that the camera device also controls
      * the camera's flash unit, always firing it for still
-     * captures. The flash may be fired during a precapture
-     * sequence (triggered by
-     * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}) and will always
-     * be fired for captures for which the
+     * captures.</p>
+     * <p>The flash may be fired during a precapture sequence
+     * (triggered by {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}) and
+     * will always be fired for captures for which the
      * {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} field is set to
      * STILL_CAPTURE</p>
      *
@@ -722,9 +729,10 @@
 
     /**
      * <p>Like ON_AUTO_FLASH, but with automatic red eye
-     * reduction. If deemed necessary by the camera device,
-     * a red eye reduction flash will fire during the
-     * precapture sequence.</p>
+     * reduction.</p>
+     * <p>If deemed necessary by the camera device, a red eye
+     * reduction flash will fire during the precapture
+     * sequence.</p>
      * @see CaptureRequest#CONTROL_AE_MODE
      */
     public static final int CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4;
@@ -741,8 +749,9 @@
 
     /**
      * <p>The precapture metering sequence will be started
-     * by the camera device. The exact effect of the precapture
-     * trigger depends on the current AE mode and state.</p>
+     * by the camera device.</p>
+     * <p>The exact effect of the precapture trigger depends on
+     * the current AE mode and state.</p>
      * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
      */
     public static final int CONTROL_AE_PRECAPTURE_TRIGGER_START = 1;
@@ -754,7 +763,7 @@
     /**
      * <p>The auto-focus routine does not control the lens;
      * {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} is controlled by the
-     * application</p>
+     * application.</p>
      *
      * @see CaptureRequest#LENS_FOCUS_DISTANCE
      * @see CaptureRequest#CONTROL_AF_MODE
@@ -839,8 +848,11 @@
     public static final int CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4;
 
     /**
-     * <p>Extended depth of field (digital focus). AF
-     * trigger is ignored, AF state should always be
+     * <p>Extended depth of field (digital focus) mode.</p>
+     * <p>The camera device will produce images with an extended
+     * depth of field automatically; no special focusing
+     * operations need to be done before taking a picture.</p>
+     * <p>AF triggers are ignored, and the AF state will always be
      * INACTIVE.</p>
      * @see CaptureRequest#CONTROL_AF_MODE
      */
@@ -874,8 +886,8 @@
     //
 
     /**
-     * <p>The camera device's auto white balance routine is disabled;
-     * the application-selected color transform matrix
+     * <p>The camera device's auto-white balance routine is disabled.</p>
+     * <p>The application-selected color transform matrix
      * ({@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}) and gains
      * ({@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}) are used by the camera
      * device for manual white balance control.</p>
@@ -887,9 +899,12 @@
     public static final int CONTROL_AWB_MODE_OFF = 0;
 
     /**
-     * <p>The camera device's auto white balance routine is active;
-     * the application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
-     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.</p>
+     * <p>The camera device's auto-white balance routine is active.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
      *
      * @see CaptureRequest#COLOR_CORRECTION_GAINS
      * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
@@ -898,65 +913,125 @@
     public static final int CONTROL_AWB_MODE_AUTO = 1;
 
     /**
-     * <p>The camera device's auto white balance routine is disabled;
+     * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses incandescent light as the assumed scene
-     * illumination for white balance. While the exact white balance
-     * transforms are up to the camera device, they will approximately
-     * match the CIE standard illuminant A.</p>
+     * illumination for white balance.</p>
+     * <p>While the exact white balance transforms are up to the
+     * camera device, they will approximately match the CIE
+     * standard illuminant A.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_INCANDESCENT = 2;
 
     /**
-     * <p>The camera device's auto white balance routine is disabled;
+     * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses fluorescent light as the assumed scene
-     * illumination for white balance. While the exact white balance
-     * transforms are up to the camera device, they will approximately
-     * match the CIE standard illuminant F2.</p>
+     * illumination for white balance.</p>
+     * <p>While the exact white balance transforms are up to the
+     * camera device, they will approximately match the CIE
+     * standard illuminant F2.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_FLUORESCENT = 3;
 
     /**
-     * <p>The camera device's auto white balance routine is disabled;
+     * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses warm fluorescent light as the assumed scene
-     * illumination for white balance. While the exact white balance
-     * transforms are up to the camera device, they will approximately
-     * match the CIE standard illuminant F4.</p>
+     * illumination for white balance.</p>
+     * <p>While the exact white balance transforms are up to the
+     * camera device, they will approximately match the CIE
+     * standard illuminant F4.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_WARM_FLUORESCENT = 4;
 
     /**
-     * <p>The camera device's auto white balance routine is disabled;
+     * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses daylight light as the assumed scene
-     * illumination for white balance. While the exact white balance
-     * transforms are up to the camera device, they will approximately
-     * match the CIE standard illuminant D65.</p>
+     * illumination for white balance.</p>
+     * <p>While the exact white balance transforms are up to the
+     * camera device, they will approximately match the CIE
+     * standard illuminant D65.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_DAYLIGHT = 5;
 
     /**
-     * <p>The camera device's auto white balance routine is disabled;
+     * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses cloudy daylight light as the assumed scene
      * illumination for white balance.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_CLOUDY_DAYLIGHT = 6;
 
     /**
-     * <p>The camera device's auto white balance routine is disabled;
+     * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses twilight light as the assumed scene
      * illumination for white balance.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_TWILIGHT = 7;
 
     /**
-     * <p>The camera device's auto white balance routine is disabled;
+     * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses shade light as the assumed scene
      * illumination for white balance.</p>
+     * <p>The application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.
+     * For devices that support the MANUAL_POST_PROCESSING capability, the
+     * values used by the camera device for the transform and gains
+     * will be available in the capture result for this request.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_SHADE = 8;
@@ -966,38 +1041,43 @@
     //
 
     /**
-     * <p>This request doesn't fall into the other
-     * categories. Default to preview-like
+     * <p>The goal of this request doesn't fall into the other
+     * categories. The camera device will default to preview-like
      * behavior.</p>
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      */
     public static final int CONTROL_CAPTURE_INTENT_CUSTOM = 0;
 
     /**
-     * <p>This request is for a preview-like usecase. The
-     * precapture trigger may be used to start off a metering
-     * w/flash sequence</p>
+     * <p>This request is for a preview-like use case.</p>
+     * <p>The precapture trigger may be used to start off a metering
+     * w/flash sequence.</p>
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      */
     public static final int CONTROL_CAPTURE_INTENT_PREVIEW = 1;
 
     /**
      * <p>This request is for a still capture-type
-     * usecase.</p>
+     * use case.</p>
+     * <p>If the flash unit is under automatic control, it may fire as needed.</p>
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      */
     public static final int CONTROL_CAPTURE_INTENT_STILL_CAPTURE = 2;
 
     /**
      * <p>This request is for a video recording
-     * usecase.</p>
+     * use case.</p>
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      */
     public static final int CONTROL_CAPTURE_INTENT_VIDEO_RECORD = 3;
 
     /**
      * <p>This request is for a video snapshot (still
-     * image while recording video) usecase</p>
+     * image while recording video) use case.</p>
+     * <p>The camera device should take the highest-quality image
+     * possible (given the other settings) without disrupting the
+     * frame rate of video recording.<br />
+     * </p>
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      */
     public static final int CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT = 4;
@@ -1006,15 +1086,16 @@
      * <p>This request is for a ZSL usecase; the
      * application will stream full-resolution images and
      * reprocess one or several later for a final
-     * capture</p>
+     * capture.</p>
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      */
     public static final int CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG = 5;
 
     /**
      * <p>This request is for manual capture use case where
-     * the applications want to directly control the capture parameters
-     * (e.g. {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}, {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} etc.).</p>
+     * the applications want to directly control the capture parameters.</p>
+     * <p>For example, the application may wish to manually control
+     * {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}, {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, etc.</p>
      *
      * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      * @see CaptureRequest#SENSOR_SENSITIVITY
@@ -1034,7 +1115,8 @@
 
     /**
      * <p>A "monocolor" effect where the image is mapped into
-     * a single color.  This will typically be grayscale.</p>
+     * a single color.</p>
+     * <p>This will typically be grayscale.</p>
      * @see CaptureRequest#CONTROL_EFFECT_MODE
      */
     public static final int CONTROL_EFFECT_MODE_MONO = 1;
@@ -1094,31 +1176,42 @@
     //
 
     /**
-     * <p>Full application control of pipeline. All 3A
-     * routines are disabled, no other settings in
-     * android.control.* have any effect</p>
+     * <p>Full application control of pipeline.</p>
+     * <p>All control by the device's metering and focusing (3A)
+     * routines is disabled, and no other settings in
+     * android.control.* have any effect, except that
+     * {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} may be used by the camera
+     * device to select post-processing values for processing
+     * blocks that do not allow for manual control, or are not
+     * exposed by the camera API.</p>
+     * <p>However, the camera device's 3A routines may continue to
+     * collect statistics and update their internal state so that
+     * when control is switched to AUTO mode, good control values
+     * can be immediately applied.</p>
+     *
+     * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      * @see CaptureRequest#CONTROL_MODE
      */
     public static final int CONTROL_MODE_OFF = 0;
 
     /**
-     * <p>Use settings for each individual 3A routine.
-     * Manual control of capture parameters is disabled. All
+     * <p>Use settings for each individual 3A routine.</p>
+     * <p>Manual control of capture parameters is disabled. All
      * controls in android.control.* besides sceneMode take
-     * effect</p>
+     * effect.</p>
      * @see CaptureRequest#CONTROL_MODE
      */
     public static final int CONTROL_MODE_AUTO = 1;
 
     /**
-     * <p>Use specific scene mode. Enabling this disables
-     * control.aeMode, control.awbMode and control.afMode
-     * controls; the camera device will ignore those settings while
-     * USE_SCENE_MODE is active (except for FACE_PRIORITY
-     * scene mode). Other control entries are still active.
-     * This setting can only be used if scene mode is supported
-     * (i.e. {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes} contain some modes
-     * other than DISABLED).</p>
+     * <p>Use a specific scene mode.</p>
+     * <p>Enabling this disables control.aeMode, control.awbMode and
+     * control.afMode controls; the camera device will ignore
+     * those settings while USE_SCENE_MODE is active (except for
+     * FACE_PRIORITY scene mode). Other control entries are still
+     * active.  This setting can only be used if scene mode is
+     * supported (i.e. {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}
+     * contain some modes other than DISABLED).</p>
      *
      * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
      * @see CaptureRequest#CONTROL_MODE
@@ -1128,7 +1221,12 @@
     /**
      * <p>Same as OFF mode, except that this capture will not be
      * used by camera device background auto-exposure, auto-white balance and
-     * auto-focus algorithms to update their statistics.</p>
+     * auto-focus algorithms (3A) to update their statistics.</p>
+     * <p>Specifically, the 3A routines are locked to the last
+     * values set from a request with AUTO, OFF, or
+     * USE_SCENE_MODE, and any statistics or state updates
+     * collected from manual captures with OFF_KEEP_STATE will be
+     * discarded by the camera device.</p>
      * @see CaptureRequest#CONTROL_MODE
      */
     public static final int CONTROL_MODE_OFF_KEEP_STATE = 3;
@@ -1146,8 +1244,9 @@
     /**
      * <p>If face detection support exists, use face
      * detection data for auto-focus, auto-white balance, and
-     * auto-exposure routines. If face detection statistics are
-     * disabled (i.e. {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} is set to OFF),
+     * auto-exposure routines.</p>
+     * <p>If face detection statistics are disabled
+     * (i.e. {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} is set to OFF),
      * this should still operate correctly (but will not return
      * face detection statistics to the framework).</p>
      * <p>Unlike the other scene modes, {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
@@ -1163,8 +1262,8 @@
     public static final int CONTROL_SCENE_MODE_FACE_PRIORITY = 1;
 
     /**
-     * <p>Optimized for photos of quickly moving objects.
-     * Similar to SPORTS.</p>
+     * <p>Optimized for photos of quickly moving objects.</p>
+     * <p>Similar to SPORTS.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_ACTION = 2;
@@ -1233,8 +1332,8 @@
     public static final int CONTROL_SCENE_MODE_FIREWORKS = 12;
 
     /**
-     * <p>Optimized for photos of quickly moving people.
-     * Similar to ACTION.</p>
+     * <p>Optimized for photos of quickly moving people.</p>
+     * <p>Similar to ACTION.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_SPORTS = 13;
@@ -1266,11 +1365,13 @@
     //
 
     /**
+     * <p>Video stabilization is disabled.</p>
      * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
      */
     public static final int CONTROL_VIDEO_STABILIZATION_MODE_OFF = 0;
 
     /**
+     * <p>Video stabilization is enabled.</p>
      * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
      */
     public static final int CONTROL_VIDEO_STABILIZATION_MODE_ON = 1;
@@ -1280,21 +1381,20 @@
     //
 
     /**
-     * <p>No edge enhancement is applied</p>
+     * <p>No edge enhancement is applied.</p>
      * @see CaptureRequest#EDGE_MODE
      */
     public static final int EDGE_MODE_OFF = 0;
 
     /**
-     * <p>Must not slow down frame rate relative to sensor
+     * <p>Apply edge enhancement at a quality level that does not slow down frame rate relative to sensor
      * output</p>
      * @see CaptureRequest#EDGE_MODE
      */
     public static final int EDGE_MODE_FAST = 1;
 
     /**
-     * <p>Frame rate may be reduced by high
-     * quality</p>
+     * <p>Apply high-quality edge enhancement, at a cost of reducing output frame rate.</p>
      * @see CaptureRequest#EDGE_MODE
      */
     public static final int EDGE_MODE_HIGH_QUALITY = 2;
@@ -1327,10 +1427,10 @@
     //
 
     /**
+     * <p>No hot pixel correction is applied.</p>
      * <p>The frame rate must not be reduced relative to sensor raw output
      * for this option.</p>
-     * <p>No hot pixel correction is applied.
-     * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+     * <p>The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
      *
      * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
      * @see CaptureRequest#HOT_PIXEL_MODE
@@ -1338,10 +1438,9 @@
     public static final int HOT_PIXEL_MODE_OFF = 0;
 
     /**
-     * <p>The frame rate must not be reduced relative to sensor raw output
-     * for this option.</p>
-     * <p>Hot pixel correction is applied.
-     * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+     * <p>Hot pixel correction is applied, without reducing frame
+     * rate relative to sensor raw output.</p>
+     * <p>The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
      *
      * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
      * @see CaptureRequest#HOT_PIXEL_MODE
@@ -1349,10 +1448,9 @@
     public static final int HOT_PIXEL_MODE_FAST = 1;
 
     /**
-     * <p>The frame rate may be reduced relative to sensor raw output
-     * for this option.</p>
-     * <p>A high-quality hot pixel correction is applied.
-     * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+     * <p>High-quality hot pixel correction is applied, at a cost
+     * of reducing frame rate relative to sensor raw output.</p>
+     * <p>The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
      *
      * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
      * @see CaptureRequest#HOT_PIXEL_MODE
@@ -1380,21 +1478,21 @@
     //
 
     /**
-     * <p>No noise reduction is applied</p>
+     * <p>No noise reduction is applied.</p>
      * @see CaptureRequest#NOISE_REDUCTION_MODE
      */
     public static final int NOISE_REDUCTION_MODE_OFF = 0;
 
     /**
-     * <p>Must not slow down frame rate relative to sensor
-     * output</p>
+     * <p>Noise reduction is applied without reducing frame rate relative to sensor
+     * output.</p>
      * @see CaptureRequest#NOISE_REDUCTION_MODE
      */
     public static final int NOISE_REDUCTION_MODE_FAST = 1;
 
     /**
-     * <p>May slow down frame rate to provide highest
-     * quality</p>
+     * <p>High-quality noise reduction is applied, at the cost of reducing frame rate
+     * relative to sensor output.</p>
      * @see CaptureRequest#NOISE_REDUCTION_MODE
      */
     public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2;
@@ -1404,8 +1502,9 @@
     //
 
     /**
-     * <p>Default. No test pattern mode is used, and the camera
+     * <p>No test pattern mode is used, and the camera
      * device returns captures from the image sensor.</p>
+     * <p>This is the default if the key is not set.</p>
      * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
      */
     public static final int SENSOR_TEST_PATTERN_MODE_OFF = 0;
@@ -1509,19 +1608,21 @@
     //
 
     /**
-     * <p>No lens shading correction is applied</p>
+     * <p>No lens shading correction is applied.</p>
      * @see CaptureRequest#SHADING_MODE
      */
     public static final int SHADING_MODE_OFF = 0;
 
     /**
-     * <p>Must not slow down frame rate relative to sensor raw output</p>
+     * <p>Apply lens shading corrections, without slowing
+     * frame rate relative to sensor raw output</p>
      * @see CaptureRequest#SHADING_MODE
      */
     public static final int SHADING_MODE_FAST = 1;
 
     /**
-     * <p>Frame rate may be reduced by high quality</p>
+     * <p>Apply high-quality lens shading correction, at the
+     * cost of reduced frame rate.</p>
      * @see CaptureRequest#SHADING_MODE
      */
     public static final int SHADING_MODE_HIGH_QUALITY = 2;
@@ -1531,20 +1632,28 @@
     //
 
     /**
+     * <p>Do not include face detection statistics in capture
+     * results.</p>
      * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      */
     public static final int STATISTICS_FACE_DETECT_MODE_OFF = 0;
 
     /**
-     * <p>Optional Return rectangle and confidence
-     * only</p>
+     * <p>Return face rectangle and confidence values only.</p>
+     * <p>In this mode, only android.statistics.faceRectangles and
+     * android.statistics.faceScores outputs are valid.</p>
      * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      */
     public static final int STATISTICS_FACE_DETECT_MODE_SIMPLE = 1;
 
     /**
-     * <p>Optional Return all face
-     * metadata</p>
+     * <p>Return all face
+     * metadata.</p>
+     * <p>In this mode,
+     * android.statistics.faceRectangles,
+     * android.statistics.faceScores,
+     * android.statistics.faceIds, and
+     * android.statistics.faceLandmarks outputs are valid.</p>
      * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      */
     public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2;
@@ -1554,11 +1663,13 @@
     //
 
     /**
+     * <p>Do not include a lens shading map in the capture result.</p>
      * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
      */
     public static final int STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0;
 
     /**
+     * <p>Include a lens shading map in the capture result.</p>
      * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
      */
     public static final int STATISTICS_LENS_SHADING_MAP_MODE_ON = 1;
@@ -1582,15 +1693,15 @@
     public static final int TONEMAP_MODE_CONTRAST_CURVE = 0;
 
     /**
-     * <p>Advanced gamma mapping and color enhancement may be applied.</p>
-     * <p>Should not slow down frame rate relative to raw sensor output.</p>
+     * <p>Advanced gamma mapping and color enhancement may be applied, without
+     * reducing frame rate compared to raw sensor output.</p>
      * @see CaptureRequest#TONEMAP_MODE
      */
     public static final int TONEMAP_MODE_FAST = 1;
 
     /**
-     * <p>Advanced gamma mapping and color enhancement may be applied.</p>
-     * <p>May slow down frame rate relative to raw sensor output.</p>
+     * <p>High-quality gamma mapping and color enhancement will be applied, at
+     * the cost of reduced frame rate compared to raw sensor output.</p>
      * @see CaptureRequest#TONEMAP_MODE
      */
     public static final int TONEMAP_MODE_HIGH_QUALITY = 2;
@@ -1600,7 +1711,8 @@
     //
 
     /**
-     * <p>AE is off or recently reset. When a camera device is opened, it starts in
+     * <p>AE is off or recently reset.</p>
+     * <p>When a camera device is opened, it starts in
      * this state. This is a transient state, the camera device may skip reporting
      * this state in capture result.</p>
      * @see CaptureResult#CONTROL_AE_STATE
@@ -1609,7 +1721,8 @@
 
     /**
      * <p>AE doesn't yet have a good set of control values
-     * for the current scene. This is a transient state, the camera device may skip
+     * for the current scene.</p>
+     * <p>This is a transient state, the camera device may skip
      * reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AE_STATE
      */
@@ -1638,11 +1751,13 @@
 
     /**
      * <p>AE has been asked to do a precapture sequence
-     * (through the {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} START),
-     * and is currently executing it. Once PRECAPTURE
-     * completes, AE will transition to CONVERGED or
-     * FLASH_REQUIRED as appropriate. This is a transient state, the
-     * camera device may skip reporting this state in capture result.</p>
+     * and is currently executing it.</p>
+     * <p>Precapture can be triggered through setting
+     * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} to START.</p>
+     * <p>Once PRECAPTURE completes, AE will transition to CONVERGED
+     * or FLASH_REQUIRED as appropriate. This is a transient
+     * state, the camera device may skip reporting this state in
+     * capture result.</p>
      *
      * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
      * @see CaptureResult#CONTROL_AE_STATE
@@ -1654,61 +1769,78 @@
     //
 
     /**
-     * <p>AF off or has not yet tried to scan/been asked
-     * to scan.  When a camera device is opened, it starts in
-     * this state. This is a transient state, the camera device may
-     * skip reporting this state in capture result.</p>
+     * <p>AF is off or has not yet tried to scan/been asked
+     * to scan.</p>
+     * <p>When a camera device is opened, it starts in this
+     * state. This is a transient state, the camera device may
+     * skip reporting this state in capture
+     * result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_INACTIVE = 0;
 
     /**
-     * <p>if CONTINUOUS_* modes are supported. AF is
-     * currently doing an AF scan initiated by a continuous
-     * autofocus mode. This is a transient state, the camera device may
-     * skip reporting this state in capture result.</p>
+     * <p>AF is currently performing an AF scan initiated the
+     * camera device in a continuous autofocus mode.</p>
+     * <p>Only used by CONTINUOUS_* AF modes. This is a transient
+     * state, the camera device may skip reporting this state in
+     * capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_PASSIVE_SCAN = 1;
 
     /**
-     * <p>if CONTINUOUS_* modes are supported. AF currently
-     * believes it is in focus, but may restart scanning at
-     * any time. This is a transient state, the camera device may skip
-     * reporting this state in capture result.</p>
+     * <p>AF currently believes it is in focus, but may
+     * restart scanning at any time.</p>
+     * <p>Only used by CONTINUOUS_* AF modes. This is a transient
+     * state, the camera device may skip reporting this state in
+     * capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_PASSIVE_FOCUSED = 2;
 
     /**
-     * <p>if AUTO or MACRO modes are supported. AF is doing
-     * an AF scan because it was triggered by AF trigger. This is a
-     * transient state, the camera device may skip reporting
-     * this state in capture result.</p>
+     * <p>AF is performing an AF scan because it was
+     * triggered by AF trigger.</p>
+     * <p>Only used by AUTO or MACRO AF modes. This is a transient
+     * state, the camera device may skip reporting this state in
+     * capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_ACTIVE_SCAN = 3;
 
     /**
-     * <p>if any AF mode besides OFF is supported. AF
-     * believes it is focused correctly and is
-     * locked.</p>
+     * <p>AF believes it is focused correctly and has locked
+     * focus.</p>
+     * <p>This state is reached only after an explicit START AF trigger has been
+     * sent ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}), when good focus has been obtained.</p>
+     * <p>The lens will remain stationary until the AF mode ({@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}) is changed or
+     * a new AF trigger is sent to the camera device ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}).</p>
+     *
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CaptureRequest#CONTROL_AF_TRIGGER
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_FOCUSED_LOCKED = 4;
 
     /**
-     * <p>if any AF mode besides OFF is supported. AF has
-     * failed to focus successfully and is
-     * locked.</p>
+     * <p>AF has failed to focus successfully and has locked
+     * focus.</p>
+     * <p>This state is reached only after an explicit START AF trigger has been
+     * sent ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}), when good focus cannot be obtained.</p>
+     * <p>The lens will remain stationary until the AF mode ({@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}) is changed or
+     * a new AF trigger is sent to the camera device ({@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}).</p>
+     *
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CaptureRequest#CONTROL_AF_TRIGGER
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5;
 
     /**
-     * <p>if CONTINUOUS_* modes are supported. AF finished a
-     * passive scan without finding focus, and may restart
-     * scanning at any time. This is a transient state, the camera
+     * <p>AF finished a passive scan without finding focus,
+     * and may restart scanning at any time.</p>
+     * <p>Only used by CONTINUOUS_* AF modes. This is a transient state, the camera
      * device may skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
@@ -1719,16 +1851,19 @@
     //
 
     /**
-     * <p>AWB is not in auto mode.  When a camera device is opened, it
-     * starts in this state. This is a transient state, the camera device may
-     * skip reporting this state in capture result.</p>
+     * <p>AWB is not in auto mode, or has not yet started metering.</p>
+     * <p>When a camera device is opened, it starts in this
+     * state. This is a transient state, the camera device may
+     * skip reporting this state in capture
+     * result.</p>
      * @see CaptureResult#CONTROL_AWB_STATE
      */
     public static final int CONTROL_AWB_STATE_INACTIVE = 0;
 
     /**
      * <p>AWB doesn't yet have a good set of control
-     * values for the current scene. This is a transient state, the camera device
+     * values for the current scene.</p>
+     * <p>This is a transient state, the camera device
      * may skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AWB_STATE
      */
@@ -1776,8 +1911,9 @@
     public static final int FLASH_STATE_FIRED = 3;
 
     /**
-     * <p>Flash partially illuminated this frame. This is usually due to the next
-     * or previous frame having the flash fire, and the flash spilling into this capture
+     * <p>Flash partially illuminated this frame.</p>
+     * <p>This is usually due to the next or previous frame having
+     * the flash fire, and the flash spilling into this capture
      * due to hardware limitations.</p>
      * @see CaptureResult#FLASH_STATE
      */
@@ -1800,8 +1936,10 @@
     public static final int LENS_STATE_STATIONARY = 0;
 
     /**
-     * <p>Any of the lens parameters ({@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance},
-     * {@link CaptureRequest#LENS_FILTER_DENSITY android.lens.filterDensity} or {@link CaptureRequest#LENS_APERTURE android.lens.aperture}) is changing.</p>
+     * <p>One or several of the lens parameters
+     * ({@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance},
+     * {@link CaptureRequest#LENS_FILTER_DENSITY android.lens.filterDensity} or {@link CaptureRequest#LENS_APERTURE android.lens.aperture}) is
+     * currently changing.</p>
      *
      * @see CaptureRequest#LENS_APERTURE
      * @see CaptureRequest#LENS_FILTER_DENSITY
@@ -1816,16 +1954,22 @@
     //
 
     /**
+     * <p>The camera device does not detect any flickering illumination
+     * in the current scene.</p>
      * @see CaptureResult#STATISTICS_SCENE_FLICKER
      */
     public static final int STATISTICS_SCENE_FLICKER_NONE = 0;
 
     /**
+     * <p>The camera device detects illumination flickering at 50Hz
+     * in the current scene.</p>
      * @see CaptureResult#STATISTICS_SCENE_FLICKER
      */
     public static final int STATISTICS_SCENE_FLICKER_50HZ = 1;
 
     /**
+     * <p>The camera device detects illumination flickering at 60Hz
+     * in the current scene.</p>
      * @see CaptureResult#STATISTICS_SCENE_FLICKER
      */
     public static final int STATISTICS_SCENE_FLICKER_60HZ = 2;
@@ -1835,8 +1979,8 @@
     //
 
     /**
-     * <p>The current result is not yet fully synchronized to any request.
-     * Synchronization is in progress, and reading metadata from this
+     * <p>The current result is not yet fully synchronized to any request.</p>
+     * <p>Synchronization is in progress, and reading metadata from this
      * result may include a mix of data that have taken effect since the
      * last synchronization time.</p>
      * <p>In some future result, within {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} frames,
@@ -1851,10 +1995,10 @@
     public static final int SYNC_FRAME_NUMBER_CONVERGING = -1;
 
     /**
-     * <p>The current result's synchronization status is unknown. The
-     * result may have already converged, or it may be in progress.
-     * Reading from this result may include some mix of settings from
-     * past requests.</p>
+     * <p>The current result's synchronization status is unknown.</p>
+     * <p>The result may have already converged, or it may be in
+     * progress.  Reading from this result may include some mix
+     * of settings from past requests.</p>
      * <p>After a settings change, the new settings will eventually all
      * take effect for the output buffers and results. However, this
      * value will not change when that happens. Altering settings
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 0ff8cce..bf7bd37 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -733,8 +733,16 @@
      * included at all in the request settings. When included and
      * set to START, the camera device will trigger the autoexposure
      * precapture metering sequence.</p>
-     * <p>The effect of auto-exposure (AE) precapture trigger depends
-     * on the current AE mode and state; see
+     * <p>The precapture sequence should triggered before starting a
+     * high-quality still capture for final metering decisions to
+     * be made, and for firing pre-capture flash pulses to estimate
+     * scene brightness and required final capture flash power, when
+     * the flash is enabled.</p>
+     * <p>Normally, this entry should be set to START for only a
+     * single request, and the application should wait until the
+     * sequence completes before starting a new one.</p>
+     * <p>The exact effect of auto-exposure (AE) precapture trigger
+     * depends on the current AE mode and state; see
      * {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} for AE precapture state transition
      * details.</p>
      *
@@ -800,7 +808,11 @@
      * autofocus algorithm. If autofocus is disabled, this trigger has no effect.</p>
      * <p>When set to CANCEL, the camera device will cancel any active trigger,
      * and return to its initial AF state.</p>
-     * <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what that means for each AF mode.</p>
+     * <p>Generally, applications should set this entry to START or CANCEL for only a
+     * single capture, and then return it to IDLE (or not set at all). Specifying
+     * START for multiple captures in a row means restarting the AF operation over
+     * and over again.</p>
+     * <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
      *
      * @see CaptureResult#CONTROL_AF_STATE
      * @see #CONTROL_AF_TRIGGER_IDLE
@@ -813,9 +825,11 @@
     /**
      * <p>Whether auto-white balance (AWB) is currently locked to its
      * latest calculated values.</p>
-     * <p>Note that AWB lock is only meaningful for AUTO
-     * mode; in other modes, AWB is already fixed to a specific
-     * setting.</p>
+     * <p>Note that AWB lock is only meaningful when
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} is in the AUTO mode; in other modes,
+     * AWB is already fixed to a specific setting.</p>
+     *
+     * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final Key<Boolean> CONTROL_AWB_LOCK =
             new Key<Boolean>("android.control.awbLock", boolean.class);
@@ -825,17 +839,21 @@
      * transform fields, and what its illumination target
      * is.</p>
      * <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
-     * <p>When set to the ON mode, the camera device's auto white balance
+     * <p>When set to the ON mode, the camera device's auto-white balance
      * routine is enabled, overriding the application's selected
      * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
-     * <p>When set to the OFF mode, the camera device's auto white balance
+     * <p>When set to the OFF mode, the camera device's auto-white balance
      * routine is disabled. The application manually controls the white
      * balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
      * and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
-     * <p>When set to any other modes, the camera device's auto white balance
-     * routine is disabled. The camera device uses each particular illumination
-     * target for white balance adjustment.</p>
+     * <p>When set to any other modes, the camera device's auto-white
+     * balance routine is disabled. The camera device uses each
+     * particular illumination target for white balance
+     * adjustment. The application's values for
+     * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform},
+     * {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} are ignored.</p>
      *
      * @see CaptureRequest#COLOR_CORRECTION_GAINS
      * @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -886,8 +904,8 @@
      * strategy.</p>
      * <p>This control (except for MANUAL) is only effective if
      * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
-     * <p>ZERO_SHUTTER_LAG must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
-     * contains ZSL. MANUAL must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+     * <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+     * contains ZSL. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
      * contains MANUAL_SENSOR.</p>
      *
      * @see CaptureRequest#CONTROL_MODE
@@ -962,7 +980,9 @@
      * <p>This is the mode that that is active when
      * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY,
      * these modes will disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
-     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.</p>
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.
+     * The scene modes available for a given camera device are listed in
+     * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}.</p>
      * <p>The interpretation and implementation of these scene modes is left
      * to the implementor of the camera device. Their behavior will not be
      * consistent across all devices, and any given device may only implement
@@ -970,6 +990,7 @@
      *
      * @see CaptureRequest#CONTROL_AE_MODE
      * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
      * @see CaptureRequest#CONTROL_AWB_MODE
      * @see CaptureRequest#CONTROL_MODE
      * @see #CONTROL_SCENE_MODE_DISABLED
@@ -996,6 +1017,8 @@
     /**
      * <p>Whether video stabilization is
      * active.</p>
+     * <p>Video stabilization automatically translates and scales images from the camera
+     * in order to stabilize motion between consecutive frames.</p>
      * <p>If enabled, video stabilization can modify the
      * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to keep the video stream
      * stabilized</p>
@@ -1110,14 +1133,14 @@
     /**
      * <p>Compression quality of the final JPEG
      * image.</p>
-     * <p>85-95 is typical usage range</p>
+     * <p>85-95 is typical usage range.</p>
      */
     public static final Key<Byte> JPEG_QUALITY =
             new Key<Byte>("android.jpeg.quality", byte.class);
 
     /**
      * <p>Compression quality of JPEG
-     * thumbnail</p>
+     * thumbnail.</p>
      */
     public static final Key<Byte> JPEG_THUMBNAIL_QUALITY =
             new Key<Byte>("android.jpeg.thumbnailQuality", byte.class);
@@ -1229,12 +1252,18 @@
     /**
      * <p>Sets whether the camera device uses optical image stabilization (OIS)
      * when capturing images.</p>
-     * <p>OIS is used to compensate for motion blur due to small movements of
-     * the camera during capture. Unlike digital image stabilization, OIS makes
-     * use of mechanical elements to stabilize the camera sensor, and thus
-     * allows for longer exposure times before camera shake becomes
-     * apparent.</p>
-     * <p>This is not expected to be supported on most devices.</p>
+     * <p>OIS is used to compensate for motion blur due to small
+     * movements of the camera during capture. Unlike digital image
+     * stabilization ({@link CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE android.control.videoStabilizationMode}), OIS
+     * makes use of mechanical elements to stabilize the camera
+     * sensor, and thus allows for longer exposure times before
+     * camera shake becomes apparent.</p>
+     * <p>Not all devices will support OIS; see
+     * {@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization} for
+     * available controls.</p>
+     *
+     * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION
      * @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
      * @see #LENS_OPTICAL_STABILIZATION_MODE_ON
      */
@@ -1242,16 +1271,15 @@
             new Key<Integer>("android.lens.opticalStabilizationMode", int.class);
 
     /**
-     * <p>Mode of operation for the noise reduction.
-     * algorithm</p>
+     * <p>Mode of operation for the noise reduction algorithm.</p>
      * <p>Noise filtering control. OFF means no noise reduction
      * will be applied by the camera device.</p>
-     * <p>This must be set to a valid mode in
+     * <p>This must be set to a valid mode from
      * {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}.</p>
      * <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
      * will be applied. HIGH_QUALITY mode indicates that the camera device
      * will use the highest-quality noise filtering algorithms,
-     * even if it slows down capture rate. FAST means the camera device should not
+     * even if it slows down capture rate. FAST means the camera device will not
      * slow down capture rate when applying noise filtering.</p>
      *
      * @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
@@ -1435,7 +1463,7 @@
      * <p>When enabled, the sensor sends a test pattern instead of
      * doing a real exposure from the camera.</p>
      * <p>When a test pattern is enabled, all manual sensor controls specified
-     * by android.sensor.* should be ignored. All other controls should
+     * by android.sensor.* will be ignored. All other controls should
      * work as normal.</p>
      * <p>For example, if manual flash is enabled, flash firing should still
      * occur (and that the test pattern remain unmodified, since the flash
@@ -1490,7 +1518,7 @@
             new Key<Integer>("android.shading.mode", int.class);
 
     /**
-     * <p>State of the face detector
+     * <p>Control for the face detector
      * unit.</p>
      * <p>Whether face detection is enabled, and whether it
      * should output just the basic fields or the full set of
@@ -1508,7 +1536,7 @@
     /**
      * <p>Operating mode for hotpixel map generation.</p>
      * <p>If set to ON, a hotpixel map is returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.
-     * If set to OFF, no hotpixel map should be returned.</p>
+     * If set to OFF, no hotpixel map will be returned.</p>
      * <p>This must be set to a valid mode from {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES android.statistics.info.availableHotPixelMapModes}.</p>
      *
      * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
@@ -1521,7 +1549,7 @@
      * <p>Whether the camera device will output the lens
      * shading map in output result metadata.</p>
      * <p>When set to ON,
-     * android.statistics.lensShadingMap must be provided in
+     * android.statistics.lensShadingMap will be provided in
      * the output result metadata.</p>
      * @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
      * @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index ce3de1d..3d17ed3 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -579,8 +579,16 @@
      * included at all in the request settings. When included and
      * set to START, the camera device will trigger the autoexposure
      * precapture metering sequence.</p>
-     * <p>The effect of auto-exposure (AE) precapture trigger depends
-     * on the current AE mode and state; see
+     * <p>The precapture sequence should triggered before starting a
+     * high-quality still capture for final metering decisions to
+     * be made, and for firing pre-capture flash pulses to estimate
+     * scene brightness and required final capture flash power, when
+     * the flash is enabled.</p>
+     * <p>Normally, this entry should be set to START for only a
+     * single request, and the application should wait until the
+     * sequence completes before starting a new one.</p>
+     * <p>The exact effect of auto-exposure (AE) precapture trigger
+     * depends on the current AE mode and state; see
      * {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} for AE precapture state transition
      * details.</p>
      *
@@ -592,7 +600,7 @@
             new Key<Integer>("android.control.aePrecaptureTrigger", int.class);
 
     /**
-     * <p>Current state of auto-exposure (AE) algorithm.</p>
+     * <p>Current state of the auto-exposure (AE) algorithm.</p>
      * <p>Switching between or enabling AE modes ({@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}) always
      * resets the AE state to INACTIVE. Similarly, switching between {@link CaptureRequest#CONTROL_MODE android.control.mode},
      * or {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} if <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code> resets all
@@ -844,7 +852,11 @@
      * autofocus algorithm. If autofocus is disabled, this trigger has no effect.</p>
      * <p>When set to CANCEL, the camera device will cancel any active trigger,
      * and return to its initial AF state.</p>
-     * <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what that means for each AF mode.</p>
+     * <p>Generally, applications should set this entry to START or CANCEL for only a
+     * single capture, and then return it to IDLE (or not set at all). Specifying
+     * START for multiple captures in a row means restarting the AF operation over
+     * and over again.</p>
+     * <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what the trigger means for each AF mode.</p>
      *
      * @see CaptureResult#CONTROL_AF_STATE
      * @see #CONTROL_AF_TRIGGER_IDLE
@@ -1034,13 +1046,13 @@
      * <td align="center">PASSIVE_SCAN</td>
      * <td align="center">AF_TRIGGER</td>
      * <td align="center">FOCUSED_LOCKED</td>
-     * <td align="center">Immediate trans. If focus is good, Lens now locked</td>
+     * <td align="center">Immediate transition, if focus is good. Lens now locked</td>
      * </tr>
      * <tr>
      * <td align="center">PASSIVE_SCAN</td>
      * <td align="center">AF_TRIGGER</td>
      * <td align="center">NOT_FOCUSED_LOCKED</td>
-     * <td align="center">Immediate trans. if focus is bad, Lens now locked</td>
+     * <td align="center">Immediate transition, if focus is bad. Lens now locked</td>
      * </tr>
      * <tr>
      * <td align="center">PASSIVE_SCAN</td>
@@ -1064,13 +1076,13 @@
      * <td align="center">PASSIVE_FOCUSED</td>
      * <td align="center">AF_TRIGGER</td>
      * <td align="center">FOCUSED_LOCKED</td>
-     * <td align="center">Immediate trans. Lens now locked</td>
+     * <td align="center">Immediate transition, lens now locked</td>
      * </tr>
      * <tr>
      * <td align="center">PASSIVE_UNFOCUSED</td>
      * <td align="center">AF_TRIGGER</td>
      * <td align="center">NOT_FOCUSED_LOCKED</td>
-     * <td align="center">Immediate trans. Lens now locked</td>
+     * <td align="center">Immediate transition, lens now locked</td>
      * </tr>
      * <tr>
      * <td align="center">FOCUSED_LOCKED</td>
@@ -1137,13 +1149,13 @@
      * <td align="center">PASSIVE_SCAN</td>
      * <td align="center">AF_TRIGGER</td>
      * <td align="center">FOCUSED_LOCKED</td>
-     * <td align="center">Eventual trans. once focus good, Lens now locked</td>
+     * <td align="center">Eventual transition once the focus is good. Lens now locked</td>
      * </tr>
      * <tr>
      * <td align="center">PASSIVE_SCAN</td>
      * <td align="center">AF_TRIGGER</td>
      * <td align="center">NOT_FOCUSED_LOCKED</td>
-     * <td align="center">Eventual trans. if cannot focus, Lens now locked</td>
+     * <td align="center">Eventual transition if cannot find focus. Lens now locked</td>
      * </tr>
      * <tr>
      * <td align="center">PASSIVE_SCAN</td>
@@ -1254,9 +1266,11 @@
     /**
      * <p>Whether auto-white balance (AWB) is currently locked to its
      * latest calculated values.</p>
-     * <p>Note that AWB lock is only meaningful for AUTO
-     * mode; in other modes, AWB is already fixed to a specific
-     * setting.</p>
+     * <p>Note that AWB lock is only meaningful when
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} is in the AUTO mode; in other modes,
+     * AWB is already fixed to a specific setting.</p>
+     *
+     * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final Key<Boolean> CONTROL_AWB_LOCK =
             new Key<Boolean>("android.control.awbLock", boolean.class);
@@ -1266,17 +1280,21 @@
      * transform fields, and what its illumination target
      * is.</p>
      * <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
-     * <p>When set to the ON mode, the camera device's auto white balance
+     * <p>When set to the ON mode, the camera device's auto-white balance
      * routine is enabled, overriding the application's selected
      * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
-     * <p>When set to the OFF mode, the camera device's auto white balance
+     * <p>When set to the OFF mode, the camera device's auto-white balance
      * routine is disabled. The application manually controls the white
      * balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
      * and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
-     * <p>When set to any other modes, the camera device's auto white balance
-     * routine is disabled. The camera device uses each particular illumination
-     * target for white balance adjustment.</p>
+     * <p>When set to any other modes, the camera device's auto-white
+     * balance routine is disabled. The camera device uses each
+     * particular illumination target for white balance
+     * adjustment. The application's values for
+     * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform},
+     * {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} are ignored.</p>
      *
      * @see CaptureRequest#COLOR_CORRECTION_GAINS
      * @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -1327,8 +1345,8 @@
      * strategy.</p>
      * <p>This control (except for MANUAL) is only effective if
      * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
-     * <p>ZERO_SHUTTER_LAG must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
-     * contains ZSL. MANUAL must be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+     * <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+     * contains ZSL. MANUAL will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
      * contains MANUAL_SENSOR.</p>
      *
      * @see CaptureRequest#CONTROL_MODE
@@ -1533,7 +1551,9 @@
      * <p>This is the mode that that is active when
      * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY,
      * these modes will disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
-     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.</p>
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.
+     * The scene modes available for a given camera device are listed in
+     * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}.</p>
      * <p>The interpretation and implementation of these scene modes is left
      * to the implementor of the camera device. Their behavior will not be
      * consistent across all devices, and any given device may only implement
@@ -1541,6 +1561,7 @@
      *
      * @see CaptureRequest#CONTROL_AE_MODE
      * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES
      * @see CaptureRequest#CONTROL_AWB_MODE
      * @see CaptureRequest#CONTROL_MODE
      * @see #CONTROL_SCENE_MODE_DISABLED
@@ -1567,6 +1588,8 @@
     /**
      * <p>Whether video stabilization is
      * active.</p>
+     * <p>Video stabilization automatically translates and scales images from the camera
+     * in order to stabilize motion between consecutive frames.</p>
      * <p>If enabled, video stabilization can modify the
      * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to keep the video stream
      * stabilized</p>
@@ -1698,14 +1721,14 @@
     /**
      * <p>Compression quality of the final JPEG
      * image.</p>
-     * <p>85-95 is typical usage range</p>
+     * <p>85-95 is typical usage range.</p>
      */
     public static final Key<Byte> JPEG_QUALITY =
             new Key<Byte>("android.jpeg.quality", byte.class);
 
     /**
      * <p>Compression quality of JPEG
-     * thumbnail</p>
+     * thumbnail.</p>
      */
     public static final Key<Byte> JPEG_THUMBNAIL_QUALITY =
             new Key<Byte>("android.jpeg.thumbnailQuality", byte.class);
@@ -1817,12 +1840,18 @@
     /**
      * <p>Sets whether the camera device uses optical image stabilization (OIS)
      * when capturing images.</p>
-     * <p>OIS is used to compensate for motion blur due to small movements of
-     * the camera during capture. Unlike digital image stabilization, OIS makes
-     * use of mechanical elements to stabilize the camera sensor, and thus
-     * allows for longer exposure times before camera shake becomes
-     * apparent.</p>
-     * <p>This is not expected to be supported on most devices.</p>
+     * <p>OIS is used to compensate for motion blur due to small
+     * movements of the camera during capture. Unlike digital image
+     * stabilization ({@link CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE android.control.videoStabilizationMode}), OIS
+     * makes use of mechanical elements to stabilize the camera
+     * sensor, and thus allows for longer exposure times before
+     * camera shake becomes apparent.</p>
+     * <p>Not all devices will support OIS; see
+     * {@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization} for
+     * available controls.</p>
+     *
+     * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION
      * @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
      * @see #LENS_OPTICAL_STABILIZATION_MODE_ON
      */
@@ -1866,16 +1895,15 @@
             new Key<Integer>("android.lens.state", int.class);
 
     /**
-     * <p>Mode of operation for the noise reduction.
-     * algorithm</p>
+     * <p>Mode of operation for the noise reduction algorithm.</p>
      * <p>Noise filtering control. OFF means no noise reduction
      * will be applied by the camera device.</p>
-     * <p>This must be set to a valid mode in
+     * <p>This must be set to a valid mode from
      * {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}.</p>
      * <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
      * will be applied. HIGH_QUALITY mode indicates that the camera device
      * will use the highest-quality noise filtering algorithms,
-     * even if it slows down capture rate. FAST means the camera device should not
+     * even if it slows down capture rate. FAST means the camera device will not
      * slow down capture rate when applying noise filtering.</p>
      *
      * @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
@@ -2170,7 +2198,7 @@
      * <p>When enabled, the sensor sends a test pattern instead of
      * doing a real exposure from the camera.</p>
      * <p>When a test pattern is enabled, all manual sensor controls specified
-     * by android.sensor.* should be ignored. All other controls should
+     * by android.sensor.* will be ignored. All other controls should
      * work as normal.</p>
      * <p>For example, if manual flash is enabled, flash firing should still
      * occur (and that the test pattern remain unmodified, since the flash
@@ -2225,7 +2253,7 @@
             new Key<Integer>("android.shading.mode", int.class);
 
     /**
-     * <p>State of the face detector
+     * <p>Control for the face detector
      * unit.</p>
      * <p>Whether face detection is enabled, and whether it
      * should output just the basic fields or the full set of
@@ -2241,9 +2269,13 @@
             new Key<Integer>("android.statistics.faceDetectMode", int.class);
 
     /**
-     * <p>List of unique IDs for detected
-     * faces</p>
-     * <p>Only available if faceDetectMode == FULL</p>
+     * <p>List of unique IDs for detected faces.</p>
+     * <p>Each detected face is given a unique ID that is valid for as long as the face is visible
+     * to the camera device.  A face that leaves the field of view and later returns may be
+     * assigned a new ID.</p>
+     * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} == FULL</p>
+     *
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      * @hide
      */
     public static final Key<int[]> STATISTICS_FACE_IDS =
@@ -2251,8 +2283,13 @@
 
     /**
      * <p>List of landmarks for detected
-     * faces</p>
-     * <p>Only available if faceDetectMode == FULL</p>
+     * faces.</p>
+     * <p>The coordinate system is that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+     * <code>(0, 0)</code> being the top-left pixel of the active array.</p>
+     * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} == FULL</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      * @hide
      */
     public static final Key<int[]> STATISTICS_FACE_LANDMARKS =
@@ -2260,8 +2297,13 @@
 
     /**
      * <p>List of the bounding rectangles for detected
-     * faces</p>
-     * <p>Only available if faceDetectMode != OFF</p>
+     * faces.</p>
+     * <p>The coordinate system is that of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
+     * <code>(0, 0)</code> being the top-left pixel of the active array.</p>
+     * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} != OFF</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      * @hide
      */
     public static final Key<android.graphics.Rect[]> STATISTICS_FACE_RECTANGLES =
@@ -2270,8 +2312,9 @@
     /**
      * <p>List of the face confidence scores for
      * detected faces</p>
-     * <p>Only available if faceDetectMode != OFF. The value should be
-     * meaningful (for example, setting 100 at all times is illegal).</p>
+     * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} != OFF.</p>
+     *
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      * @hide
      */
     public static final Key<byte[]> STATISTICS_FACE_SCORES =
@@ -2435,12 +2478,13 @@
      * The camera device uses this entry to tell the application what the scene
      * illuminant frequency is.</p>
      * <p>When manual exposure control is enabled
-     * (<code>{@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} == OFF</code> or <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == OFF</code>),
-     * the {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} doesn't do the antibanding, and the
-     * application can ensure it selects exposure times that do not cause banding
-     * issues by looking into this metadata field. See {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode}
-     * for more details.</p>
-     * <p>Report NONE if there doesn't appear to be flickering illumination.</p>
+     * (<code>{@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} == OFF</code> or <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} ==
+     * OFF</code>), the {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} doesn't perform
+     * antibanding, and the application can ensure it selects
+     * exposure times that do not cause banding issues by looking
+     * into this metadata field. See
+     * {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} for more details.</p>
+     * <p>Reports NONE if there doesn't appear to be flickering illumination.</p>
      *
      * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
      * @see CaptureRequest#CONTROL_AE_MODE
@@ -2455,7 +2499,7 @@
     /**
      * <p>Operating mode for hotpixel map generation.</p>
      * <p>If set to ON, a hotpixel map is returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.
-     * If set to OFF, no hotpixel map should be returned.</p>
+     * If set to OFF, no hotpixel map will be returned.</p>
      * <p>This must be set to a valid mode from {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES android.statistics.info.availableHotPixelMapModes}.</p>
      *
      * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
@@ -2483,7 +2527,7 @@
      * <p>Whether the camera device will output the lens
      * shading map in output result metadata.</p>
      * <p>When set to ON,
-     * android.statistics.lensShadingMap must be provided in
+     * android.statistics.lensShadingMap will be provided in
      * the output result metadata.</p>
      * @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
      * @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
diff --git a/core/java/android/hardware/camera2/params/StreamConfiguration.java b/core/java/android/hardware/camera2/params/StreamConfiguration.java
index dd862b5..a6fc10f 100644
--- a/core/java/android/hardware/camera2/params/StreamConfiguration.java
+++ b/core/java/android/hardware/camera2/params/StreamConfiguration.java
@@ -30,7 +30,8 @@
  * Immutable class to store the available stream
  * {@link CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS configurations} to set up
  * {@link android.view.Surface Surfaces} for creating a {@link CameraCaptureSession capture session}
- * with {@link CameraDevice#createCaptureSession}.  <!-- TODO: link to input stream configuration -->
+ * with {@link CameraDevice#createCaptureSession}.
+ * <!-- TODO: link to input stream configuration -->
  *
  * <p>This is the authoritative list for all input/output formats (and sizes respectively
  * for that format) that are supported by a camera device.</p>
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 60e76e0..65d4726 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -429,6 +429,11 @@
      */
     public final static int INVALID_NET_ID = 0;
 
+    /**
+     * @hide
+     */
+    public final static int REQUEST_ID_UNSET = 0;
+
     private final IConnectivityManager mService;
 
     private final String mPackageName;
@@ -883,8 +888,8 @@
      * @hide
      */
     public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
-        for (Integer capability : nc.getNetworkCapabilities()) {
-            switch (capability.intValue()) {
+        for (int capability : nc.getCapabilities()) {
+            switch (capability) {
                 case NetworkCapabilities.NET_CAPABILITY_CBS:
                 case NetworkCapabilities.NET_CAPABILITY_DUN:
                 case NetworkCapabilities.NET_CAPABILITY_EIMS:
@@ -902,7 +907,7 @@
         }
         // All the capabilities are typically provided by restricted networks.
         // Conclude that this network is restricted.
-        nc.removeNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
     }
 
     private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
@@ -926,15 +931,14 @@
                 return null;
             }
             NetworkCapabilities netCap = new NetworkCapabilities();
-            netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-            netCap.addNetworkCapability(cap);
+            netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
             maybeMarkCapabilitiesRestricted(netCap);
             return netCap;
         } else if (networkType == TYPE_WIFI) {
             if ("p2p".equals(feature)) {
                 NetworkCapabilities netCap = new NetworkCapabilities();
                 netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
-                netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
+                netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
                 maybeMarkCapabilitiesRestricted(netCap);
                 return netCap;
             }
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 22b26b1..49a307e 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -74,8 +74,10 @@
         if (linkProperties.getRoutes().size() == 0) {
             for (RouteInfo r : orig.linkProperties.getRoutes()) linkProperties.addRoute(r);
         }
-        if (linkProperties.getDnses().size() == 0) {
-            for (InetAddress d : orig.linkProperties.getDnses()) linkProperties.addDns(d);
+        if (linkProperties.getDnsServers().size() == 0) {
+            for (InetAddress d : orig.linkProperties.getDnsServers()) {
+                linkProperties.addDnsServer(d);
+            }
         }
     }
 
@@ -211,7 +213,7 @@
     public boolean addDns(String addrString) {
         if (TextUtils.isEmpty(addrString) == false) {
             try {
-                linkProperties.addDns(NetworkUtils.numericToInetAddress(addrString));
+                linkProperties.addDnsServer(NetworkUtils.numericToInetAddress(addrString));
             } catch (IllegalArgumentException e) {
                 Log.e(TAG, "addDns failed with addrString " + addrString);
                 return true;
diff --git a/core/java/android/net/DnsPinger.java b/core/java/android/net/DnsPinger.java
index 66f0fd0..7acf3f5 100644
--- a/core/java/android/net/DnsPinger.java
+++ b/core/java/android/net/DnsPinger.java
@@ -248,7 +248,7 @@
             return mDefaultDns;
         }
 
-        Collection<InetAddress> dnses = curLinkProps.getDnses();
+        Collection<InetAddress> dnses = curLinkProps.getDnsServers();
         if (dnses == null || dnses.size() == 0) {
             loge("getDns::LinkProps has null dns - returning default");
             return mDefaultDns;
diff --git a/core/java/android/net/IpPrefix.aidl b/core/java/android/net/IpPrefix.aidl
new file mode 100644
index 0000000..9e552c7
--- /dev/null
+++ b/core/java/android/net/IpPrefix.aidl
@@ -0,0 +1,20 @@
+/**
+ *
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+parcelable IpPrefix;
diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java
new file mode 100644
index 0000000..a14d13f
--- /dev/null
+++ b/core/java/android/net/IpPrefix.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+/**
+ * This class represents an IP prefix, i.e., a contiguous block of IP addresses aligned on a
+ * power of two boundary (also known as an "IP subnet"). A prefix is specified by two pieces of
+ * information:
+ *
+ * <ul>
+ * <li>A starting IP address (IPv4 or IPv6). This is the first IP address of the prefix.
+ * <li>A prefix length. This specifies the length of the prefix by specifing the number of bits
+ *     in the IP address, starting from the most significant bit in network byte order, that
+ *     are constant for all addresses in the prefix.
+ * </ul>
+ *
+ * For example, the prefix <code>192.0.2.0/24</code> covers the 256 IPv4 addresses from
+ * <code>192.0.2.0</code> to <code>192.0.2.255</code>, inclusive, and the prefix
+ * <code>2001:db8:1:2</code>  covers the 2^64 IPv6 addresses from <code>2001:db8:1:2::</code> to
+ * <code>2001:db8:1:2:ffff:ffff:ffff:ffff</code>, inclusive.
+ *
+ * Objects of this class are immutable.
+ */
+public final class IpPrefix implements Parcelable {
+    private final byte[] address;  // network byte order
+    private final int prefixLength;
+
+    /**
+     * Constructs a new {@code IpPrefix} from a byte array containing an IPv4 or IPv6 address in
+     * network byte order and a prefix length.
+     *
+     * @param address the IP address. Must be non-null and exactly 4 or 16 bytes long.
+     * @param prefixLength the prefix length. Must be &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 3c36679..8eefa0f 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -30,6 +30,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Hashtable;
+import java.util.List;
 
 /**
  * Describes the properties of a network link.
@@ -43,7 +44,7 @@
  * does not affect live networks.
  *
  */
-public class LinkProperties implements Parcelable {
+public final class LinkProperties implements Parcelable {
     // The interface described by the network link.
     private String mIfaceName;
     private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
@@ -58,10 +59,12 @@
     private Hashtable<String, LinkProperties> mStackedLinks =
         new Hashtable<String, LinkProperties>();
 
-    // @hide
+    /**
+     * @hide
+     */
     public static class CompareResult<T> {
-        public Collection<T> removed = new ArrayList<T>();
-        public Collection<T> added = new ArrayList<T>();
+        public List<T> removed = new ArrayList<T>();
+        public List<T> added = new ArrayList<T>();
 
         @Override
         public String toString() {
@@ -74,14 +77,20 @@
         }
     }
 
+    /**
+     * @hide
+     */
     public LinkProperties() {
     }
 
+    /**
+     * @hide
+     */
     public LinkProperties(LinkProperties source) {
         if (source != null) {
             mIfaceName = source.getInterfaceName();
             for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l);
-            for (InetAddress i : source.getDnses()) mDnses.add(i);
+            for (InetAddress i : source.getDnsServers()) mDnses.add(i);
             mDomains = source.getDomains();
             for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
             mHttpProxy = (source.getHttpProxy() == null)  ?
@@ -98,6 +107,7 @@
      * will have their interface changed to match this new value.
      *
      * @param iface The name of the network interface used for this link.
+     * @hide
      */
     public void setInterfaceName(String iface) {
         mIfaceName = iface;
@@ -117,9 +127,11 @@
         return mIfaceName;
     }
 
-    // @hide
-    public Collection<String> getAllInterfaceNames() {
-        Collection interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
+    /**
+     * @hide
+     */
+    public List<String> getAllInterfaceNames() {
+        List<String> interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
         if (mIfaceName != null) interfaceNames.add(new String(mIfaceName));
         for (LinkProperties stacked: mStackedLinks.values()) {
             interfaceNames.addAll(stacked.getAllInterfaceNames());
@@ -134,23 +146,23 @@
      * prefix lengths for each address.  This is a simplified utility alternative to
      * {@link LinkProperties#getLinkAddresses}.
      *
-     * @return An umodifiable {@link Collection} of {@link InetAddress} for this link.
+     * @return An umodifiable {@link List} of {@link InetAddress} for this link.
      * @hide
      */
-    public Collection<InetAddress> getAddresses() {
-        Collection<InetAddress> addresses = new ArrayList<InetAddress>();
+    public List<InetAddress> getAddresses() {
+        List<InetAddress> addresses = new ArrayList<InetAddress>();
         for (LinkAddress linkAddress : mLinkAddresses) {
             addresses.add(linkAddress.getAddress());
         }
-        return Collections.unmodifiableCollection(addresses);
+        return Collections.unmodifiableList(addresses);
     }
 
     /**
      * Returns all the addresses on this link and all the links stacked above it.
      * @hide
      */
-    public Collection<InetAddress> getAllAddresses() {
-        Collection<InetAddress> addresses = new ArrayList<InetAddress>();
+    public List<InetAddress> getAllAddresses() {
+        List<InetAddress> addresses = new ArrayList<InetAddress>();
         for (LinkAddress linkAddress : mLinkAddresses) {
             addresses.add(linkAddress.getAddress());
         }
@@ -174,6 +186,7 @@
      * same address/prefix does not already exist.  If it does exist it is replaced.
      * @param address The {@code LinkAddress} to add.
      * @return true if {@code address} was added or updated, false otherwise.
+     * @hide
      */
     public boolean addLinkAddress(LinkAddress address) {
         if (address == null) {
@@ -200,6 +213,7 @@
      *
      * @param toRemove A {@link LinkAddress} specifying the address to remove.
      * @return true if the address was removed, false if it did not exist.
+     * @hide
      */
     public boolean removeLinkAddress(LinkAddress toRemove) {
         int i = findLinkAddressIndex(toRemove);
@@ -214,18 +228,18 @@
      * Returns all the {@link LinkAddress} on this link.  Typically a link will have
      * one IPv4 address and one or more IPv6 addresses.
      *
-     * @return An unmodifiable {@link Collection} of {@link LinkAddress} for this link.
+     * @return An unmodifiable {@link List} of {@link LinkAddress} for this link.
      */
-    public Collection<LinkAddress> getLinkAddresses() {
-        return Collections.unmodifiableCollection(mLinkAddresses);
+    public List<LinkAddress> getLinkAddresses() {
+        return Collections.unmodifiableList(mLinkAddresses);
     }
 
     /**
      * Returns all the addresses on this link and all the links stacked above it.
      * @hide
      */
-    public Collection<LinkAddress> getAllLinkAddresses() {
-        Collection<LinkAddress> addresses = new ArrayList<LinkAddress>();
+    public List<LinkAddress> getAllLinkAddresses() {
+        List<LinkAddress> addresses = new ArrayList<LinkAddress>();
         addresses.addAll(mLinkAddresses);
         for (LinkProperties stacked: mStackedLinks.values()) {
             addresses.addAll(stacked.getAllLinkAddresses());
@@ -239,6 +253,7 @@
      *
      * @param addresses The {@link Collection} of {@link LinkAddress} to set in this
      *                  object.
+     * @hide
      */
     public void setLinkAddresses(Collection<LinkAddress> addresses) {
         mLinkAddresses.clear();
@@ -250,20 +265,21 @@
     /**
      * Adds the given {@link InetAddress} to the list of DNS servers.
      *
-     * @param dns The {@link InetAddress} to add to the list of DNS servers.
+     * @param dnsServer The {@link InetAddress} to add to the list of DNS servers.
+     * @hide
      */
-    public void addDns(InetAddress dns) {
-        if (dns != null) mDnses.add(dns);
+    public void addDnsServer(InetAddress dnsServer) {
+        if (dnsServer != null) mDnses.add(dnsServer);
     }
 
     /**
-     * Returns all the {@link LinkAddress} for DNS servers on this link.
+     * Returns all the {@link InetAddress} for DNS servers on this link.
      *
-     * @return An umodifiable {@link Collection} of {@link InetAddress} for DNS servers on
+     * @return An umodifiable {@link List} of {@link InetAddress} for DNS servers on
      *         this link.
      */
-    public Collection<InetAddress> getDnses() {
-        return Collections.unmodifiableCollection(mDnses);
+    public List<InetAddress> getDnsServers() {
+        return Collections.unmodifiableList(mDnses);
     }
 
     /**
@@ -271,6 +287,7 @@
      *
      * @param domains A {@link String} listing in priority order the comma separated
      *                domains to search when resolving host names on this link.
+     * @hide
      */
     public void setDomains(String domains) {
         mDomains = domains;
@@ -323,6 +340,7 @@
      * proper course is to add either un-named or properly named {@link RouteInfo}.
      *
      * @param route A {@link RouteInfo} to add to this object.
+     * @hide
      */
     public void addRoute(RouteInfo route) {
         if (route != null) {
@@ -339,18 +357,18 @@
     /**
      * Returns all the {@link RouteInfo} set on this link.
      *
-     * @return An unmodifiable {@link Collection} of {@link RouteInfo} for this link.
+     * @return An unmodifiable {@link List} of {@link RouteInfo} for this link.
      */
-    public Collection<RouteInfo> getRoutes() {
-        return Collections.unmodifiableCollection(mRoutes);
+    public List<RouteInfo> getRoutes() {
+        return Collections.unmodifiableList(mRoutes);
     }
 
     /**
      * Returns all the routes on this link and all the links stacked above it.
      * @hide
      */
-    public Collection<RouteInfo> getAllRoutes() {
-        Collection<RouteInfo> routes = new ArrayList();
+    public List<RouteInfo> getAllRoutes() {
+        List<RouteInfo> routes = new ArrayList();
         routes.addAll(mRoutes);
         for (LinkProperties stacked: mStackedLinks.values()) {
             routes.addAll(stacked.getAllRoutes());
@@ -364,6 +382,7 @@
      * not enforce it and applications may ignore them.
      *
      * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
+     * @hide
      */
     public void setHttpProxy(ProxyInfo proxy) {
         mHttpProxy = proxy;
@@ -419,16 +438,17 @@
      * Returns all the links stacked on top of this link.
      * @hide
      */
-    public Collection<LinkProperties> getStackedLinks() {
-        Collection<LinkProperties> stacked = new ArrayList<LinkProperties>();
+    public List<LinkProperties> getStackedLinks() {
+        List<LinkProperties> stacked = new ArrayList<LinkProperties>();
         for (LinkProperties link : mStackedLinks.values()) {
           stacked.add(new LinkProperties(link));
         }
-        return Collections.unmodifiableCollection(stacked);
+        return Collections.unmodifiableList(stacked);
     }
 
     /**
      * Clears this object to its initial state.
+     * @hide
      */
     public void clear() {
         mIfaceName = null;
@@ -443,7 +463,6 @@
 
     /**
      * Implement the Parcelable interface
-     * @hide
      */
     public int describeContents() {
         return 0;
@@ -463,12 +482,12 @@
 
         String domainName = "Domains: " + mDomains;
 
-        String mtu = "MTU: " + mMtu;
+        String mtu = " MTU: " + mMtu;
 
         String routes = " Routes: [";
         for (RouteInfo route : mRoutes) routes += route.toString() + ",";
         routes += "] ";
-        String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " ");
+        String proxy = (mHttpProxy == null ? "" : " HttpProxy: " + mHttpProxy.toString() + " ");
 
         String stacked = "";
         if (mStackedLinks.values().size() > 0) {
@@ -486,6 +505,7 @@
      * Returns true if this link has an IPv4 address.
      *
      * @return {@code true} if there is an IPv4 address, {@code false} otherwise.
+     * @hide
      */
     public boolean hasIPv4Address() {
         for (LinkAddress address : mLinkAddresses) {
@@ -500,6 +520,7 @@
      * Returns true if this link has an IPv6 address.
      *
      * @return {@code true} if there is an IPv6 address, {@code false} otherwise.
+     * @hide
      */
     public boolean hasIPv6Address() {
         for (LinkAddress address : mLinkAddresses) {
@@ -543,7 +564,7 @@
      * @hide
      */
     public boolean isIdenticalDnses(LinkProperties target) {
-        Collection<InetAddress> targetDnses = target.getDnses();
+        Collection<InetAddress> targetDnses = target.getDnsServers();
         String targetDomains = target.getDomains();
         if (mDomains == null) {
             if (targetDomains != null) return false;
@@ -696,7 +717,7 @@
         result.removed = new ArrayList<InetAddress>(mDnses);
         result.added.clear();
         if (target != null) {
-            for (InetAddress newAddress : target.getDnses()) {
+            for (InetAddress newAddress : target.getDnsServers()) {
                 if (! result.removed.remove(newAddress)) {
                     result.added.add(newAddress);
                 }
@@ -831,7 +852,7 @@
                 addressCount = in.readInt();
                 for (int i=0; i<addressCount; i++) {
                     try {
-                        netProp.addDns(InetAddress.getByAddress(in.createByteArray()));
+                        netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray()));
                     } catch (UnknownHostException e) { }
                 }
                 netProp.setDomains(in.readString());
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 35274f1..fe96287 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -44,6 +44,9 @@
     private static final String TAG = "NetworkCapabilities";
     private static final boolean DBG = false;
 
+    /**
+     * @hide
+     */
     public NetworkCapabilities() {
     }
 
@@ -154,58 +157,64 @@
      * Multiple capabilities may be applied sequentially.  Note that when searching
      * for a network to satisfy a request, all capabilities requested must be satisfied.
      *
-     * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
+     * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
+     * @return This NetworkCapability to facilitate chaining.
+     * @hide
      */
-    public void addNetworkCapability(int networkCapability) {
-        if (networkCapability < MIN_NET_CAPABILITY ||
-                networkCapability > MAX_NET_CAPABILITY) {
+    public NetworkCapabilities addCapability(int capability) {
+        if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
             throw new IllegalArgumentException("NetworkCapability out of range");
         }
-        mNetworkCapabilities |= 1 << networkCapability;
+        mNetworkCapabilities |= 1 << capability;
+        return this;
     }
 
     /**
      * Removes (if found) the given capability from this {@code NetworkCapability} instance.
      *
-     * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
+     * @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
+     * @return This NetworkCapability to facilitate chaining.
+     * @hide
      */
-    public void removeNetworkCapability(int networkCapability) {
-        if (networkCapability < MIN_NET_CAPABILITY ||
-                networkCapability > MAX_NET_CAPABILITY) {
+    public NetworkCapabilities removeCapability(int capability) {
+        if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
             throw new IllegalArgumentException("NetworkCapability out of range");
         }
-        mNetworkCapabilities &= ~(1 << networkCapability);
+        mNetworkCapabilities &= ~(1 << capability);
+        return this;
     }
 
     /**
      * Gets all the capabilities set on this {@code NetworkCapability} instance.
      *
-     * @return a {@link Collection} of {@code NetworkCapabilities.NET_CAPABILITY_*} values
+     * @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values
      *         for this instance.
+     * @hide
      */
-    public Collection<Integer> getNetworkCapabilities() {
+    public int[] getCapabilities() {
         return enumerateBits(mNetworkCapabilities);
     }
 
     /**
      * Tests for the presence of a capabilitity on this instance.
      *
-     * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
+     * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
      * @return {@code true} if set on this instance.
      */
-    public boolean hasCapability(int networkCapability) {
-        if (networkCapability < MIN_NET_CAPABILITY ||
-                networkCapability > MAX_NET_CAPABILITY) {
+    public boolean hasCapability(int capability) {
+        if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
             return false;
         }
-        return ((mNetworkCapabilities & (1 << networkCapability)) != 0);
+        return ((mNetworkCapabilities & (1 << capability)) != 0);
     }
 
-    private Collection<Integer> enumerateBits(long val) {
-        ArrayList<Integer> result = new ArrayList<Integer>();
+    private int[] enumerateBits(long val) {
+        int size = Long.bitCount(val);
+        int[] result = new int[size];
+        int index = 0;
         int resource = 0;
         while (val > 0) {
-            if ((val & 1) == 1) result.add(resource);
+            if ((val & 1) == 1) result[index++] = resource;
             val = val >> 1;
             resource++;
         }
@@ -265,33 +274,40 @@
      * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
      *
      * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added.
+     * @return This NetworkCapability to facilitate chaining.
+     * @hide
      */
-    public void addTransportType(int transportType) {
+    public NetworkCapabilities addTransportType(int transportType) {
         if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
             throw new IllegalArgumentException("TransportType out of range");
         }
         mTransportTypes |= 1 << transportType;
+        return this;
     }
 
     /**
      * Removes (if found) the given transport from this {@code NetworkCapability} instance.
      *
      * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed.
+     * @return This NetworkCapability to facilitate chaining.
+     * @hide
      */
-    public void removeTransportType(int transportType) {
+    public NetworkCapabilities removeTransportType(int transportType) {
         if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
             throw new IllegalArgumentException("TransportType out of range");
         }
         mTransportTypes &= ~(1 << transportType);
+        return this;
     }
 
     /**
      * Gets all the transports set on this {@code NetworkCapability} instance.
      *
-     * @return a {@link Collection} of {@code NetworkCapabilities.TRANSPORT_*} values
+     * @return an array of {@code NetworkCapabilities.TRANSPORT_*} values
      *         for this instance.
+     * @hide
      */
-    public Collection<Integer> getTransportTypes() {
+    public int[] getTransportTypes() {
         return enumerateBits(mTransportTypes);
     }
 
@@ -340,6 +356,7 @@
      * fast backhauls and slow backhauls.
      *
      * @param upKbps the estimated first hop upstream (device to network) bandwidth.
+     * @hide
      */
     public void setLinkUpstreamBandwidthKbps(int upKbps) {
         mLinkUpBandwidthKbps = upKbps;
@@ -368,6 +385,7 @@
      * fast backhauls and slow backhauls.
      *
      * @param downKbps the estimated first hop downstream (network to device) bandwidth.
+     * @hide
      */
     public void setLinkDownstreamBandwidthKbps(int downKbps) {
         mLinkDownBandwidthKbps = downKbps;
@@ -464,24 +482,22 @@
         };
 
     public String toString() {
-        Collection<Integer> types = getTransportTypes();
-        String transports = (types.size() > 0 ? " Transports: " : "");
-        Iterator<Integer> i = types.iterator();
-        while (i.hasNext()) {
-            switch (i.next()) {
+        int[] types = getTransportTypes();
+        String transports = (types.length > 0 ? " Transports: " : "");
+        for (int i = 0; i < types.length;) {
+            switch (types[i]) {
                 case TRANSPORT_CELLULAR:    transports += "CELLULAR"; break;
                 case TRANSPORT_WIFI:        transports += "WIFI"; break;
                 case TRANSPORT_BLUETOOTH:   transports += "BLUETOOTH"; break;
                 case TRANSPORT_ETHERNET:    transports += "ETHERNET"; break;
             }
-            if (i.hasNext()) transports += "|";
+            if (++i < types.length) transports += "|";
         }
 
-        types = getNetworkCapabilities();
-        String capabilities = (types.size() > 0 ? " Capabilities: " : "");
-        i = types.iterator();
-        while (i.hasNext()) {
-            switch (i.next().intValue()) {
+        types = getCapabilities();
+        String capabilities = (types.length > 0 ? " Capabilities: " : "");
+        for (int i = 0; i < types.length; ) {
+            switch (types[i]) {
                 case NET_CAPABILITY_MMS:            capabilities += "MMS"; break;
                 case NET_CAPABILITY_SUPL:           capabilities += "SUPL"; break;
                 case NET_CAPABILITY_DUN:            capabilities += "DUN"; break;
@@ -497,7 +513,7 @@
                 case NET_CAPABILITY_INTERNET:       capabilities += "INTERNET"; break;
                 case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
             }
-            if (i.hasNext()) capabilities += "&";
+            if (++i < types.length) capabilities += "&";
         }
 
         String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 47377e9..7911c72 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -22,19 +22,14 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
- * Defines a request for a network, made by calling {@link ConnectivityManager#requestNetwork}
- * or {@link ConnectivityManager#listenForNetwork}.
- *
- * This token records the {@link NetworkCapabilities} used to make the request and identifies
- * the request.  It should be used to release the request via
- * {@link ConnectivityManager#releaseNetworkRequest} when the network is no longer desired.
+ * Defines a request for a network, made through {@link NetworkRequest.Builder} and used
+ * to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes
+ * via {@link ConnectivityManager#listenForNetwork}.
  */
 public class NetworkRequest implements Parcelable {
     /**
-     * The {@link NetworkCapabilities} that define this request.  This should not be modified.
-     * The networkCapabilities of the request are set when
-     * {@link ConnectivityManager#requestNetwork} is called and the value is presented here
-     * as a convenient reminder of what was requested.
+     * The {@link NetworkCapabilities} that define this request.
+     * @hide
      */
     public final NetworkCapabilities networkCapabilities;
 
@@ -71,6 +66,95 @@
         this.legacyType = that.legacyType;
     }
 
+    /**
+     * Builder used to create {@link NetworkRequest} objects.  Specify the Network features
+     * needed in terms of {@link NetworkCapabilities} features
+     */
+    public static class Builder {
+        private final NetworkCapabilities mNetworkCapabilities = new NetworkCapabilities();
+
+        /**
+         * Default constructor for Builder.
+         */
+        public Builder() {}
+
+        /**
+         * Build {@link NetworkRequest} give the current set of capabilities.
+         */
+        public NetworkRequest build() {
+            return new NetworkRequest(mNetworkCapabilities, ConnectivityManager.TYPE_NONE,
+                    ConnectivityManager.REQUEST_ID_UNSET);
+        }
+
+        /**
+         * Add the given capability requirement to this builder.  These represent
+         * the requested network's required capabilities.  Note that when searching
+         * for a network to satisfy a request, all capabilities requested must be
+         * satisfied.  See {@link NetworkCapabilities} for {@code NET_CAPABILITIY_*}
+         * definitions.
+         *
+         * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to add.
+         * @return The builder to facilitate chaining
+         *         {@code builder.addCapability(...).addCapability();}.
+         */
+        public Builder addCapability(int capability) {
+            mNetworkCapabilities.addCapability(capability);
+            return this;
+        }
+
+        /**
+         * Removes (if found) the given capability from this builder instance.
+         *
+         * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to remove.
+         * @return The builder to facilitate chaining.
+         */
+        public Builder removeCapability(int capability) {
+            mNetworkCapabilities.removeCapability(capability);
+            return this;
+        }
+
+        /**
+         * Adds the given transport requirement to this builder.  These represent
+         * the set of allowed transports for the request.  Only networks using one
+         * of these transports will satisfy the request.  If no particular transports
+         * are required, none should be specified here.  See {@link NetworkCapabilities}
+         * for {@code TRANSPORT_*} definitions.
+         *
+         * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to add.
+         * @return The builder to facilitate chaining.
+         */
+        public Builder addTransportType(int transportType) {
+            mNetworkCapabilities.addTransportType(transportType);
+            return this;
+        }
+
+        /**
+         * Removes (if found) the given transport from this builder instance.
+         *
+         * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to remove.
+         * @return The builder to facilitate chaining.
+         */
+        public Builder removeTransportType(int transportType) {
+            mNetworkCapabilities.removeTransportType(transportType);
+            return this;
+        }
+
+        /**
+         * @hide
+         */
+        public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
+            mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
+            return this;
+        }
+        /**
+         * @hide
+         */
+        public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
+            mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
+            return this;
+        }
+    }
+
     // implement the Parcelable interface
     public int describeContents() {
         return 0;
diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java
index 4973b3d..573a8f8 100644
--- a/core/java/android/net/ProxyDataTracker.java
+++ b/core/java/android/net/ProxyDataTracker.java
@@ -107,8 +107,8 @@
         mNetworkCapabilities = new NetworkCapabilities();
         mNetworkInfo.setIsAvailable(true);
         try {
-          mLinkProperties.addDns(InetAddress.getByName(DNS1));
-          mLinkProperties.addDns(InetAddress.getByName(DNS2));
+          mLinkProperties.addDnsServer(InetAddress.getByName(DNS1));
+          mLinkProperties.addDnsServer(InetAddress.getByName(DNS2));
         } catch (UnknownHostException e) {
           Log.e(TAG, "Could not add DNS address", e);
         }
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index ad8e4f7..c2b888c 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -35,10 +35,10 @@
  *
  * A route contains three pieces of information:
  * <ul>
- * <li>a destination {@link LinkAddress} for directly-connected subnets.  If this is
- *     {@code null} it indicates a default route of the address family (IPv4 or IPv6)
+ * <li>a destination {@link IpPrefix} specifying the network destinations covered by this route.
+ *     If this is {@code null} it indicates a default route of the address family (IPv4 or IPv6)
  *     implied by the gateway IP address.
- * <li>a gateway {@link InetAddress} for default routes.  If this is {@code null} it
+ * <li>a gateway {@link InetAddress} indicating the next hop to use.  If this is {@code null} it
  *     indicates a directly-connected route.
  * <li>an interface (which may be unspecified).
  * </ul>
@@ -46,9 +46,10 @@
  * destination and gateway are both specified, they must be of the same address family
  * (IPv4 or IPv6).
  */
-public class RouteInfo implements Parcelable {
+public final class RouteInfo implements Parcelable {
     /**
      * The IP destination address for this route.
+     * TODO: Make this an IpPrefix.
      */
     private final LinkAddress mDestination;
 
@@ -80,6 +81,19 @@
      * @param destination the destination prefix
      * @param gateway the IP address to route packets through
      * @param iface the interface name to send packets on
+     *
+     * TODO: Convert to use IpPrefix.
+     *
+     * @hide
+     */
+    public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) {
+        this(destination == null ? null :
+                new LinkAddress(destination.getAddress(), destination.getPrefixLength()),
+                gateway, iface);
+    }
+
+    /**
+     * @hide
      */
     public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
         if (destination == null) {
@@ -105,7 +119,7 @@
         mHasGateway = (!gateway.isAnyLocalAddress());
 
         mDestination = new LinkAddress(NetworkUtils.getNetworkPart(destination.getAddress(),
-                destination.getNetworkPrefixLength()), destination.getNetworkPrefixLength());
+                destination.getPrefixLength()), destination.getPrefixLength());
         if ((destination.getAddress() instanceof Inet4Address &&
                  (gateway instanceof Inet4Address == false)) ||
                 (destination.getAddress() instanceof Inet6Address &&
@@ -128,8 +142,17 @@
      * <p>
      * Destination and gateway may not both be null.
      *
-     * @param destination the destination address and prefix in a {@link LinkAddress}
+     * @param destination the destination address and prefix in an {@link IpPrefix}
      * @param gateway the {@link InetAddress} to route packets through
+     *
+     * @hide
+     */
+    public RouteInfo(IpPrefix destination, InetAddress gateway) {
+        this(destination, gateway, null);
+    }
+
+    /**
+     * @hide
      */
     public RouteInfo(LinkAddress destination, InetAddress gateway) {
         this(destination, gateway, null);
@@ -139,16 +162,27 @@
      * Constructs a default {@code RouteInfo} object.
      *
      * @param gateway the {@link InetAddress} to route packets through
+     *
+     * @hide
      */
     public RouteInfo(InetAddress gateway) {
-        this(null, gateway, null);
+        this((LinkAddress) null, gateway, null);
     }
 
     /**
      * Constructs a {@code RouteInfo} object representing a direct connected subnet.
      *
-     * @param destination the {@link LinkAddress} describing the address and prefix
+     * @param destination the {@link IpPrefix} describing the address and prefix
      *                    length of the subnet.
+     *
+     * @hide
+     */
+    public RouteInfo(IpPrefix destination) {
+        this(destination, null, null);
+    }
+
+    /**
+     * @hide
      */
     public RouteInfo(LinkAddress destination) {
         this(destination, null, null);
@@ -176,29 +210,37 @@
 
     private boolean isHost() {
         return (mDestination.getAddress() instanceof Inet4Address &&
-                mDestination.getNetworkPrefixLength() == 32) ||
+                mDestination.getPrefixLength() == 32) ||
                (mDestination.getAddress() instanceof Inet6Address &&
-                mDestination.getNetworkPrefixLength() == 128);
+                mDestination.getPrefixLength() == 128);
     }
 
     private boolean isDefault() {
         boolean val = false;
         if (mGateway != null) {
             if (mGateway instanceof Inet4Address) {
-                val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0);
+                val = (mDestination == null || mDestination.getPrefixLength() == 0);
             } else {
-                val = (mDestination == null || mDestination.getNetworkPrefixLength() == 0);
+                val = (mDestination == null || mDestination.getPrefixLength() == 0);
             }
         }
         return val;
     }
 
     /**
-     * Retrieves the destination address and prefix length in the form of a {@link LinkAddress}.
+     * Retrieves the destination address and prefix length in the form of an {@link IpPrefix}.
      *
-     * @return {@link LinkAddress} specifying the destination.  This is never {@code null}.
+     * @return {@link IpPrefix} specifying the destination.  This is never {@code null}.
      */
-    public LinkAddress getDestination() {
+    public IpPrefix getDestination() {
+        return new IpPrefix(mDestination.getAddress(), mDestination.getPrefixLength());
+    }
+
+    /**
+     * TODO: Convert callers to use IpPrefix and then remove.
+     * @hide
+     */
+    public LinkAddress getDestinationLinkAddress() {
         return mDestination;
     }
 
@@ -233,7 +275,8 @@
     /**
      * Indicates if this route is a host route (ie, matches only a single host address).
      *
-     * @return {@code true} if the destination has a prefix length of 32/128 for v4/v6.
+     * @return {@code true} if the destination has a prefix length of 32 or 128 for IPv4 or IPv6,
+     * respectively.
      * @hide
      */
     public boolean isHostRoute() {
@@ -263,7 +306,7 @@
 
         // match the route destination and destination with prefix length
         InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
-                mDestination.getNetworkPrefixLength());
+                mDestination.getPrefixLength());
 
         return mDestination.getAddress().equals(dstNet);
     }
@@ -285,8 +328,8 @@
         for (RouteInfo route : routes) {
             if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) {
                 if ((bestRoute != null) &&
-                        (bestRoute.mDestination.getNetworkPrefixLength() >=
-                        route.mDestination.getNetworkPrefixLength())) {
+                        (bestRoute.mDestination.getPrefixLength() >=
+                        route.mDestination.getPrefixLength())) {
                     continue;
                 }
                 if (route.matches(dest)) bestRoute = route;
@@ -295,13 +338,22 @@
         return bestRoute;
     }
 
+    /**
+     * Returns a human-readable description of this object.
+     */
     public String toString() {
         String val = "";
         if (mDestination != null) val = mDestination.toString();
-        if (mGateway != null) val += " -> " + mGateway.getHostAddress();
+        val += " ->";
+        if (mGateway != null) val += " " + mGateway.getHostAddress();
+        if (mInterface != null) val += " " + mInterface;
         return val;
     }
 
+    /**
+     * Compares this RouteInfo object against the specified object and indicates if they are equal.
+     * @return {@code true} if the objects are equal, {@code false} otherwise.
+     */
     public boolean equals(Object obj) {
         if (this == obj) return true;
 
@@ -309,11 +361,14 @@
 
         RouteInfo target = (RouteInfo) obj;
 
-        return Objects.equals(mDestination, target.getDestination()) &&
+        return Objects.equals(mDestination, target.getDestinationLinkAddress()) &&
                 Objects.equals(mGateway, target.getGateway()) &&
                 Objects.equals(mInterface, target.getInterface());
     }
 
+    /**
+     *  Returns a hashcode for this <code>RouteInfo</code> object.
+     */
     public int hashCode() {
         return (mDestination == null ? 0 : mDestination.hashCode() * 41)
                 + (mGateway == null ? 0 :mGateway.hashCode() * 47)
@@ -323,7 +378,6 @@
 
     /**
      * Implement the Parcelable interface
-     * @hide
      */
     public int describeContents() {
         return 0;
@@ -331,7 +385,6 @@
 
     /**
      * Implement the Parcelable interface
-     * @hide
      */
     public void writeToParcel(Parcel dest, int flags) {
         if (mDestination == null) {
@@ -339,7 +392,7 @@
         } else {
             dest.writeByte((byte) 1);
             dest.writeByteArray(mDestination.getAddress().getAddress());
-            dest.writeInt(mDestination.getNetworkPrefixLength());
+            dest.writeInt(mDestination.getPrefixLength());
         }
 
         if (mGateway == null) {
@@ -354,7 +407,6 @@
 
     /**
      * Implement the Parcelable interface.
-     * @hide
      */
     public static final Creator<RouteInfo> CREATOR =
         new Creator<RouteInfo>() {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bd988a6..55c66ba 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6029,6 +6029,7 @@
 
         /**
          * Battery level [1-99] at which low power mode automatically turns on.
+         * If 0, it will not automatically turn on.
          * @hide
          */
         public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level";
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index fd475cd..8bd0f4d 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -29,6 +29,7 @@
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.util.ArrayMap;
 import android.util.Log;
 
 import java.util.List;
@@ -54,7 +55,7 @@
             + "[" + getClass().getSimpleName() + "]";
 
     private INotificationListenerWrapper mWrapper = null;
-    private Ranking mRanking;
+    private RankingMap mRankingMap;
 
     private INotificationManager mNoMan;
 
@@ -75,7 +76,22 @@
      *            object as well as its identifying information (tag and id) and source
      *            (package name).
      */
-    public abstract void onNotificationPosted(StatusBarNotification sbn);
+    public void onNotificationPosted(StatusBarNotification sbn) {
+        // optional
+    }
+
+    /**
+     * Implement this method to learn about new notifications as they are posted by apps.
+     *
+     * @param sbn A data structure encapsulating the original {@link android.app.Notification}
+     *            object as well as its identifying information (tag and id) and source
+     *            (package name).
+     * @param rankingMap The current ranking map that can be used to retrieve ranking information
+     *                   for active notifications, including the newly posted one.
+     */
+    public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
+        onNotificationPosted(sbn);
+    }
 
     /**
      * Implement this method to learn when notifications are removed.
@@ -94,7 +110,33 @@
      *            and source (package name) used to post the {@link android.app.Notification} that
      *            was just removed.
      */
-    public abstract void onNotificationRemoved(StatusBarNotification sbn);
+    public void onNotificationRemoved(StatusBarNotification sbn) {
+        // optional
+    }
+
+    /**
+     * Implement this method to learn when notifications are removed.
+     * <P>
+     * This might occur because the user has dismissed the notification using system UI (or another
+     * notification listener) or because the app has withdrawn the notification.
+     * <P>
+     * NOTE: The {@link StatusBarNotification} object you receive will be "light"; that is, the
+     * result from {@link StatusBarNotification#getNotification} may be missing some heavyweight
+     * fields such as {@link android.app.Notification#contentView} and
+     * {@link android.app.Notification#largeIcon}. However, all other fields on
+     * {@link StatusBarNotification}, sufficient to match this call with a prior call to
+     * {@link #onNotificationPosted(StatusBarNotification)}, will be intact.
+     *
+     * @param sbn A data structure encapsulating at least the original information (tag and id)
+     *            and source (package name) used to post the {@link android.app.Notification} that
+     *            was just removed.
+     * @param rankingMap The current ranking map that can be used to retrieve ranking information
+     *                   for active notifications.
+     *
+     */
+    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
+        onNotificationRemoved(sbn);
+    }
 
     /**
      * Implement this method to learn about when the listener is enabled and connected to
@@ -107,10 +149,11 @@
 
     /**
      * Implement this method to be notified when the notification ranking changes.
-     * <P>
-     * Call {@link #getCurrentRanking()} to retrieve the new ranking.
+     *
+     * @param rankingMap The current ranking map that can be used to retrieve ranking information
+     *                   for active notifications.
      */
-    public void onNotificationRankingUpdate() {
+    public void onNotificationRankingUpdate(RankingMap rankingMap) {
         // optional
     }
 
@@ -241,16 +284,19 @@
      *
      * <p>
      * The returned object represents the current ranking snapshot and only
-     * applies for currently active notifications. Hence you must retrieve a
-     * new Ranking after each notification event such as
-     * {@link #onNotificationPosted(StatusBarNotification)},
-     * {@link #onNotificationRemoved(StatusBarNotification)}, etc.
+     * applies for currently active notifications.
+     * <p>
+     * Generally you should use the RankingMap that is passed with events such
+     * as {@link #onNotificationPosted(StatusBarNotification, RankingMap)},
+     * {@link #onNotificationRemoved(StatusBarNotification, RankingMap)}, and
+     * so on. This method should only be used when needing access outside of
+     * such events, for example to retrieve the RankingMap right after
+     * initialization.
      *
-     * @return A {@link NotificationListenerService.Ranking} object providing
-     *     access to ranking information
+     * @return A {@link RankingMap} object providing access to ranking information
      */
-    public Ranking getCurrentRanking() {
-        return mRanking;
+    public RankingMap getCurrentRanking() {
+        return mRankingMap;
     }
 
     @Override
@@ -313,7 +359,7 @@
             synchronized (mWrapper) {
                 applyUpdate(update);
                 try {
-                    NotificationListenerService.this.onNotificationPosted(sbn);
+                    NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap);
                 } catch (Throwable t) {
                     Log.w(TAG, "Error running onNotificationPosted", t);
                 }
@@ -326,7 +372,7 @@
             synchronized (mWrapper) {
                 applyUpdate(update);
                 try {
-                    NotificationListenerService.this.onNotificationRemoved(sbn);
+                    NotificationListenerService.this.onNotificationRemoved(sbn, mRankingMap);
                 } catch (Throwable t) {
                     Log.w(TAG, "Error running onNotificationRemoved", t);
                 }
@@ -351,7 +397,7 @@
             synchronized (mWrapper) {
                 applyUpdate(update);
                 try {
-                    NotificationListenerService.this.onNotificationRankingUpdate();
+                    NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap);
                 } catch (Throwable t) {
                     Log.w(TAG, "Error running onNotificationRankingUpdate", t);
                 }
@@ -360,7 +406,65 @@
     }
 
     private void applyUpdate(NotificationRankingUpdate update) {
-        mRanking = new Ranking(update);
+        mRankingMap = new RankingMap(update);
+    }
+
+    /**
+     * Provides access to ranking information on a currently active
+     * notification.
+     *
+     * <p>
+     * Note that this object is not updated on notification events (such as
+     * {@link #onNotificationPosted(StatusBarNotification, RankingMap)},
+     * {@link #onNotificationRemoved(StatusBarNotification)}, etc.). Make sure
+     * to retrieve a new Ranking from the current {@link RankingMap} whenever
+     * a notification event occurs.
+     */
+    public static class Ranking {
+        private final String mKey;
+        private final int mRank;
+        private final boolean mIsAmbient;
+        private final boolean mIsInterceptedByDnd;
+
+        private Ranking(String key, int rank, boolean isAmbient, boolean isInterceptedByDnd) {
+            mKey = key;
+            mRank = rank;
+            mIsAmbient = isAmbient;
+            mIsInterceptedByDnd = isInterceptedByDnd;
+        }
+
+        /**
+         * Returns the key of the notification this Ranking applies to.
+         */
+        public String getKey() {
+            return mKey;
+        }
+
+        /**
+         * Returns the rank of the notification.
+         *
+         * @return the rank of the notification, that is the 0-based index in
+         *     the list of active notifications.
+         */
+        public int getRank() {
+            return mRank;
+        }
+
+        /**
+         * Returns whether the notification is an ambient notification, that is
+         * a notification that doesn't require the user's immediate attention.
+         */
+        public boolean isAmbient() {
+            return mIsAmbient;
+        }
+
+        /**
+         * Returns whether the notification was intercepted by
+         * &quot;Do not disturb&quot;.
+         */
+        public boolean isInterceptedByDoNotDisturb() {
+            return mIsInterceptedByDnd;
+        }
     }
 
     /**
@@ -371,11 +475,14 @@
      * Note that this object represents a ranking snapshot that only applies to
      * notifications active at the time of retrieval.
      */
-    public static class Ranking implements Parcelable {
+    public static class RankingMap implements Parcelable {
         private final NotificationRankingUpdate mRankingUpdate;
+        private final ArrayMap<String, Ranking> mRankingCache;
+        private boolean mRankingCacheInitialized;
 
-        private Ranking(NotificationRankingUpdate rankingUpdate) {
+        private RankingMap(NotificationRankingUpdate rankingUpdate) {
             mRankingUpdate = rankingUpdate;
+            mRankingCache = new ArrayMap<>(rankingUpdate.getOrderedKeys().length);
         }
 
         /**
@@ -389,56 +496,37 @@
         }
 
         /**
-         * Returns the rank of the notification with the given key, that is the
-         * index of <code>key</code> in the array of keys returned by
-         * {@link #getOrderedKeys()}.
+         * Returns the Ranking for the notification with the given key.
          *
-         * @return The rank of the notification with the given key; -1 when the
-         *      given key is unknown.
+         * @return the Ranking of the notification with the given key;
+         *     <code>null</code> when the key is unknown.
          */
-        public int getRank(String key) {
-            // TODO: Optimize.
+        public Ranking getRanking(String key) {
+            synchronized (mRankingCache) {
+                if (!mRankingCacheInitialized) {
+                    initializeRankingCache();
+                    mRankingCacheInitialized = true;
+                }
+            }
+            return mRankingCache.get(key);
+        }
+
+        private void initializeRankingCache() {
             String[] orderedKeys = mRankingUpdate.getOrderedKeys();
-            for (int i = 0; i < orderedKeys.length; i++) {
-                if (orderedKeys[i].equals(key)) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-
-        /**
-         * Returns whether the notification with the given key was intercepted
-         * by &quot;Do not disturb&quot;.
-         */
-        public boolean isInterceptedByDoNotDisturb(String key) {
-            // TODO: Optimize.
-            for (String interceptedKey : mRankingUpdate.getDndInterceptedKeys()) {
-                if (interceptedKey.equals(key)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Returns whether the notification with the given key is an ambient
-         * notification, that is a notification that doesn't require the user's
-         * immediate attention.
-         */
-        public boolean isAmbient(String key) {
-            // TODO: Optimize.
             int firstAmbientIndex = mRankingUpdate.getFirstAmbientIndex();
-            if (firstAmbientIndex < 0) {
-                return false;
-            }
-            String[] orderedKeys = mRankingUpdate.getOrderedKeys();
-            for (int i = firstAmbientIndex; i < orderedKeys.length; i++) {
-                if (orderedKeys[i].equals(key)) {
-                    return true;
+            for (int i = 0; i < orderedKeys.length; i++) {
+                String key = orderedKeys[i];
+                boolean isAmbient = firstAmbientIndex > -1 && firstAmbientIndex <= i;
+                boolean isInterceptedByDnd = false;
+                // TODO: Optimize.
+                for (String s : mRankingUpdate.getDndInterceptedKeys()) {
+                    if (s.equals(key)) {
+                        isInterceptedByDnd = true;
+                        break;
+                    }
                 }
+                mRankingCache.put(key, new Ranking(key, i, isAmbient, isInterceptedByDnd));
             }
-            return false;
         }
 
         // ----------- Parcelable
@@ -453,16 +541,16 @@
             dest.writeParcelable(mRankingUpdate, flags);
         }
 
-        public static final Creator<Ranking> CREATOR = new Creator<Ranking>() {
+        public static final Creator<RankingMap> CREATOR = new Creator<RankingMap>() {
             @Override
-            public Ranking createFromParcel(Parcel source) {
+            public RankingMap createFromParcel(Parcel source) {
                 NotificationRankingUpdate rankingUpdate = source.readParcelable(null);
-                return new Ranking(rankingUpdate);
+                return new RankingMap(rankingUpdate);
             }
 
             @Override
-            public Ranking[] newArray(int size) {
-                return new Ranking[size];
+            public RankingMap[] newArray(int size) {
+                return new RankingMap[size];
             }
         };
     }
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index f440853..1d9aa05 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -440,26 +440,10 @@
     }
 
     // Documentation from interface
-    public SpannableStringBuilder replace(int start, int end,
+    public SpannableStringBuilder replace(final int start, final int end,
             CharSequence tb, int tbstart, int tbend) {
         checkRange("replace", start, end);
 
-        // Sanity check
-        if (start > end) {
-            Log.w(TAG, "Bad arguments to #replace : "
-                    + "start = " + start + ", end = " + end);
-            final int tmp = start;
-            start = end;
-            end = tmp;
-        }
-        if (tbstart > tbend) {
-            Log.w(TAG, "Bad arguments to #replace : "
-                    + "tbstart = " + tbstart + ", tbend = " + tbend);
-            final int tmp = tbstart;
-            tbstart = tbend;
-            tbend = tmp;
-        }
-
         int filtercount = mFilters.length;
         for (int i = 0; i < filtercount; i++) {
             CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end);
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 11db996..72b9d3e 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -74,7 +74,8 @@
     private boolean mProfilingEnabled;
 
     ThreadedRenderer(boolean translucent) {
-        AtlasInitializer.sInstance.init();
+        // Temporarily disabled
+        //AtlasInitializer.sInstance.init();
 
         long rootNodePtr = nCreateRootRenderNode();
         mRootNode = RenderNode.adopt(rootNodePtr);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 117fe8e..7c70ee4 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6105,7 +6105,7 @@
             // apply insets path and take things from there.
             try {
                 mPrivateFlags3 |= PFLAG3_FITTING_SYSTEM_WINDOWS;
-                return !dispatchApplyWindowInsets(new WindowInsets(insets)).hasInsets();
+                return dispatchApplyWindowInsets(new WindowInsets(insets)).isConsumed();
             } finally {
                 mPrivateFlags3 &= ~PFLAG3_FITTING_SYSTEM_WINDOWS;
             }
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 0f40ee7..eef09ae 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5574,11 +5574,11 @@
     @Override
     public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
         insets = super.dispatchApplyWindowInsets(insets);
-        if (insets.hasInsets()) {
+        if (!insets.isConsumed()) {
             final int count = getChildCount();
             for (int i = 0; i < count; i++) {
                 insets = getChildAt(i).dispatchApplyWindowInsets(insets);
-                if (!insets.hasInsets()) {
+                if (insets.isConsumed()) {
                     break;
                 }
             }
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 294f472..3a1e826 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -35,6 +35,9 @@
     private Rect mTempRect;
     private boolean mIsRound;
 
+    private boolean mSystemWindowInsetsConsumed = false;
+    private boolean mWindowDecorInsetsConsumed = false;
+
     private static final Rect EMPTY_RECT = new Rect(0, 0, 0, 0);
 
     /**
@@ -52,13 +55,17 @@
 
     /** @hide */
     public WindowInsets(Rect systemWindowInsets, boolean isRound) {
-        this(systemWindowInsets, EMPTY_RECT, isRound);
+        this(systemWindowInsets, null, isRound);
     }
 
     /** @hide */
     public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, boolean isRound) {
-        mSystemWindowInsets = systemWindowInsets;
-        mWindowDecorInsets = windowDecorInsets;
+        mSystemWindowInsetsConsumed = systemWindowInsets == null;
+        mSystemWindowInsets = mSystemWindowInsetsConsumed ? EMPTY_RECT : systemWindowInsets;
+
+        mWindowDecorInsetsConsumed = windowDecorInsets == null;
+        mWindowDecorInsets = mWindowDecorInsetsConsumed ? EMPTY_RECT : windowDecorInsets;
+
         mIsRound = isRound;
     }
 
@@ -70,12 +77,14 @@
     public WindowInsets(WindowInsets src) {
         mSystemWindowInsets = src.mSystemWindowInsets;
         mWindowDecorInsets = src.mWindowDecorInsets;
+        mSystemWindowInsetsConsumed = src.mSystemWindowInsetsConsumed;
+        mWindowDecorInsetsConsumed = src.mWindowDecorInsetsConsumed;
         mIsRound = src.mIsRound;
     }
 
     /** @hide */
     public WindowInsets(Rect systemWindowInsets) {
-        this(systemWindowInsets, EMPTY_RECT);
+        this(systemWindowInsets, null);
     }
 
     /**
@@ -238,6 +247,24 @@
     }
 
     /**
+     * Check if these insets have been fully consumed.
+     *
+     * <p>Insets are considered "consumed" if the applicable <code>consume*</code> methods
+     * have been called such that all insets have been set to zero. This affects propagation of
+     * insets through the view hierarchy; insets that have not been fully consumed will continue
+     * to propagate down to child views.</p>
+     *
+     * <p>The result of this method is equivalent to the return value of
+     * {@link View#fitSystemWindows(android.graphics.Rect)}.</p>
+     *
+     * @return true if the insets have been fully consumed.
+     * @hide Pending API
+     */
+    public boolean isConsumed() {
+        return mSystemWindowInsetsConsumed && mWindowDecorInsetsConsumed;
+    }
+
+    /**
      * Returns true if the associated window has a round shape.
      *
      * <p>A round window's left, top, right and bottom edges reach all the way to the
@@ -258,7 +285,8 @@
      */
     public WindowInsets consumeSystemWindowInsets() {
         final WindowInsets result = new WindowInsets(this);
-        result.mSystemWindowInsets = new Rect(0, 0, 0, 0);
+        result.mSystemWindowInsets = EMPTY_RECT;
+        result.mSystemWindowInsetsConsumed = true;
         return result;
     }
 
@@ -276,10 +304,12 @@
             boolean right, boolean bottom) {
         if (left || top || right || bottom) {
             final WindowInsets result = new WindowInsets(this);
-            result.mSystemWindowInsets = new Rect(left ? 0 : mSystemWindowInsets.left,
+            result.mSystemWindowInsets = new Rect(
+                    left ? 0 : mSystemWindowInsets.left,
                     top ? 0 : mSystemWindowInsets.top,
                     right ? 0 : mSystemWindowInsets.right,
                     bottom ? 0 : mSystemWindowInsets.bottom);
+            result.mSystemWindowInsetsConsumed = !hasSystemWindowInsets();
             return result;
         }
         return this;
@@ -299,6 +329,7 @@
             int right, int bottom) {
         final WindowInsets result = new WindowInsets(this);
         result.mSystemWindowInsets = new Rect(left, top, right, bottom);
+        result.mSystemWindowInsetsConsumed = !hasSystemWindowInsets();
         return result;
     }
 
@@ -308,6 +339,7 @@
     public WindowInsets consumeWindowDecorInsets() {
         final WindowInsets result = new WindowInsets(this);
         result.mWindowDecorInsets.set(0, 0, 0, 0);
+        result.mWindowDecorInsetsConsumed = true;
         return result;
     }
 
@@ -322,6 +354,7 @@
                     top ? 0 : mWindowDecorInsets.top,
                     right ? 0 : mWindowDecorInsets.right,
                     bottom ? 0 : mWindowDecorInsets.bottom);
+            result.mWindowDecorInsetsConsumed = !hasWindowDecorInsets();
             return result;
         }
         return this;
@@ -333,6 +366,7 @@
     public WindowInsets replaceWindowDecorInsets(int left, int top, int right, int bottom) {
         final WindowInsets result = new WindowInsets(this);
         result.mWindowDecorInsets = new Rect(left, top, right, bottom);
+        result.mWindowDecorInsetsConsumed = !hasWindowDecorInsets();
         return result;
     }
 
diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java
index fad6747..66f5f6c 100644
--- a/core/java/android/view/inputmethod/CursorAnchorInfo.java
+++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -186,12 +186,12 @@
     /**
      * Builder for {@link CursorAnchorInfo}. This class is not designed to be thread-safe.
      */
-    public static final class CursorAnchorInfoBuilder {
+    public static final class Builder {
         /**
          * Sets the text range of the selection. Calling this can be skipped if there is no
          * selection.
          */
-        public CursorAnchorInfoBuilder setSelectionRange(final int newStart, final int newEnd) {
+        public Builder setSelectionRange(final int newStart, final int newEnd) {
             mSelectionStart = newStart;
             mSelectionEnd = newEnd;
             return this;
@@ -205,8 +205,7 @@
          * @param index index where the composing text starts.
          * @param composingText the entire composing text.
          */
-        public CursorAnchorInfoBuilder setComposingText(final int index,
-                final CharSequence composingText) {
+        public Builder setComposingText(final int index, final CharSequence composingText) {
             mComposingTextStart = index;
             if (composingText == null) {
                 mComposingText = null;
@@ -236,9 +235,8 @@
          * that will be transformed with the transformation matrix when rendered on the screen. This
          * should be calculated or compatible with {@link Layout#getLineBottom(int)}.
          */
-        public CursorAnchorInfoBuilder setInsertionMarkerLocation(
-                final float horizontalPosition, final float lineTop, final float lineBaseline,
-                final float lineBottom){
+        public Builder setInsertionMarkerLocation(final float horizontalPosition,
+                final float lineTop, final float lineBaseline, final float lineBottom){
             mInsertionMarkerHorizontal = horizontalPosition;
             mInsertionMarkerTop = lineTop;
             mInsertionMarkerBaseline = lineBaseline;
@@ -269,9 +267,8 @@
          * @throws IllegalArgumentException If the index is a negative value, or not greater than
          * all of the previously called indices.
          */
-        public CursorAnchorInfoBuilder addCharacterRect(final int index,
-                final float leadingEdgeX, final float leadingEdgeY, final float trailingEdgeX,
-                final float trailingEdgeY) {
+        public Builder addCharacterRect(final int index, final float leadingEdgeX,
+                final float leadingEdgeY, final float trailingEdgeX, final float trailingEdgeY) {
             if (index < 0) {
                 throw new IllegalArgumentException("index must not be a negative integer.");
             }
@@ -289,7 +286,7 @@
          * @param matrix transformation matrix from local coordinates into screen coordinates. null
          * is interpreted as an identity matrix.
          */
-        public CursorAnchorInfoBuilder setMatrix(final Matrix matrix) {
+        public Builder setMatrix(final Matrix matrix) {
             mMatrix.set(matrix != null ? matrix : Matrix.IDENTITY_MATRIX);
             return this;
         }
@@ -297,7 +294,7 @@
 
         /**
          * @return {@link CursorAnchorInfo} using parameters in this
-         * {@link CursorAnchorInfoBuilder}.
+         * {@link Builder}.
          */
         public CursorAnchorInfo build() {
             return new CursorAnchorInfo(this);
@@ -323,7 +320,7 @@
         }
     }
 
-    private CursorAnchorInfo(final CursorAnchorInfoBuilder builder) {
+    private CursorAnchorInfo(final Builder builder) {
         mSelectionStart = builder.mSelectionStart;
         mSelectionEnd = builder.mSelectionEnd;
         mComposingTextStart = builder.mComposingTextStart;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 27d6b82..4467128 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -96,7 +96,6 @@
 import android.view.WindowManager;
 import android.view.inputmethod.CorrectionInfo;
 import android.view.inputmethod.CursorAnchorInfo;
-import android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.ExtractedText;
 import android.view.inputmethod.ExtractedTextRequest;
@@ -3013,7 +3012,7 @@
      * {@link InputMethodManager#isWatchingCursor(View)} returns false.
      */
     private final class CursorAnchorInfoNotifier implements TextViewPositionListener {
-        final CursorAnchorInfoBuilder mSelectionInfoBuilder = new CursorAnchorInfoBuilder();
+        final CursorAnchorInfo.Builder mSelectionInfoBuilder = new CursorAnchorInfo.Builder();
         final int[] mTmpIntOffset = new int[2];
         final Matrix mViewToScreenMatrix = new Matrix();
 
@@ -3037,7 +3036,7 @@
                 return;
             }
 
-            final CursorAnchorInfoBuilder builder = mSelectionInfoBuilder;
+            final CursorAnchorInfo.Builder builder = mSelectionInfoBuilder;
             builder.reset();
 
             final int selectionStart = mTextView.getSelectionStart();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 43c8dde..84202eb 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5842,7 +5842,6 @@
                 int end = text.partialEndOffset;
                 if (end > N) end = N;
                 removeParcelableSpans(content, start, end);
-                // If start > end, content.replace will swap them before using them.
                 content.replace(start, end, text.text);
             }
         }
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index cbd9a6a..4f1cd68 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -146,6 +146,8 @@
     private ActionMenuPresenter mOuterActionMenuPresenter;
     private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
 
+    private boolean mCollapsible;
+
     public Toolbar(Context context) {
         this(context, null);
     }
@@ -969,6 +971,23 @@
         return child.getMeasuredWidth() + hMargins;
     }
 
+    /**
+     * Returns true if the Toolbar is collapsible and has no child views with a measured size > 0.
+     */
+    private boolean shouldCollapse() {
+        if (!mCollapsible) return false;
+
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = getChildAt(i);
+            if (shouldLayout(child) && child.getMeasuredWidth() > 0 &&
+                    child.getMeasuredHeight() > 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int width = 0;
@@ -1093,7 +1112,8 @@
         final int measuredHeight = resolveSizeAndState(
                 Math.max(height, getSuggestedMinimumHeight()),
                 heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT);
-        setMeasuredDimension(measuredWidth, measuredHeight);
+
+        setMeasuredDimension(measuredWidth, shouldCollapse() ? 0 : measuredHeight);
     }
 
     @Override
@@ -1490,6 +1510,16 @@
     }
 
     /**
+     * Force the toolbar to collapse to zero-height during measurement if
+     * it could be considered "empty" (no visible elements with nonzero measured size)
+     * @hide
+     */
+    public void setCollapsible(boolean collapsible) {
+        mCollapsible = collapsible;
+        requestLayout();
+    }
+
+    /**
      * Interface responsible for receiving menu item click events if the items themselves
      * do not have individual item click listeners.
      */
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
index b298d85..bed0b88 100644
--- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -424,7 +424,7 @@
 
     @Override
     public void setCollapsible(boolean collapsible) {
-        // Ignore
+        mToolbar.setCollapsible(collapsible);
     }
 
     @Override
@@ -569,7 +569,7 @@
 
     @Override
     public void setNavigationIcon(int resId) {
-        setNavigationIcon(mToolbar.getContext().getDrawable(resId));
+        setNavigationIcon(resId != 0 ? mToolbar.getContext().getDrawable(resId) : null);
     }
 
     @Override
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 8e56eec..432a615 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -828,13 +828,12 @@
                 : layout(layout), canvas(canvas), x(x), y(y), paint(paint), glyphs(glyphs),
                     pos(pos) { }
 
-        void operator()(SkTypeface* t, size_t start, size_t end) {
+        void operator()(size_t start, size_t end) {
             for (size_t i = start; i < end; i++) {
                 glyphs[i] = layout.getGlyphId(i);
                 pos[i].fX = x + layout.getX(i);
                 pos[i].fY = y + layout.getY(i);
             }
-            paint->setTypeface(t);
             canvas->drawPosText(glyphs + start, (end - start) << 1, pos + start, *paint);
         }
     private:
@@ -857,7 +856,7 @@
         paint->setTextAlign(SkPaint::kLeft_Align);
         paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
         DrawTextFunctor f(layout, canvas, x, y, paint, glyphs, pos);
-        MinikinUtils::forFontRun(layout, f);
+        MinikinUtils::forFontRun(layout, paint, f);
         doDrawTextDecorations(canvas, x, y, layout.getAdvance(), paint);
         paint->setTextAlign(align);
         delete[] glyphs;
diff --git a/core/jni/android/graphics/MinikinSkia.cpp b/core/jni/android/graphics/MinikinSkia.cpp
index 2b96f1b..25eb941 100644
--- a/core/jni/android/graphics/MinikinSkia.cpp
+++ b/core/jni/android/graphics/MinikinSkia.cpp
@@ -43,13 +43,14 @@
     return !!glyph;
 }
 
-static void MinikinFontSkia_SetSkiaPaint(SkTypeface* typeface, SkPaint* skPaint, const MinikinPaint& paint) {
-    skPaint->setTypeface(typeface);
+static void MinikinFontSkia_SetSkiaPaint(const MinikinFont* font, SkPaint* skPaint, const MinikinPaint& paint) {
     skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
     skPaint->setTextSize(paint.size);
     skPaint->setTextScaleX(paint.scaleX);
     skPaint->setTextSkewX(paint.skewX);
     MinikinFontSkia::unpackPaintFlags(skPaint, paint.paintFlags);
+    // Apply font fakery on top of user-supplied flags.
+    MinikinFontSkia::populateSkPaint(skPaint, font, paint.fakery);
 }
 
 float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
@@ -57,7 +58,7 @@
     SkPaint skPaint;
     uint16_t glyph16 = glyph_id;
     SkScalar skWidth;
-    MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
+    MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint);
     skPaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, NULL);
 #ifdef VERBOSE
     ALOGD("width for typeface %d glyph %d = %f", mTypeface->uniqueID(), glyph_id, skWidth);
@@ -70,7 +71,7 @@
     SkPaint skPaint;
     uint16_t glyph16 = glyph_id;
     SkRect skBounds;
-    MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
+    MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint);
     skPaint.getTextWidths(&glyph16, sizeof(glyph16), NULL, &skBounds);
     bounds->mLeft = skBounds.fLeft;
     bounds->mTop = skBounds.fTop;
@@ -90,7 +91,7 @@
     }
 }
 
-SkTypeface *MinikinFontSkia::GetSkTypeface() {
+SkTypeface *MinikinFontSkia::GetSkTypeface() const {
     return mTypeface;
 }
 
@@ -115,4 +116,12 @@
     paint->setHinting(static_cast<SkPaint::Hinting>(paintFlags >> 16));
 }
 
+void MinikinFontSkia::populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery) {
+    paint->setTypeface(reinterpret_cast<const MinikinFontSkia*>(font)->GetSkTypeface());
+    paint->setFakeBoldText(paint->isFakeBoldText() || fakery.isFakeBold());
+    if (fakery.isFakeItalic()) {
+        paint->setTextSkewX(paint->getTextSkewX() - 0.25f);
+    }
+}
+
 }
diff --git a/core/jni/android/graphics/MinikinSkia.h b/core/jni/android/graphics/MinikinSkia.h
index 0452c57..ac4d2a0 100644
--- a/core/jni/android/graphics/MinikinSkia.h
+++ b/core/jni/android/graphics/MinikinSkia.h
@@ -36,10 +36,13 @@
 
     int32_t GetUniqueId() const;
 
-    SkTypeface *GetSkTypeface();
+    SkTypeface* GetSkTypeface() const;
 
     static uint32_t packPaintFlags(const SkPaint* paint);
     static void unpackPaintFlags(SkPaint* paint, uint32_t paintFlags);
+
+    // set typeface and fake bold/italic parameters
+    static void populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery);
 private:
     SkTypeface *mTypeface;
 };
diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h
index ea7eb5d..a96c6b1 100644
--- a/core/jni/android/graphics/MinikinUtils.h
+++ b/core/jni/android/graphics/MinikinUtils.h
@@ -36,23 +36,30 @@
 
     static float xOffsetForTextAlign(SkPaint* paint, const Layout& layout);
 
-    // f is a functor of type void f(SkTypeface *, size_t start, size_t end);
+    // f is a functor of type void f(size_t start, size_t end);
     template <typename F>
-    static void forFontRun(const Layout& layout, F& f) {
-        SkTypeface* lastFace = NULL;
+    static void forFontRun(const Layout& layout, SkPaint* paint, F& f) {
+        float saveSkewX = paint->getTextSkewX();
+        bool savefakeBold = paint->isFakeBoldText();
+        MinikinFont* curFont = NULL;
         size_t start = 0;
         size_t nGlyphs = layout.nGlyphs();
         for (size_t i = 0; i < nGlyphs; i++) {
-            MinikinFontSkia* mfs = static_cast<MinikinFontSkia*>(layout.getFont(i));
-            SkTypeface* skFace = mfs->GetSkTypeface();
-            if (i > 0 && skFace != lastFace) {
-                f(lastFace, start, i);
+            MinikinFont* nextFont = layout.getFont(i);
+            if (i > 0 && nextFont != curFont) {
+                MinikinFontSkia::populateSkPaint(paint, curFont, layout.getFakery(start));
+                f(start, i);
+                paint->setTextSkewX(saveSkewX);
+                paint->setFakeBoldText(savefakeBold);
                 start = i;
             }
-            lastFace = skFace;
+            curFont = nextFont;
         }
         if (nGlyphs > start) {
-            f(lastFace, start, nGlyphs);
+            MinikinFontSkia::populateSkPaint(paint, curFont, layout.getFakery(start));
+            f(start, nGlyphs);
+            paint->setTextSkewX(saveSkewX);
+            paint->setFakeBoldText(savefakeBold);
         }
     }
 };
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 3dc874e..8b11d31 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -429,27 +429,29 @@
         GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(skewX);
     }
 
-    static jfloat ascent(JNIEnv* env, jobject paint) {
-        NPE_CHECK_RETURN_ZERO(env, paint);
-        SkPaint::FontMetrics    metrics;
-        (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
-        return SkScalarToFloat(metrics.fAscent);
-    }
-
-    static jfloat descent(JNIEnv* env, jobject paint) {
-        NPE_CHECK_RETURN_ZERO(env, paint);
-        SkPaint::FontMetrics    metrics;
-        (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
-        return SkScalarToFloat(metrics.fDescent);
-    }
-
-    static SkScalar getMetricsInternal(SkPaint *paint, SkPaint::FontMetrics *metrics) {
+    static SkScalar getMetricsInternal(JNIEnv* env, jobject jpaint, SkPaint::FontMetrics *metrics) {
         const int kElegantTop = 2500;
         const int kElegantBottom = -1000;
-        const int kElegantAscent = 1946;
-        const int kElegantDescent = -512;
+        const int kElegantAscent = 1900;
+        const int kElegantDescent = -500;
         const int kElegantLeading = 0;
+        SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
+#ifdef USE_MINIKIN
+        TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
+        typeface = TypefaceImpl_resolveDefault(typeface);
+        FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle);
+        float saveSkewX = paint->getTextSkewX();
+        bool savefakeBold = paint->isFakeBoldText();
+        MinikinFontSkia::populateSkPaint(paint, baseFont.font, baseFont.fakery);
+#endif
         SkScalar spacing = paint->getFontMetrics(metrics);
+#ifdef USE_MINIKIN
+        // The populateSkPaint call may have changed fake bold / text skew
+        // because we want to measure with those effects applied, so now
+        // restore the original settings.
+        paint->setTextSkewX(saveSkewX);
+        paint->setFakeBoldText(savefakeBold);
+#endif
         SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
         if (paintOpts.getFontVariant() == SkPaintOptionsAndroid::kElegant_Variant) {
             SkScalar size = paint->getTextSize();
@@ -463,10 +465,24 @@
         return spacing;
     }
 
+    static jfloat ascent(JNIEnv* env, jobject paint) {
+        NPE_CHECK_RETURN_ZERO(env, paint);
+        SkPaint::FontMetrics metrics;
+        getMetricsInternal(env, paint, &metrics);
+        return SkScalarToFloat(metrics.fAscent);
+    }
+
+    static jfloat descent(JNIEnv* env, jobject paint) {
+        NPE_CHECK_RETURN_ZERO(env, paint);
+        SkPaint::FontMetrics metrics;
+        getMetricsInternal(env, paint, &metrics);
+        return SkScalarToFloat(metrics.fDescent);
+    }
+
     static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         SkPaint::FontMetrics metrics;
-        SkScalar spacing = getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
+        SkScalar spacing = getMetricsInternal(env, paint, &metrics);
 
         if (metricsObj) {
             SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class));
@@ -483,7 +499,7 @@
         NPE_CHECK_RETURN_ZERO(env, paint);
         SkPaint::FontMetrics metrics;
 
-        getMetricsInternal(GraphicsJNI::getNativePaint(env, paint), &metrics);
+        getMetricsInternal(env, paint, &metrics);
         int ascent = SkScalarRoundToInt(metrics.fAscent);
         int descent = SkScalarRoundToInt(metrics.fDescent);
         int leading = SkScalarRoundToInt(metrics.fLeading);
@@ -830,13 +846,12 @@
                 : layout(layout), path(path), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) {
         }
 
-        void operator()(SkTypeface* t, size_t start, size_t end) {
+        void operator()(size_t start, size_t end) {
             for (size_t i = start; i < end; i++) {
                 glyphs[i] = layout.getGlyphId(i);
                 pos[i].fX = x + layout.getX(i);
                 pos[i].fY = y + layout.getY(i);
             }
-            paint->setTypeface(t);
             if (start == 0) {
                 paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, path);
             } else {
@@ -871,7 +886,7 @@
         paint->setTextAlign(SkPaint::kLeft_Align);
         paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
         GetTextFunctor f(layout, path, x, y, paint, glyphs, pos);
-        MinikinUtils::forFontRun(layout, f);
+        MinikinUtils::forFontRun(layout, paint, f);
         paint->setTextAlign(align);
         delete[] glyphs;
         delete[] pos;
diff --git a/core/jni/android/graphics/TypefaceImpl.cpp b/core/jni/android/graphics/TypefaceImpl.cpp
index 27df7cf..1800d0c 100644
--- a/core/jni/android/graphics/TypefaceImpl.cpp
+++ b/core/jni/android/graphics/TypefaceImpl.cpp
@@ -173,7 +173,7 @@
     } else {
         const FontStyle defaultStyle;
         FontFamily* firstFamily = reinterpret_cast<FontFamily*>(families[0]);
-        MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle);
+        MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle).font;
         SkTypeface* skTypeface = reinterpret_cast<MinikinFontSkia*>(mf)->GetSkTypeface();
         // TODO: probably better to query more precise style from family, will be important
         // when we open up API to access 100..900 weights
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index a46ccd6..d032cb6 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -656,13 +656,12 @@
                 uirenderer::Rect& bounds)
             : layout(layout), renderer(renderer), x(x), y(y), paint(paint), glyphs(glyphs),
             pos(pos), totalAdvance(totalAdvance), bounds(bounds) { }
-    void operator()(SkTypeface* t, size_t start, size_t end) {
+    void operator()(size_t start, size_t end) {
         for (size_t i = start; i < end; i++) {
             glyphs[i] = layout.getGlyphId(i);
             pos[2 * i] = layout.getX(i);
             pos[2 * i + 1] = layout.getY(i);
         }
-        paint->setTypeface(t);
         size_t glyphsCount = end - start;
         int bytesCount = glyphsCount * sizeof(jchar);
         renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount,
@@ -692,7 +691,7 @@
     float totalAdvance = layout->getAdvance();
 
     RenderTextFunctor f(*layout, renderer, x, y, paint, glyphs, pos, totalAdvance, bounds);
-    MinikinUtils::forFontRun(*layout, f);
+    MinikinUtils::forFontRun(*layout, paint, f);
     delete[] glyphs;
     delete[] pos;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8768779..c5fd83d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2688,7 +2688,8 @@
                 android:theme="@style/Theme.Holo.Dialog.Alert"
                 android:finishOnCloseSystemDialogs="true"
                 android:excludeFromRecents="true"
-                android:multiprocess="true">
+                android:multiprocess="true"
+                android:documentLaunchMode="never">
             <intent-filter>
                 <action android:name="android.intent.action.CHOOSER" />
                 <category android:name="android.intent.category.DEFAULT" />
diff --git a/core/res/res/drawable-hdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-hdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..0c3c3b4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-mdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..8322ae3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-xhdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..e6c0047
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_background_mtrl_mult.9.png b/core/res/res/drawable-xxhdpi/dialog_background_mtrl_mult.9.png
new file mode 100644
index 0000000..bb9debb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_background_mtrl_mult.9.png
Binary files differ
diff --git a/core/res/res/drawable/dialog_background_shadow_material.xml b/core/res/res/drawable/dialog_background_shadow_material.xml
new file mode 100644
index 0000000..0554920
--- /dev/null
+++ b/core/res/res/drawable/dialog_background_shadow_material.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/dialog_background_mtrl_mult"
+    android:tint="?attr/colorBackground"
+    android:tintMode="multiply" />
diff --git a/core/res/res/layout/dialog_custom_title_material.xml b/core/res/res/layout/dialog_custom_title_material.xml
index 1bb93eb..550b72e 100644
--- a/core/res/res/layout/dialog_custom_title_material.xml
+++ b/core/res/res/layout/dialog_custom_title_material.xml
@@ -23,6 +23,7 @@
     android:fitsSystemWindows="true">
     <FrameLayout android:id="@android:id/title_container"
         android:layout_width="match_parent"
+        android:layout_height="?android:attr/windowTitleSize"
         android:layout_weight="0"
         android:gravity="center_vertical|start"
         style="?android:attr/windowTitleBackgroundStyle" />
diff --git a/core/res/res/layout/dialog_title_material.xml b/core/res/res/layout/dialog_title_material.xml
index b92c1e7..918c8f1 100644
--- a/core/res/res/layout/dialog_title_material.xml
+++ b/core/res/res/layout/dialog_title_material.xml
@@ -22,7 +22,7 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:fitsSystemWindows="true">
-    <TextView android:id="@+id/alertTitle"
+    <TextView android:id="@+id/title"
         style="?android:attr/windowTitleStyle"
         android:singleLine="true"
         android:ellipsize="end"
diff --git a/core/res/res/layout/preference_material.xml b/core/res/res/layout/preference_material.xml
index a4fe73d..a9599139 100644
--- a/core/res/res/layout/preference_material.xml
+++ b/core/res/res/layout/preference_material.xml
@@ -31,7 +31,7 @@
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:minWidth="58dip"
-        android:gravity="left|center_vertical"
+        android:gravity="start|center_vertical"
         android:orientation="horizontal">
         <ImageView
             android:id="@+android:id/icon"
diff --git a/core/res/res/values-large/themes.xml b/core/res/res/values-large/themes.xml
deleted file mode 100644
index 8c8f86c..0000000
--- a/core/res/res/values-large/themes.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2010, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<!--
-===============================================================
-                        PLEASE READ
-===============================================================
-
-The Holo themes must not be modified in order to pass CTS.
-Many related themes and styles depend on other values defined in this file.
-If you would like to provide custom themes and styles for your device,
-please see themes_device_defaults.xml.
-
-===============================================================
-                        PLEASE READ
-===============================================================
- -->
-<resources>
-    <style name="Theme.Holo.DialogWhenLarge"
-            parent="@android:style/Theme.Holo.Dialog.FixedSize">
-        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
-    </style>
-    <style name="Theme.Holo.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.Holo.Dialog.NoActionBar.FixedSize">
-        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
-    </style>
-    <style name="Theme.Holo.Light.DialogWhenLarge"
-            parent="@android:style/Theme.Holo.Light.Dialog.FixedSize">
-    </style>
-    <style name="Theme.Holo.Light.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.Holo.Light.Dialog.NoActionBar.FixedSize">
-    </style>
-
-    <style name="Theme.Material.DialogWhenLarge"
-            parent="@android:style/Theme.Material.Dialog.FixedSize">
-        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
-    </style>
-    <style name="Theme.Material.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.Material.Dialog.NoActionBar.FixedSize">
-        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
-    </style>
-    <style name="Theme.Material.Light.DialogWhenLarge"
-            parent="@android:style/Theme.Material.Light.Dialog.FixedSize">
-    </style>
-    <style name="Theme.Material.Light.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.Material.Light.Dialog.NoActionBar.FixedSize">
-    </style>
-</resources>
diff --git a/core/res/res/values-large/themes_device_defaults.xml b/core/res/res/values-large/themes_device_defaults.xml
index d57e827..d252c27 100644
--- a/core/res/res/values-large/themes_device_defaults.xml
+++ b/core/res/res/values-large/themes_device_defaults.xml
@@ -31,18 +31,12 @@
 ===============================================================
  -->
 <resources>
-    <style name="Theme.DeviceDefault.DialogWhenLarge"
-            parent="@android:style/Theme.DeviceDefault.Dialog.FixedSize">
+    <style name="Theme.DeviceDefault.DialogWhenLarge" parent="@style/Theme.DeviceDefault.Dialog.FixedSize">
         <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
     </style>
-    <style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar.FixedSize">
+    <style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar" parent="@style/Theme.DeviceDefault.Dialog.NoActionBar.FixedSize">
         <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
     </style>
-    <style name="Theme.DeviceDefault.Light.DialogWhenLarge"
-            parent="@android:style/Theme.DeviceDefault.Light.Dialog.FixedSize">
-    </style>
-    <style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar"
-            parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar.FixedSize">
-    </style>
+    <style name="Theme.DeviceDefault.Light.DialogWhenLarge" parent="@style/Theme.DeviceDefault.Light.Dialog.FixedSize" />
+    <style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.DeviceDefault.Light.Dialog.NoActionBar.FixedSize" />
 </resources>
diff --git a/core/res/res/values-large/themes_holo.xml b/core/res/res/values-large/themes_holo.xml
new file mode 100644
index 0000000..3f03932
--- /dev/null
+++ b/core/res/res/values-large/themes_holo.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!--
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Holo themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see themes_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+ -->
+<resources>
+    <style name="Theme.Holo.DialogWhenLarge" parent="@style/Theme.Holo.Dialog.FixedSize">
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+    <style name="Theme.Holo.DialogWhenLarge.NoActionBar" parent="@style/Theme.Holo.Dialog.NoActionBar.FixedSize">
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+    <style name="Theme.Holo.Light.DialogWhenLarge" parent="@style/Theme.Holo.Light.Dialog.FixedSize" />
+    <style name="Theme.Holo.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.Holo.Light.Dialog.NoActionBar.FixedSize" />
+</resources>
diff --git a/core/res/res/values-large/themes_material.xml b/core/res/res/values-large/themes_material.xml
new file mode 100644
index 0000000..2781608
--- /dev/null
+++ b/core/res/res/values-large/themes_material.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Material themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see themes_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+ -->
+<resources>
+    <style name="Theme.Material.DialogWhenLarge" parent="@style/Theme.Material.Dialog.FixedSize">
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+    <style name="Theme.Material.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.Dialog.NoActionBar.FixedSize">
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+    <style name="Theme.Material.Light.DialogWhenLarge" parent="@style/Theme.Material.Light.Dialog.FixedSize" />
+    <style name="Theme.Material.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.Light.Dialog.NoActionBar.FixedSize" />
+</resources>
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index fdbe0a0..faa9fb7 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -89,6 +89,9 @@
     <color name="material_teal_A200">#ff18ffff</color>
     <color name="material_teal_A400">#ff00e5ff</color>
 
+    <!-- Accent color used by Settings -->
+    <color name="material_dark_teal_A400">#ff009688</color>
+
     <color name="material_green_100">#ffb7e1cd</color>
     <color name="material_green_300">#ff57bb8a</color>
     <color name="material_green_500">#ff0f9d58</color>
@@ -143,7 +146,10 @@
     <color name="material_blue_grey_600">#ff546e7a</color>
     <color name="material_blue_grey_700">#ff455a64</color>
     <color name="material_blue_grey_800">#ff37474f</color>
+    <!-- Primary color used by Settings -->
     <color name="material_blue_grey_900">#ff263238</color>
+    <!-- Primary dark color used by Settings -->
+    <color name="material_blue_grey_950">#ff21272b</color>
 
     <color name="material_brown_100">#ffd7ccc8</color>
     <color name="material_brown_300">#ffa1887f</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 59d01de..27ac6c30 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -595,10 +595,11 @@
     <integer name="config_shutdownBatteryTemperature">680</integer>
 
     <!-- Display low battery warning when battery level dips to this value -->
-    <integer name="config_lowBatteryWarningLevel">20</integer>
+    <integer name="config_lowBatteryWarningLevel">15</integer>
 
-    <!-- Close low battery warning when battery level reaches this value -->
-    <integer name="config_lowBatteryCloseWarningLevel">25</integer>
+    <!-- Close low battery warning when battery level reaches the lowBatteryWarningLevel
+         plus this -->
+    <integer name="config_lowBatteryCloseWarningBump">5</integer>
 
     <!-- Default color for notification LED. -->
     <color name="config_defaultNotificationColor">#ffffffff</color>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 94cf116..e16082f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2244,6 +2244,8 @@
   <public type="style" name="TextAppearance.Material.Widget.TextView.PopupMenu" />
   <public type="style" name="TextAppearance.Material.Widget.TextView.SpinnerItem" />
 
+  <public type="style" name="Theme.DeviceDefault.Settings" />
+
   <public type="style" name="Theme.Material" />
   <public type="style" name="Theme.Material.Dialog" />
   <public type="style" name="Theme.Material.Dialog.MinWidth" />
@@ -2257,6 +2259,7 @@
   <public type="style" name="Theme.Material.NoActionBar.Overscan" />
   <public type="style" name="Theme.Material.NoActionBar.TranslucentDecor" />
   <public type="style" name="Theme.Material.Panel" />
+  <public type="style" name="Theme.Material.Settings" />
   <public type="style" name="Theme.Material.Voice" />
   <public type="style" name="Theme.Material.Wallpaper" />
   <public type="style" name="Theme.Material.Wallpaper.NoTitleBar" />
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index a40835c..7120521 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -344,8 +344,7 @@
         <item name="android:textColor">#66000000</item>
     </style>
 
-    <style name="Widget.StatusBar.Material.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal">
-    </style>
+    <style name="Widget.StatusBar.Material.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal" />
 
     <style name="Widget.StatusBar.Material.ProgressBar.Media">
         <item name="android:progressDrawable">@drawable/notification_material_media_progress</item>
@@ -963,12 +962,17 @@
     <!-- Window title -->
     <style name="WindowTitleBackground.Material">
         <item name="background">@null</item>
+        <item name="paddingStart">16dp</item>
+        <item name="paddingEnd">16dp</item>
+        <item name="paddingTop">16dp</item>
     </style>
 
     <style name="WindowTitle.Material">
         <item name="singleLine">true</item>
         <item name="textAppearance">@style/TextAppearance.Material.WindowTitle</item>
         <item name="shadowRadius">0</item>
+        <item name="ellipsize">end</item>
+        <item name="textAlignment">viewStart</item>
     </style>
 
     <style name="DialogWindowTitle.Material">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 853df6e..d8e31ea 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1509,7 +1509,7 @@
   <java-symbol type="integer" name="config_defaultNotificationLedOn" />
   <java-symbol type="integer" name="config_deskDockKeepsScreenOn" />
   <java-symbol type="integer" name="config_lightSensorWarmupTime" />
-  <java-symbol type="integer" name="config_lowBatteryCloseWarningLevel" />
+  <java-symbol type="integer" name="config_lowBatteryCloseWarningBump" />
   <java-symbol type="integer" name="config_lowBatteryWarningLevel" />
   <java-symbol type="integer" name="config_networkPolicyDefaultWarning" />
   <java-symbol type="integer" name="config_networkTransitionTimeout" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 6b7d861..27c8754 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -555,4 +555,7 @@
 
     <style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.Material.Light.SearchBar" />
 
+    <!-- DeviceDefault theme for a window that should look like the Settings app.  -->
+    <style name="Theme.DeviceDefault.Settings" parent="Theme.Material.Settings" />
+
 </resources>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 1304d2b..a42996a 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -154,7 +154,7 @@
         <item name="windowContentOverlay">@null</item>
         <item name="windowShowWallpaper">false</item>
         <item name="windowTitleStyle">@style/WindowTitle.Material</item>
-        <item name="windowTitleSize">25dip</item>
+        <item name="windowTitleSize">@dimen/action_bar_default_height_material</item>
         <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
         <item name="windowContentTransitions">false</item>
         <item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
@@ -503,7 +503,7 @@
         <item name="windowContentOverlay">@drawable/ab_solid_shadow_material</item>
         <item name="windowShowWallpaper">false</item>
         <item name="windowTitleStyle">@style/WindowTitle.Material</item>
-        <item name="windowTitleSize">25dip</item>
+        <item name="windowTitleSize">@dimen/action_bar_default_height_material</item>
         <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
         <item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
         <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
@@ -1006,7 +1006,7 @@
     <style name="Theme.Material.Dialog">
         <item name="windowFrame">@null</item>
         <item name="windowTitleStyle">@style/DialogWindowTitle.Material</item>
-        <item name="windowBackground">@drawable/dialog_background_material</item>
+        <item name="windowBackground">@drawable/dialog_background_shadow_material</item>
         <item name="windowIsFloating">true</item>
         <item name="windowContentOverlay">@null</item>
         <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
@@ -1102,18 +1102,15 @@
     <!-- Theme for a window that will be displayed either full-screen on
          smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
-    <style name="Theme.Material.DialogWhenLarge" parent="@style/Theme.Material">
-    </style>
+    <style name="Theme.Material.DialogWhenLarge" parent="@style/Theme.Material" />
 
     <!-- Theme for a window without a title bar that will be displayed either
          full-screen on smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
-    <style name="Theme.Material.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.NoActionBar">
-    </style>
+    <style name="Theme.Material.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.NoActionBar" />
 
     <!-- Theme for a presentation window on a secondary display. -->
-    <style name="Theme.Material.Dialog.Presentation" parent="@style/Theme.Material.NoActionBar.Fullscreen">
-    </style>
+    <style name="Theme.Material.Dialog.Presentation" parent="@style/Theme.Material.NoActionBar.Fullscreen" />
 
     <!-- Light material dialog themes -->
 
@@ -1125,7 +1122,7 @@
     <style name="Theme.Material.Light.Dialog">
         <item name="windowFrame">@null</item>
         <item name="windowTitleStyle">@style/DialogWindowTitle.Material.Light</item>
-        <item name="windowBackground">?attr/colorBackground</item>
+        <item name="windowBackground">@drawable/dialog_background_shadow_material</item>
         <item name="windowIsFloating">true</item>
         <item name="windowContentOverlay">@null</item>
         <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
@@ -1189,15 +1186,12 @@
     <!-- Theme for a window that will be displayed either full-screen on
          smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
-    <style name="Theme.Material.Light.DialogWhenLarge" parent="@style/Theme.Material.Light">
-    </style>
+    <style name="Theme.Material.Light.DialogWhenLarge" parent="@style/Theme.Material.Light" />
 
     <!-- Theme for a window without an action bar that will be displayed either full-screen
          on smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
-    <style name="Theme.Material.Light.DialogWhenLarge.NoActionBar"
-            parent="@style/Theme.Material.Light.NoActionBar">
-    </style>
+    <style name="Theme.Material.Light.DialogWhenLarge.NoActionBar" parent="@style/Theme.Material.Light.NoActionBar" />
 
     <!-- Material light theme for alert dialog windows, which is used by the
          {@link android.app.AlertDialog} class.  This is basically a dialog
@@ -1219,8 +1213,7 @@
     </style>
 
     <!-- Theme for a presentation window on a secondary display. -->
-    <style name="Theme.Material.Light.Dialog.Presentation" parent="@style/Theme.Material.Light.NoActionBar.Fullscreen" >
-    </style>
+    <style name="Theme.Material.Light.Dialog.Presentation" parent="@style/Theme.Material.Light.NoActionBar.Fullscreen" />
 
     <!-- Default material (dark) for windows that want to have the user's selected
          wallpaper appear behind them.  -->
@@ -1236,4 +1229,11 @@
         <item name="windowNoTitle">true</item>
     </style>
 
+    <!-- Default theme for Settings and activities launched from Settings. -->
+    <style name="Theme.Material.Settings" parent="@style/Theme.Material.Light.DarkActionBar">
+        <item name="colorPrimary">@color/material_blue_grey_900</item>
+        <item name="colorPrimaryDark">@color/material_blue_grey_950</item>
+        <item name="colorAccent">@color/material_dark_teal_A400</item>
+    </style>
+
 </resources>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
index db125e6..116a31e 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
@@ -336,7 +336,7 @@
                     if (!InetAddress.isNumeric(dnsAddr)) {
                         throw new SAXException();
                     }
-                    mLinkProperties.addDns(InetAddress.getByName(dnsAddr));
+                    mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr));
                 } catch (UnknownHostException e) {
                     throw new SAXException();
                 }
@@ -348,7 +348,7 @@
                     if (!InetAddress.isNumeric(dnsAddr)) {
                         throw new SAXException();
                     }
-                    mLinkProperties.addDns(InetAddress.getByName(dnsAddr));
+                    mLinkProperties.addDnsServer(InetAddress.getByName(dnsAddr));
                 } catch (UnknownHostException e) {
                     throw new SAXException();
                 }
diff --git a/core/tests/coretests/src/android/net/LinkAddressTest.java b/core/tests/coretests/src/android/net/LinkAddressTest.java
index bccf556..814ecdd 100644
--- a/core/tests/coretests/src/android/net/LinkAddressTest.java
+++ b/core/tests/coretests/src/android/net/LinkAddressTest.java
@@ -56,26 +56,26 @@
         // Valid addresses work as expected.
         address = new LinkAddress(V4_ADDRESS, 25);
         assertEquals(V4_ADDRESS, address.getAddress());
-        assertEquals(25, address.getNetworkPrefixLength());
+        assertEquals(25, address.getPrefixLength());
         assertEquals(0, address.getFlags());
         assertEquals(RT_SCOPE_UNIVERSE, address.getScope());
 
         address = new LinkAddress(V6_ADDRESS, 127);
         assertEquals(V6_ADDRESS, address.getAddress());
-        assertEquals(127, address.getNetworkPrefixLength());
+        assertEquals(127, address.getPrefixLength());
         assertEquals(0, address.getFlags());
         assertEquals(RT_SCOPE_UNIVERSE, address.getScope());
 
         // Nonsensical flags/scopes or combinations thereof are acceptable.
         address = new LinkAddress(V6 + "/64", IFA_F_DEPRECATED | IFA_F_PERMANENT, RT_SCOPE_LINK);
         assertEquals(V6_ADDRESS, address.getAddress());
-        assertEquals(64, address.getNetworkPrefixLength());
+        assertEquals(64, address.getPrefixLength());
         assertEquals(IFA_F_DEPRECATED | IFA_F_PERMANENT, address.getFlags());
         assertEquals(RT_SCOPE_LINK, address.getScope());
 
         address = new LinkAddress(V4 + "/23", 123, 456);
         assertEquals(V4_ADDRESS, address.getAddress());
-        assertEquals(23, address.getNetworkPrefixLength());
+        assertEquals(23, address.getPrefixLength());
         assertEquals(123, address.getFlags());
         assertEquals(456, address.getScope());
 
@@ -94,10 +94,10 @@
         }
 
         assertEquals(NetworkUtils.numericToInetAddress("127.0.0.1"), ipv4Loopback.getAddress());
-        assertEquals(8, ipv4Loopback.getNetworkPrefixLength());
+        assertEquals(8, ipv4Loopback.getPrefixLength());
 
         assertEquals(NetworkUtils.numericToInetAddress("::1"), ipv6Loopback.getAddress());
-        assertEquals(128, ipv6Loopback.getNetworkPrefixLength());
+        assertEquals(128, ipv6Loopback.getPrefixLength());
 
         // Null addresses are rejected.
         try {
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index 553afe0..e649baa 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -88,8 +88,8 @@
             source.addLinkAddress(LINKADDRV4);
             source.addLinkAddress(LINKADDRV6);
             // set 2 dnses
-            source.addDns(DNS1);
-            source.addDns(DNS2);
+            source.addDnsServer(DNS1);
+            source.addDnsServer(DNS2);
             // set 2 gateways
             source.addRoute(new RouteInfo(GATEWAY1));
             source.addRoute(new RouteInfo(GATEWAY2));
@@ -101,8 +101,8 @@
             target.setInterfaceName(NAME);
             target.addLinkAddress(LINKADDRV4);
             target.addLinkAddress(LINKADDRV6);
-            target.addDns(DNS1);
-            target.addDns(DNS2);
+            target.addDnsServer(DNS1);
+            target.addDnsServer(DNS2);
             target.addRoute(new RouteInfo(GATEWAY1));
             target.addRoute(new RouteInfo(GATEWAY2));
             target.setMtu(MTU);
@@ -114,8 +114,8 @@
             target.setInterfaceName("qmi1");
             target.addLinkAddress(LINKADDRV4);
             target.addLinkAddress(LINKADDRV6);
-            target.addDns(DNS1);
-            target.addDns(DNS2);
+            target.addDnsServer(DNS1);
+            target.addDnsServer(DNS2);
             target.addRoute(new RouteInfo(GATEWAY1));
             target.addRoute(new RouteInfo(GATEWAY2));
             target.setMtu(MTU);
@@ -127,8 +127,8 @@
             target.addLinkAddress(new LinkAddress(
                     NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
             target.addLinkAddress(LINKADDRV6);
-            target.addDns(DNS1);
-            target.addDns(DNS2);
+            target.addDnsServer(DNS1);
+            target.addDnsServer(DNS2);
             target.addRoute(new RouteInfo(GATEWAY1));
             target.addRoute(new RouteInfo(GATEWAY2));
             target.setMtu(MTU);
@@ -139,8 +139,8 @@
             target.addLinkAddress(LINKADDRV4);
             target.addLinkAddress(LINKADDRV6);
             // change dnses
-            target.addDns(NetworkUtils.numericToInetAddress("75.208.7.2"));
-            target.addDns(DNS2);
+            target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2"));
+            target.addDnsServer(DNS2);
             target.addRoute(new RouteInfo(GATEWAY1));
             target.addRoute(new RouteInfo(GATEWAY2));
             target.setMtu(MTU);
@@ -150,8 +150,8 @@
             target.setInterfaceName(NAME);
             target.addLinkAddress(LINKADDRV4);
             target.addLinkAddress(LINKADDRV6);
-            target.addDns(DNS1);
-            target.addDns(DNS2);
+            target.addDnsServer(DNS1);
+            target.addDnsServer(DNS2);
             // change gateway
             target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
             target.addRoute(new RouteInfo(GATEWAY2));
@@ -162,8 +162,8 @@
             target.setInterfaceName(NAME);
             target.addLinkAddress(LINKADDRV4);
             target.addLinkAddress(LINKADDRV6);
-            target.addDns(DNS1);
-            target.addDns(DNS2);
+            target.addDnsServer(DNS1);
+            target.addDnsServer(DNS2);
             target.addRoute(new RouteInfo(GATEWAY1));
             target.addRoute(new RouteInfo(GATEWAY2));
             // change mtu
@@ -185,8 +185,8 @@
             source.addLinkAddress(LINKADDRV4);
             source.addLinkAddress(LINKADDRV6);
             // set 2 dnses
-            source.addDns(DNS1);
-            source.addDns(DNS2);
+            source.addDnsServer(DNS1);
+            source.addDnsServer(DNS2);
             // set 2 gateways
             source.addRoute(new RouteInfo(GATEWAY1));
             source.addRoute(new RouteInfo(GATEWAY2));
@@ -197,8 +197,8 @@
             target.setInterfaceName(NAME);
             target.addLinkAddress(LINKADDRV6);
             target.addLinkAddress(LINKADDRV4);
-            target.addDns(DNS2);
-            target.addDns(DNS1);
+            target.addDnsServer(DNS2);
+            target.addDnsServer(DNS1);
             target.addRoute(new RouteInfo(GATEWAY2));
             target.addRoute(new RouteInfo(GATEWAY1));
             target.setMtu(MTU);
diff --git a/core/tests/coretests/src/android/net/RouteInfoTest.java b/core/tests/coretests/src/android/net/RouteInfoTest.java
index 55d6592..c80d0bf 100644
--- a/core/tests/coretests/src/android/net/RouteInfoTest.java
+++ b/core/tests/coretests/src/android/net/RouteInfoTest.java
@@ -43,17 +43,17 @@
 
         // Invalid input.
         try {
-            r = new RouteInfo(null, null, "rmnet0");
+            r = new RouteInfo((LinkAddress) null, null, "rmnet0");
             fail("Expected RuntimeException:  destination and gateway null");
         } catch(RuntimeException e) {}
 
         // Null destination is default route.
-        r = new RouteInfo(null, Address("2001:db8::1"), null);
+        r = new RouteInfo((LinkAddress) null, Address("2001:db8::1"), null);
         assertEquals(Prefix("::/0"), r.getDestination());
         assertEquals(Address("2001:db8::1"), r.getGateway());
         assertNull(r.getInterface());
 
-        r = new RouteInfo(null, Address("192.0.2.1"), "wlan0");
+        r = new RouteInfo((LinkAddress) null, Address("192.0.2.1"), "wlan0");
         assertEquals(Prefix("0.0.0.0/0"), r.getDestination());
         assertEquals(Address("192.0.2.1"), r.getGateway());
         assertEquals("wlan0", r.getInterface());
@@ -71,17 +71,19 @@
     }
 
     public void testMatches() {
-        class PatchedRouteInfo extends RouteInfo {
+        class PatchedRouteInfo {
+            private final RouteInfo mRouteInfo;
+
             public PatchedRouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
-                super(destination, gateway, iface);
+                mRouteInfo = new RouteInfo(destination, gateway, iface);
             }
 
             public boolean matches(InetAddress destination) {
-                return super.matches(destination);
+                return mRouteInfo.matches(destination);
             }
         }
 
-        RouteInfo r;
+        PatchedRouteInfo r;
 
         r = new PatchedRouteInfo(Prefix("2001:db8:f00::ace:d00d/127"), null, "rmnet0");
         assertTrue(r.matches(Address("2001:db8:f00::ace:d00c")));
@@ -96,11 +98,11 @@
         assertFalse(r.matches(Address("192.0.0.21")));
         assertFalse(r.matches(Address("8.8.8.8")));
 
-        RouteInfo ipv6Default = new PatchedRouteInfo(Prefix("::/0"), null, "rmnet0");
+        PatchedRouteInfo ipv6Default = new PatchedRouteInfo(Prefix("::/0"), null, "rmnet0");
         assertTrue(ipv6Default.matches(Address("2001:db8::f00")));
         assertFalse(ipv6Default.matches(Address("192.0.2.1")));
 
-        RouteInfo ipv4Default = new PatchedRouteInfo(Prefix("0.0.0.0/0"), null, "rmnet0");
+        PatchedRouteInfo ipv4Default = new PatchedRouteInfo(Prefix("0.0.0.0/0"), null, "rmnet0");
         assertTrue(ipv4Default.matches(Address("255.255.255.255")));
         assertTrue(ipv4Default.matches(Address("192.0.2.1")));
         assertFalse(ipv4Default.matches(Address("2001:db8::f00")));
diff --git a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
index 7d72f3e..d850c7c 100644
--- a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
+++ b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java
@@ -21,7 +21,7 @@
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.inputmethod.CursorAnchorInfo;
-import android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder;
+import android.view.inputmethod.CursorAnchorInfo.Builder;
 
 public class CursorAnchorInfoTest extends InstrumentationTestCase {
     // null represents a character that is invisible, for example because it's overlapped by some
@@ -64,7 +64,7 @@
         Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
         TRANSFORM_MATRIX.setScale(10.0f, 20.0f);
 
-        final CursorAnchorInfoBuilder builder = new CursorAnchorInfoBuilder();
+        final Builder builder = new Builder();
         builder.setSelectionRange(SELECTION_START, SELECTION_END)
                 .setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT)
                 .setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
@@ -148,7 +148,7 @@
         final Matrix MATRIX3 = new Matrix();
         MATRIX3.setTranslate(210.0f, 220.0f);
         final Matrix matrix = new Matrix();
-        final CursorAnchorInfoBuilder builder = new CursorAnchorInfoBuilder();
+        final Builder builder = new Builder();
 
         matrix.set(MATRIX1);
         builder.setMatrix(matrix);
@@ -171,7 +171,7 @@
     public void testBuilderAdd() throws Exception {
         // A negative index should be rejected.
         try {
-            new CursorAnchorInfoBuilder().addCharacterRect(-1, 0.0f, 0.0f, 0.0f, 0.0f);
+            new Builder().addCharacterRect(-1, 0.0f, 0.0f, 0.0f, 0.0f);
         } catch (IllegalArgumentException ex) {
             assertTrue(true);
         }
@@ -191,4 +191,3 @@
         }
     }
 }
-
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index c9921ba3..59e15e1 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -975,11 +975,14 @@
 // Bezier approximation
 ///////////////////////////////////////////////////////////////////////////////
 
+// Depth at which recursion is aborted
+#define ABORT_DEPTH 20
+
 void PathTessellator::recursiveCubicBezierVertices(
         float p1x, float p1y, float c1x, float c1y,
         float p2x, float p2y, float c2x, float c2y,
         float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
-        Vector<Vertex>& outputVertices) {
+        Vector<Vertex>& outputVertices, int depth) {
     float dx = p2x - p1x;
     float dy = p2y - p1y;
     float d1 = fabs((c1x - p2x) * dy - (c1y - p2y) * dx);
@@ -988,7 +991,7 @@
 
     // multiplying by sqrInvScaleY/X equivalent to multiplying in dimensional scale factors
 
-    if (d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
+    if (depth >= ABORT_DEPTH || d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
         // below thresh, draw line by adding endpoint
         pushToVector(outputVertices, p2x, p2y);
     } else {
@@ -1012,11 +1015,11 @@
         recursiveCubicBezierVertices(
                 p1x, p1y, p1c1x, p1c1y,
                 mx, my, p1c1c2x, p1c1c2y,
-                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
         recursiveCubicBezierVertices(
                 mx, my, p2c1c2x, p2c1c2y,
                 p2x, p2y, p2c2x, p2c2y,
-                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
     }
 }
 
@@ -1025,12 +1028,12 @@
         float bx, float by,
         float cx, float cy,
         float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
-        Vector<Vertex>& outputVertices) {
+        Vector<Vertex>& outputVertices, int depth) {
     float dx = bx - ax;
     float dy = by - ay;
     float d = (cx - bx) * dy - (cy - by) * dx;
 
-    if (d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
+    if (depth >= ABORT_DEPTH || d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
         // below thresh, draw line by adding endpoint
         pushToVector(outputVertices, bx, by);
     } else {
@@ -1044,9 +1047,9 @@
         float my = (acy + bcy) * 0.5f;
 
         recursiveQuadraticBezierVertices(ax, ay, mx, my, acx, acy,
-                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
         recursiveQuadraticBezierVertices(mx, my, bx, by, bcx, bcy,
-                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices, depth + 1);
     }
 }
 
diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h
index f033470..8ac9a3b 100644
--- a/libs/hwui/PathTessellator.h
+++ b/libs/hwui/PathTessellator.h
@@ -105,7 +105,7 @@
             float bx, float by,
             float cx, float cy,
             float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
-            Vector<Vertex> &outputVertices);
+            Vector<Vertex> &outputVertices, int depth = 0);
 
 /*
   endpoints p1, p2
@@ -117,7 +117,7 @@
             float p2x, float p2y,
             float c2x, float c2y,
             float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
-            Vector<Vertex> &outputVertices);
+            Vector<Vertex> &outputVertices, int depth = 0);
 };
 
 }; // namespace uirenderer
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index 41cc9d2..e6bc873 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -165,12 +165,12 @@
     ShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
             const SkPath* casterPerimeter, const Matrix4* transformXY, const Matrix4* transformZ,
             const Vector3& lightCenter, float lightRadius)
-        : drawTransform(drawTransform)
+        : drawTransform(*drawTransform)
         , localClip(localClip)
         , opaque(opaque)
-        , casterPerimeter(casterPerimeter)
-        , transformXY(transformXY)
-        , transformZ(transformZ)
+        , casterPerimeter(*casterPerimeter)
+        , transformXY(*transformXY)
+        , transformZ(*transformZ)
         , lightCenter(lightCenter)
         , lightRadius(lightRadius) {
     }
@@ -182,14 +182,19 @@
         delete bufferPair;
     }
 
-    // Note - only the localClip is deep copied, since other pointers point at Allocator controlled
-    // objects, which are safe for the entire frame
-    const Matrix4* drawTransform;
+    /* Note - we deep copy all task parameters, because *even though* pointers into Allocator
+     * controlled objects (like the SkPath and Matrix4s) should be safe for the entire frame,
+     * certain Allocators are destroyed before trim() is called to flush incomplete tasks.
+     *
+     * These deep copies could be avoided, long term, by cancelling or flushing outstanding tasks
+     * before tearning down single-frame LinearAllocators.
+     */
+    const Matrix4 drawTransform;
     const Rect localClip;
     bool opaque;
-    const SkPath* casterPerimeter;
-    const Matrix4* transformXY;
-    const Matrix4* transformZ;
+    const SkPath casterPerimeter;
+    const Matrix4 transformXY;
+    const Matrix4 transformZ;
     const Vector3 lightCenter;
     const float lightRadius;
 };
@@ -281,8 +286,8 @@
 
         VertexBuffer* ambientBuffer = new VertexBuffer;
         VertexBuffer* spotBuffer = new VertexBuffer;
-        tessellateShadows(t->drawTransform, &t->localClip, t->opaque, t->casterPerimeter,
-                t->transformXY, t->transformZ, t->lightCenter, t->lightRadius,
+        tessellateShadows(&t->drawTransform, &t->localClip, t->opaque, &t->casterPerimeter,
+                &t->transformXY, &t->transformZ, t->lightCenter, t->lightRadius,
                 *ambientBuffer, *spotBuffer);
 
         t->setResult(new TessellationCache::vertexBuffer_pair_t(ambientBuffer, spotBuffer));
@@ -345,11 +350,12 @@
 
 
 void TessellationCache::trim() {
-    uint32_t size = getSize();
-    while (size > mMaxSize) {
-        size -= mCache.peekOldestValue()->getSize();
-        mCache.removeOldest();
-    }
+    // uint32_t size = getSize();
+    // while (size > mMaxSize) {
+    //     size -= mCache.peekOldestValue()->getSize();
+    //     mCache.removeOldest();
+    // }
+    mCache.clear(); // Workaround caching tessellation corruption
     mShadowCache.clear();
 }
 
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index ce9fbb1..458139b 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2344,19 +2344,24 @@
         if (rctlr == null) {
             return false;
         }
-        IAudioService service = getService();
-        final RemoteController.OnClientUpdateListener l = rctlr.getUpdateListener();
-        final ComponentName listenerComponent = new ComponentName(mContext, l.getClass());
-        try {
-            int[] artworkDimensions = rctlr.getArtworkSize();
-            boolean reg = service.registerRemoteController(rctlr.getRcDisplay(),
-                    artworkDimensions[0]/*w*/, artworkDimensions[1]/*h*/,
-                    listenerComponent);
-            rctlr.setIsRegistered(reg);
-            return reg;
-        } catch (RemoteException e) {
-            Log.e(TAG, "Dead object in registerRemoteController " + e);
-            return false;
+        if (USE_SESSIONS) {
+            rctlr.startListeningToSessions();
+            return true;
+        } else {
+            IAudioService service = getService();
+            final RemoteController.OnClientUpdateListener l = rctlr.getUpdateListener();
+            final ComponentName listenerComponent = new ComponentName(mContext, l.getClass());
+            try {
+                int[] artworkDimensions = rctlr.getArtworkSize();
+                boolean reg = service.registerRemoteController(rctlr.getRcDisplay(),
+                        artworkDimensions[0]/* w */, artworkDimensions[1]/* h */,
+                        listenerComponent);
+                rctlr.setIsRegistered(reg);
+                return reg;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in registerRemoteController " + e);
+                return false;
+            }
         }
     }
 
@@ -2369,12 +2374,16 @@
         if (rctlr == null) {
             return;
         }
-        IAudioService service = getService();
-        try {
-            service.unregisterRemoteControlDisplay(rctlr.getRcDisplay());
-            rctlr.setIsRegistered(false);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e);
+        if (USE_SESSIONS) {
+            rctlr.stopListeningToSessions();
+        } else {
+            IAudioService service = getService();
+            try {
+                service.unregisterRemoteControlDisplay(rctlr.getRcDisplay());
+                rctlr.setIsRegistered(false);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e);
+            }
         }
     }
 
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 3711585..76c7299 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -19,11 +19,17 @@
 import android.app.ActivityManager;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.media.IRemoteControlDisplay;
 import android.media.MediaMetadataEditor;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionLegacyHelper;
+import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -34,6 +40,7 @@
 import android.view.KeyEvent;
 
 import java.lang.ref.WeakReference;
+import java.util.List;
 
 /**
  * The RemoteController class is used to control media playback, display and update media metadata
@@ -56,6 +63,7 @@
     private final static int TRANSPORT_UNKNOWN = 0;
     private final static String TAG = "RemoteController";
     private final static boolean DEBUG = false;
+    private final static boolean USE_SESSIONS = true;
     private final static Object mGenLock = new Object();
     private final static Object mInfoLock = new Object();
     private final RcDisplay mRcd;
@@ -64,6 +72,11 @@
     private final int mMaxBitmapDimension;
     private MetadataEditor mMetadataEditor;
 
+    private MediaSessionManager mSessionManager;
+    private MediaSessionManager.SessionListener mSessionListener
+            = new TopTransportSessionListener();
+    private MediaController.Callback mSessionCb = new MediaControllerCallback();
+
     /**
      * Synchronized on mGenLock
      */
@@ -79,6 +92,8 @@
     private int mArtworkWidth = -1;
     private int mArtworkHeight = -1;
     private boolean mEnabled = true;
+    // synchronized on mInfoLock, for USE_SESSION apis.
+    private MediaController mCurrentSession;
 
     /**
      * Class constructor.
@@ -123,6 +138,8 @@
         mContext = context;
         mRcd = new RcDisplay(this);
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        mSessionManager = (MediaSessionManager) context
+                .getSystemService(Context.MEDIA_SESSION_SERVICE);
 
         if (ActivityManager.isLowRamDeviceStatic()) {
             mMaxBitmapDimension = MAX_BITMAP_DIMENSION;
@@ -194,8 +211,15 @@
      * @hide
      */
     public String getRemoteControlClientPackageName() {
-        return mClientPendingIntentCurrent != null ?
-                mClientPendingIntentCurrent.getCreatorPackage() : null;
+        if (USE_SESSIONS) {
+            synchronized (mInfoLock) {
+                return mCurrentSession != null ? mCurrentSession.getSessionInfo().getPackageName()
+                        : null;
+            }
+        } else {
+            return mClientPendingIntentCurrent != null ?
+                    mClientPendingIntentCurrent.getCreatorPackage() : null;
+        }
     }
 
     /**
@@ -215,22 +239,38 @@
      * @see OnClientUpdateListener#onClientPlaybackStateUpdate(int, long, long, float)
      */
     public long getEstimatedMediaPosition() {
-        if (mLastPlaybackInfo != null) {
-            if (!RemoteControlClient.playbackPositionShouldMove(mLastPlaybackInfo.mState)) {
-                return mLastPlaybackInfo.mCurrentPosMs;
+        if (USE_SESSIONS) {
+            synchronized (mInfoLock) {
+                if (mCurrentSession != null) {
+                    PlaybackState state = mCurrentSession.getPlaybackState();
+                    if (state != null) {
+                        return state.getPosition();
+                    }
+                }
             }
-
-            // Take the current position at the time of state change and estimate.
-            final long thenPos = mLastPlaybackInfo.mCurrentPosMs;
-            if (thenPos < 0) {
-                return -1;
+        } else {
+            final PlaybackInfo lastPlaybackInfo;
+            synchronized (mInfoLock) {
+                lastPlaybackInfo = mLastPlaybackInfo;
             }
+            if (lastPlaybackInfo != null) {
+                if (!RemoteControlClient.playbackPositionShouldMove(lastPlaybackInfo.mState)) {
+                    return lastPlaybackInfo.mCurrentPosMs;
+                }
 
-            final long now = SystemClock.elapsedRealtime();
-            final long then = mLastPlaybackInfo.mStateChangeTimeMs;
-            final long sinceThen = now - then;
-            final long scaledSinceThen = (long) (sinceThen * mLastPlaybackInfo.mSpeed);
-            return thenPos + scaledSinceThen;
+                // Take the current position at the time of state change and
+                // estimate.
+                final long thenPos = lastPlaybackInfo.mCurrentPosMs;
+                if (thenPos < 0) {
+                    return -1;
+                }
+
+                final long now = SystemClock.elapsedRealtime();
+                final long then = lastPlaybackInfo.mStateChangeTimeMs;
+                final long sinceThen = now - then;
+                final long scaledSinceThen = (long) (sinceThen * lastPlaybackInfo.mSpeed);
+                return thenPos + scaledSinceThen;
+            }
         }
         return -1;
     }
@@ -267,30 +307,40 @@
         if (!KeyEvent.isMediaKey(keyEvent.getKeyCode())) {
             throw new IllegalArgumentException("not a media key event");
         }
-        final PendingIntent pi;
-        synchronized(mInfoLock) {
-            if (!mIsRegistered) {
-                Log.e(TAG, "Cannot use sendMediaKeyEvent() from an unregistered RemoteController");
-                return false;
-            }
-            if (!mEnabled) {
-                Log.e(TAG, "Cannot use sendMediaKeyEvent() from a disabled RemoteController");
-                return false;
-            }
-            pi = mClientPendingIntentCurrent;
-        }
-        if (pi != null) {
-            Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
-            intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
-            try {
-                pi.send(mContext, 0, intent);
-            } catch (CanceledException e) {
-                Log.e(TAG, "Error sending intent for media button down: ", e);
+        if (USE_SESSIONS) {
+            synchronized (mInfoLock) {
+                if (mCurrentSession != null) {
+                    return mCurrentSession.dispatchMediaButtonEvent(keyEvent);
+                }
                 return false;
             }
         } else {
-            Log.i(TAG, "No-op when sending key click, no receiver right now");
-            return false;
+            final PendingIntent pi;
+            synchronized (mInfoLock) {
+                if (!mIsRegistered) {
+                    Log.e(TAG,
+                            "Cannot use sendMediaKeyEvent() from an unregistered RemoteController");
+                    return false;
+                }
+                if (!mEnabled) {
+                    Log.e(TAG, "Cannot use sendMediaKeyEvent() from a disabled RemoteController");
+                    return false;
+                }
+                pi = mClientPendingIntentCurrent;
+            }
+            if (pi != null) {
+                Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+                intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+                try {
+                    pi.send(mContext, 0, intent);
+                } catch (CanceledException e) {
+                    Log.e(TAG, "Error sending intent for media button down: ", e);
+                    return false;
+                }
+            } else {
+                Log.i(TAG, "No-op when sending key click, no receiver right now");
+                return false;
+            }
         }
         return true;
     }
@@ -311,11 +361,19 @@
         if (timeMs < 0) {
             throw new IllegalArgumentException("illegal negative time value");
         }
-        final int genId;
-        synchronized (mGenLock) {
-            genId = mClientGenerationIdCurrent;
+        if (USE_SESSIONS) {
+            synchronized (mInfoLock) {
+                if (mCurrentSession != null) {
+                    mCurrentSession.getTransportControls().seekTo(timeMs);
+                }
+            }
+        } else {
+            final int genId;
+            synchronized (mGenLock) {
+                genId = mClientGenerationIdCurrent;
+            }
+            mAudioManager.setRemoteControlClientPlaybackPosition(genId, timeMs);
         }
-        mAudioManager.setRemoteControlClientPlaybackPosition(genId, timeMs);
         return true;
     }
 
@@ -430,7 +488,6 @@
         return editor;
     }
 
-
     /**
      * A class to read the metadata published by a {@link RemoteControlClient}, or send a
      * {@link RemoteControlClient} new values for keys that can be edited.
@@ -477,26 +534,41 @@
             if (!mMetadataChanged) {
                 return;
             }
-            final int genId;
-            synchronized(mGenLock) {
-                genId = mClientGenerationIdCurrent;
-            }
-            synchronized(mInfoLock) {
-                if (mEditorMetadata.containsKey(
-                        String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER))) {
-                    Rating rating = (Rating) getObject(
-                            MediaMetadataEditor.RATING_KEY_BY_USER, null);
-                    mAudioManager.updateRemoteControlClientMetadata(genId,
-                          MediaMetadataEditor.RATING_KEY_BY_USER,
-                          rating);
-                } else {
-                    Log.e(TAG, "no metadata to apply");
+            if (USE_SESSIONS) {
+                synchronized (mInfoLock) {
+                    if (mCurrentSession != null) {
+                        if (mEditorMetadata.containsKey(
+                                String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER))) {
+                            Rating rating = (Rating) getObject(
+                                    MediaMetadataEditor.RATING_KEY_BY_USER, null);
+                            if (rating != null) {
+                                mCurrentSession.getTransportControls().setRating(rating);
+                            }
+                        }
+                    }
                 }
-                // NOT setting mApplied to true as this type of MetadataEditor will be applied
-                // multiple times, whenever the user of a RemoteController needs to change the
-                // metadata (e.g. user changes the rating of a song more than once during playback)
-                mApplied = false;
+            } else {
+                final int genId;
+                synchronized(mGenLock) {
+                    genId = mClientGenerationIdCurrent;
+                }
+                synchronized(mInfoLock) {
+                    if (mEditorMetadata.containsKey(
+                            String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER))) {
+                        Rating rating = (Rating) getObject(
+                                MediaMetadataEditor.RATING_KEY_BY_USER, null);
+                        mAudioManager.updateRemoteControlClientMetadata(genId,
+                              MediaMetadataEditor.RATING_KEY_BY_USER,
+                              rating);
+                    } else {
+                        Log.e(TAG, "no metadata to apply");
+                    }
+                }
             }
+            // NOT setting mApplied to true as this type of MetadataEditor will be applied
+            // multiple times, whenever the user of a RemoteController needs to change the
+            // metadata (e.g. user changes the rating of a song more than once during playback)
+            mApplied = false;
         }
 
     }
@@ -649,6 +721,46 @@
         }
     }
 
+    /**
+     * This receives updates when the current session changes. This is
+     * registered to receive the updates on the handler thread so it can call
+     * directly into the appropriate methods.
+     */
+    private class MediaControllerCallback extends MediaController.Callback {
+        @Override
+        public void onPlaybackStateChanged(PlaybackState state) {
+            onNewPlaybackState(state);
+        }
+
+        @Override
+        public void onMetadataChanged(MediaMetadata metadata) {
+            onNewMediaMetadata(metadata);
+        }
+    }
+
+    /**
+     * Listens for changes to the active session stack and replaces the
+     * currently tracked session if it has changed.
+     */
+    private class TopTransportSessionListener extends MediaSessionManager.SessionListener {
+        @Override
+        public void onActiveSessionsChanged(List<MediaController> controllers) {
+            int size = controllers.size();
+            for (int i = 0; i < size; i++) {
+                MediaController controller = controllers.get(i);
+                long flags = controller.getFlags();
+                // We only care about sessions that handle transport controls,
+                // which will be true for apps using RCC
+                if ((flags & MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS) != 0) {
+                    updateController(controller);
+                    return;
+                }
+            }
+            updateController(null);
+        }
+
+    }
+
     //==================================================
     // Event handling
     private final EventHandler mEventHandler;
@@ -658,6 +770,8 @@
     private final static int MSG_NEW_METADATA       = 3; // msg always has non-null obj parameter
     private final static int MSG_CLIENT_CHANGE      = 4;
     private final static int MSG_DISPLAY_ENABLE     = 5;
+    private final static int MSG_NEW_PLAYBACK_STATE = 6;
+    private final static int MSG_NEW_MEDIA_METADATA = 7;
 
     private class EventHandler extends Handler {
 
@@ -686,12 +800,46 @@
                 case MSG_DISPLAY_ENABLE:
                     onDisplayEnable(msg.arg1 == 1);
                     break;
+                case MSG_NEW_PLAYBACK_STATE:
+                    // same as new playback info but using new apis
+                    onNewPlaybackState((PlaybackState) msg.obj);
+                    break;
+                case MSG_NEW_MEDIA_METADATA:
+                    onNewMediaMetadata((MediaMetadata) msg.obj);
+                    break;
                 default:
                     Log.e(TAG, "unknown event " + msg.what);
             }
         }
     }
 
+    /**
+     * @hide
+     */
+    void startListeningToSessions() {
+        final ComponentName listenerComponent = new ComponentName(mContext,
+                mOnClientUpdateListener.getClass());
+        mSessionManager.addActiveSessionsListener(mSessionListener, listenerComponent,
+                ActivityManager.getCurrentUser());
+        mSessionListener.onActiveSessionsChanged(mSessionManager
+                .getActiveSessions(listenerComponent));
+        if (DEBUG) {
+            Log.d(TAG, "Registered session listener with component " + listenerComponent
+                    + " for user " + ActivityManager.getCurrentUser());
+        }
+    }
+
+    /**
+     * @hide
+     */
+    void stopListeningToSessions() {
+        mSessionManager.removeActiveSessionsListener(mSessionListener);
+        if (DEBUG) {
+            Log.d(TAG, "Unregistered session listener for user "
+                    + ActivityManager.getCurrentUser());
+        }
+    }
+
     /** If the msg is already queued, replace it with this one. */
     private static final int SENDMSG_REPLACE = 0;
     /** If the msg is already queued, ignore this one and leave the old. */
@@ -713,6 +861,7 @@
         handler.sendMessageDelayed(handler.obtainMessage(msg, arg1, arg2, obj), delayMs);
     }
 
+    ///////////// These calls are used by the old APIs with RCC and RCD //////////////////////
     private void onNewPendingIntent(int genId, PendingIntent pi) {
         synchronized(mGenLock) {
             if (mClientGenerationIdCurrent != genId) {
@@ -848,6 +997,86 @@
         }
     }
 
+    ///////////// These calls are used by the new APIs with Sessions //////////////////////
+    private void updateController(MediaController controller) {
+        if (DEBUG) {
+            Log.d(TAG, "Updating controller to " + controller + " previous controller is "
+                    + mCurrentSession);
+        }
+        synchronized (mInfoLock) {
+            if (controller == null) {
+                if (mCurrentSession != null) {
+                    mCurrentSession.removeCallback(mSessionCb);
+                    mCurrentSession = null;
+                    sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
+                            0 /* genId */, 1 /* clearing */, null /* obj */, 0 /* delay */);
+                }
+            } else if (mCurrentSession == null
+                    || !controller.getSessionInfo().getId()
+                            .equals(mCurrentSession.getSessionInfo().getId())) {
+                if (mCurrentSession != null) {
+                    mCurrentSession.removeCallback(mSessionCb);
+                }
+                sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
+                        0 /* genId */, 0 /* clearing */, null /* obj */, 0 /* delay */);
+                mCurrentSession = controller;
+                mCurrentSession.addCallback(mSessionCb, mEventHandler);
+
+                PlaybackState state = controller.getPlaybackState();
+                sendMsg(mEventHandler, MSG_NEW_PLAYBACK_STATE, SENDMSG_REPLACE,
+                        0 /* genId */, 0, state /* obj */, 0 /* delay */);
+
+                MediaMetadata metadata = controller.getMetadata();
+                sendMsg(mEventHandler, MSG_NEW_MEDIA_METADATA, SENDMSG_REPLACE,
+                        0 /* arg1 */, 0 /* arg2 */, metadata /* obj */, 0 /* delay */);
+            }
+            // else same controller, no need to update
+        }
+    }
+
+    private void onNewPlaybackState(PlaybackState state) {
+        final OnClientUpdateListener l;
+        synchronized (mInfoLock) {
+            l = this.mOnClientUpdateListener;
+        }
+        if (l != null) {
+            int playstate = state == null ? RemoteControlClient.PLAYSTATE_NONE : PlaybackState
+                    .getRccStateFromState(state.getState());
+            if (state == null || state.getPosition() == PlaybackState.PLAYBACK_POSITION_UNKNOWN) {
+                l.onClientPlaybackStateUpdate(playstate);
+            } else {
+                l.onClientPlaybackStateUpdate(playstate, state.getLastPositionUpdateTime(),
+                        state.getPosition(), state.getPlaybackRate());
+            }
+            if (state != null) {
+                l.onClientTransportControlUpdate(PlaybackState.getRccControlFlagsFromActions(state
+                        .getActions()));
+            }
+        }
+    }
+
+    private void onNewMediaMetadata(MediaMetadata metadata) {
+        if (metadata == null) {
+            // RemoteController only handles non-null metadata
+            return;
+        }
+        final OnClientUpdateListener l;
+        final MetadataEditor metadataEditor;
+        // prepare the received Bundle to be used inside a MetadataEditor
+        synchronized(mInfoLock) {
+            l = mOnClientUpdateListener;
+            boolean canRate = mCurrentSession != null
+                    && mCurrentSession.getRatingType() != Rating.RATING_NONE;
+            long editableKeys = canRate ? MediaMetadataEditor.RATING_KEY_BY_USER : 0;
+            Bundle legacyMetadata = MediaSessionLegacyHelper.getOldMetadata(metadata);
+            mMetadataEditor = new MetadataEditor(legacyMetadata, editableKeys);
+            metadataEditor = mMetadataEditor;
+        }
+        if (l != null) {
+            l.onClientMetadataUpdate(metadataEditor);
+        }
+    }
+
     //==================================================
     private static class PlaybackInfo {
         int mState;
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 7c03907..f0cd785 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -37,6 +37,7 @@
     boolean isTransportControlEnabled();
     void showRoutePicker();
     MediaSessionInfo getSessionInfo();
+    long getFlags();
 
     // These commands are for the TransportController
     void play();
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 57a0a54..5ca7daa 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -57,6 +57,7 @@
     private final Object mLock = new Object();
 
     private boolean mCbRegistered = false;
+    private MediaSessionInfo mInfo;
 
     private TransportControls mTransportController;
 
@@ -174,6 +175,21 @@
     }
 
     /**
+     * Get the flags for this session.
+     *
+     * @return The current set of flags for the session.
+     * @hide
+     */
+    public long getFlags() {
+        try {
+            return mSessionBinder.getFlags();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getFlags.", e);
+        }
+        return 0;
+    }
+
+    /**
      * Adds a callback to receive updates from the Session. Updates will be
      * posted on the caller's thread.
      *
@@ -253,12 +269,14 @@
      * @hide
      */
     public MediaSessionInfo getSessionInfo() {
-        try {
-            return mSessionBinder.getSessionInfo();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error in getSessionInfo.", e);
+        if (mInfo == null) {
+            try {
+                mInfo = mSessionBinder.getSessionInfo();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error in getSessionInfo.", e);
+            }
         }
-        return null;
+        return mInfo;
     }
 
     /*
diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java
index 099f601..801844f 100644
--- a/media/java/android/media/session/MediaSessionLegacyHelper.java
+++ b/media/java/android/media/session/MediaSessionLegacyHelper.java
@@ -20,6 +20,10 @@
 import android.app.PendingIntent.CanceledException;
 import android.content.Context;
 import android.content.Intent;
+import android.media.MediaMetadata;
+import android.media.MediaMetadataEditor;
+import android.media.MediaMetadataRetriever;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.ArrayMap;
@@ -64,6 +68,88 @@
         return sInstance;
     }
 
+    public static Bundle getOldMetadata(MediaMetadata metadata) {
+        Bundle oldMetadata = new Bundle();
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUM),
+                    metadata.getString(MediaMetadata.METADATA_KEY_ALBUM));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_ART)) {
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
+                    metadata.getBitmap(MediaMetadata.METADATA_KEY_ART));
+        } else if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART)) {
+            // Fall back to album art if the track art wasn't available
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
+                    metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ARTIST)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST),
+                    metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ARTIST));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_ARTIST)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ARTIST),
+                    metadata.getString(MediaMetadata.METADATA_KEY_ARTIST));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_AUTHOR)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_AUTHOR),
+                    metadata.getString(MediaMetadata.METADATA_KEY_AUTHOR));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPILATION)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPILATION),
+                    metadata.getString(MediaMetadata.METADATA_KEY_COMPILATION));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPOSER)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPOSER),
+                    metadata.getString(MediaMetadata.METADATA_KEY_COMPOSER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_DATE)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DATE),
+                    metadata.getString(MediaMetadata.METADATA_KEY_DATE));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_DISC_NUMBER)) {
+            oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_DISC_NUMBER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
+            oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DURATION),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_DURATION));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_GENRE)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_GENRE),
+                    metadata.getString(MediaMetadata.METADATA_KEY_GENRE));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_NUM_TRACKS)) {
+            oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_NUM_TRACKS));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_RATING)) {
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_OTHERS),
+                    metadata.getRating(MediaMetadata.METADATA_KEY_RATING));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_USER_RATING)) {
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER),
+                    metadata.getRating(MediaMetadata.METADATA_KEY_USER_RATING));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_TITLE)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_TITLE),
+                    metadata.getString(MediaMetadata.METADATA_KEY_TITLE));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_TRACK_NUMBER)) {
+            oldMetadata.putLong(
+                    String.valueOf(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_WRITER)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_WRITER),
+                    metadata.getString(MediaMetadata.METADATA_KEY_WRITER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_YEAR)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_YEAR),
+                    metadata.getString(MediaMetadata.METADATA_KEY_YEAR));
+        }
+        return oldMetadata;
+    }
+
     public MediaSession getSession(PendingIntent pi) {
         SessionHolder holder = mSessions.get(pi);
         return holder == null ? null : holder.mSession;
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 291bfc8..8eceee8 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -96,10 +96,13 @@
     }
 
     /**
-     * Get a list of controllers for all ongoing sessions. This requires the
-     * android.Manifest.permission.MEDIA_CONTENT_CONTROL permission be held by
-     * the calling app. You may also retrieve this list if your app is an
-     * enabled notification listener using the
+     * Get a list of controllers for all ongoing sessions. The controllers will
+     * be provided in priority order with the most important controller at index
+     * 0.
+     * <p>
+     * This requires the android.Manifest.permission.MEDIA_CONTENT_CONTROL
+     * permission be held by the calling app. You may also retrieve this list if
+     * your app is an enabled notification listener using the
      * {@link NotificationListenerService} APIs, in which case you must pass the
      * {@link ComponentName} of your enabled listener.
      *
@@ -239,7 +242,8 @@
         /**
          * Called when the list of active sessions has changed. This can be due
          * to a session being added or removed or the order of sessions
-         * changing.
+         * changing. The controllers will be provided in priority order with the
+         * most important controller at index 0.
          *
          * @param controllers The updated list of controllers for the user that
          *            changed.
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index e09ac3f..3b3f249 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -432,6 +432,8 @@
                 return STATE_REWINDING;
             case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
                 return STATE_SKIPPING_TO_PREVIOUS;
+            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
+                return STATE_SKIPPING_TO_NEXT;
             case RemoteControlClient.PLAYSTATE_STOPPED:
                 return STATE_STOPPED;
             default:
@@ -440,6 +442,41 @@
     }
 
     /**
+     * Get the {@link RemoteControlClient} state for the given
+     * {@link PlaybackState} state.
+     *
+     * @param state The state used by {@link PlaybackState}.
+     * @return The equivalent state used by {@link RemoteControlClient}.
+     * @hide
+     */
+    public static int getRccStateFromState(int state) {
+        switch (state) {
+            case STATE_BUFFERING:
+                return RemoteControlClient.PLAYSTATE_BUFFERING;
+            case STATE_ERROR:
+                return RemoteControlClient.PLAYSTATE_ERROR;
+            case STATE_FAST_FORWARDING:
+                return RemoteControlClient.PLAYSTATE_FAST_FORWARDING;
+            case STATE_NONE:
+                return RemoteControlClient.PLAYSTATE_NONE;
+            case STATE_PAUSED:
+                return RemoteControlClient.PLAYSTATE_PAUSED;
+            case STATE_PLAYING:
+                return RemoteControlClient.PLAYSTATE_PLAYING;
+            case STATE_REWINDING:
+                return RemoteControlClient.PLAYSTATE_REWINDING;
+            case STATE_SKIPPING_TO_PREVIOUS:
+                return RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS;
+            case STATE_SKIPPING_TO_NEXT:
+                return RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS;
+            case STATE_STOPPED:
+                return RemoteControlClient.PLAYSTATE_STOPPED;
+            default:
+                return -1;
+        }
+    }
+
+    /**
      * @hide
      */
     public static long getActionsFromRccControlFlags(int rccFlags) {
@@ -454,6 +491,21 @@
         return actions;
     }
 
+    /**
+     * @hide
+     */
+    public static int getRccControlFlagsFromActions(long actions) {
+        int rccFlags = 0;
+        long action = 1;
+        while (action <= actions && action < Integer.MAX_VALUE) {
+            if ((action & actions) != 0) {
+                rccFlags |= getRccFlagForAction(action);
+            }
+            action = action << 1;
+        }
+        return rccFlags;
+    }
+
     private static long getActionForRccFlag(int flag) {
         switch (flag) {
             case RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS:
@@ -480,6 +532,35 @@
         return 0;
     }
 
+    private static int getRccFlagForAction(long action) {
+        // We only care about the lower set of actions that can map to rcc
+        // flags.
+        int testAction = action < Integer.MAX_VALUE ? (int) action : 0;
+        switch (testAction) {
+            case (int) ACTION_SKIP_TO_PREVIOUS:
+                return RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS;
+            case (int) ACTION_REWIND:
+                return RemoteControlClient.FLAG_KEY_MEDIA_REWIND;
+            case (int) ACTION_PLAY:
+                return RemoteControlClient.FLAG_KEY_MEDIA_PLAY;
+            case (int) ACTION_PLAY_PAUSE:
+                return RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE;
+            case (int) ACTION_PAUSE:
+                return RemoteControlClient.FLAG_KEY_MEDIA_PAUSE;
+            case (int) ACTION_STOP:
+                return RemoteControlClient.FLAG_KEY_MEDIA_STOP;
+            case (int) ACTION_FAST_FORWARD:
+                return RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD;
+            case (int) ACTION_SKIP_TO_NEXT:
+                return RemoteControlClient.FLAG_KEY_MEDIA_NEXT;
+            case (int) ACTION_SEEK_TO:
+                return RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE;
+            case (int) ACTION_SET_RATING:
+                return RemoteControlClient.FLAG_KEY_MEDIA_RATING;
+        }
+        return 0;
+    }
+
     public static final Parcelable.Creator<PlaybackState> CREATOR
             = new Parcelable.Creator<PlaybackState>() {
         @Override
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index 7918755..a8b49e2 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -130,6 +130,11 @@
         }
     }
 
+    @Override
+    public boolean hasOverlappingRendering() {
+        return false;
+    }
+
     private void updateOwnerInfo() {
         String ownerInfo = getOwnerInfo();
         if (!TextUtils.isEmpty(ownerInfo)) {
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
deleted file mode 100644
index e6af81e..0000000
--- a/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
index 873ca7e..fa5a0f0 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
index 9d3cf53..d88397e 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
index 288d36a..59d4695 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
index 266d34d..bbebcb1 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
index 0298054..93dc268 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
index 91e2edf..0073872 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
index 9ed15a7..0073872 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
index 6f2915b..8a3d69c 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
index 3f3b692..0afd6fe 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png
deleted file mode 100644
index 5ce8708..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
index 3f7c4b0..6ca3652 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
index 956bb7c..66f5c06 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 86e2947..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index d8ab8ea..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
index a53aef1..e49a2af 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
index e1b2145..84879b9 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index dffc059..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index c0209b0..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
index 2d8f81d..d005f61 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
index 61c6d11..dca30ab 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index a67ed6d..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 6101333..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
index 90eece6..6915a4a 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
index 382cf23..309fd4e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index ca1c8c4..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index cfef88d..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
index a4b3b37..23b570e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
index ee5f623..1c5f73f 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index ca3c541..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 78d4490..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
index 3d21350..40cf808 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
index 40fbaec..36dd2be 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 77bef31..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index d79f5b7..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
index 61b4569..3b979cd 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
index 1a0312b..e8d1dea 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index d04916e..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index d940d34..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
index 8715a11..0ab0991 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
index 487a0b1..4ced46b 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index a7cff47..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png
deleted file mode 100644
index 0a60bb6..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
deleted file mode 100644
index e865f4c..0000000
--- a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
index 225d924..891397c5 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
index 7779d57..5cf3855 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
index 37d17d2..edb5b1f 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
index 5e70a07..3212336 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
index 39a0c07..7aff620 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
index 5bbf3fe..9f66c14 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
index 798f62f..9f66c14 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
index f8e549a..972b1a8 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
index c7fda96..473b0cb 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png
deleted file mode 100644
index bdf0f67..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
index 3361e34..8ad60a5 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
index ed52bc3..17cc722 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
index b380327..6fa0d5f 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
index 49df31b..70b3ef6 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
index ac45bcd..be6a5ef 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
index 9fb4266..b26600d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
index 459d011..b26600d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
index e1cddde..f2cb7be 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
index e459f2c..170bdb6 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
index 0ec4d23..b4bea6d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
index 4dedcbe..eb0eca1 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
index e55f2bf..3d8d19b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
index a39c3e5..0f6fdad 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
index 80e988f..cbe5f77 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
index 4ef12b0d..80eb803 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
index 8ef12a8..80eb803 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
index c2977c0..a6d892f 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
index 60ec10e..7183b81 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
index 8aa6e3a..657d546 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
index e272b62..df23594 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
index bf68b22..ab27aec 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
index 59ef663..31f98e1 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
index cf3a5ff..104aed7 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
index 2598954..18e113a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
index 66853db..18e113a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
index c46fd026..079e68d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
index 0e84d92..c38b43a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
index 7e96395e..c9507af 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
index cb94580..2426776 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
index 382ef39..48fb781 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
index 8d7be53..c6fb9bf 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
index 613fba0..528df6d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
index 0511ad1..055070a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
index 77fe9b2..055070a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
index ae78eb0..e17e8f4 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
index 5b446b1..aafee03 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png
deleted file mode 100644
index 83693c1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
index a2bb50a..e3cf7a6 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
index 24897ce..7e034b8 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
index aaeeb1b..a4b3a684 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
index ddee461..321fadb 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
index 23a7997..6e3219f 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
index 9f200c2..2b6021b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
index 43e9bc2..2b6021b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
index 5c0ba82..023ca54 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
index b76a0ca..3c9dccb 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png
deleted file mode 100644
index 461535c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png
deleted file mode 100644
index cebbb15..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
old mode 100644
new mode 100755
index 79cfcee..d8f1703
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
old mode 100644
new mode 100755
index 7959f65..4e12cc9
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
old mode 100644
new mode 100755
index c3bfcfb..37951a0
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
old mode 100644
new mode 100755
index 64f6a22..7281482
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
old mode 100644
new mode 100755
index 8fd36bc..a13418c
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
old mode 100644
new mode 100755
index 6f30e54..066c2d9
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
old mode 100644
new mode 100755
index 024ef8f..a619a94
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
old mode 100644
new mode 100755
index 6e0b071..115109a
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
old mode 100644
new mode 100755
index 9a56987..3101cb0
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png
deleted file mode 100644
index 7b03a11..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_05.xml b/packages/SystemUI/res/drawable/ic_notify_zen.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/ic_qs_location_05.xml
copy to packages/SystemUI/res/drawable/ic_notify_zen.xml
index 1a21e2f..c46455b 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_05.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_zen.xml
@@ -15,14 +15,14 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android" >
     <size
-        android:width="64dp"
-        android:height="64dp"/>
+        android:width="24dp"
+        android:height="24dp"/>
 
     <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
 
     <path
         android:fill="#FFFFFFFF"
-        android:pathData="M12.0,13.0c-1.74,0.0 -3.15,1.41 -3.15,3.15C8.85,18.51 12.0,22.0 12.0,22.0s3.15,-3.49 3.15,-5.85C15.15,14.41 13.74,13.0 12.0,13.0zM12.0,17.27c-0.62,0.0 -1.13,-0.5 -1.13,-1.12c0.0,-0.62 0.5,-1.12 1.13,-1.12c0.62,0.0 1.12,0.5 1.12,1.12C13.12,16.77 12.62,17.27 12.0,17.27z"/>
+        android:pathData="M4.0,24.0c0.0,11.0 9.0,20.0 20.0,20.0s20.0,-9.0 20.0,-20.0S35.0,4.0 24.0,4.0S4.0,13.0 4.0,24.0zM36.6,33.8L14.2,11.4C16.9,9.3 20.3,8.0 24.0,8.0c8.8,0.0 16.0,7.2 16.0,16.0C40.0,27.7 38.7,31.1 36.6,33.8zM8.0,24.0c0.0,-3.7 1.3,-7.1 3.4,-9.8L33.8,36.6C31.1,38.7 27.7,40.0 24.0,40.0C15.2,40.0 8.0,32.8 8.0,24.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_01.xml b/packages/SystemUI/res/drawable/ic_power_low.xml
similarity index 66%
rename from packages/SystemUI/res/drawable/ic_qs_location_01.xml
rename to packages/SystemUI/res/drawable/ic_power_low.xml
index ff37d9a..5bb7aba 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_01.xml
+++ b/packages/SystemUI/res/drawable/ic_power_low.xml
@@ -15,14 +15,14 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android" >
     <size
-        android:width="64dp"
-        android:height="64dp"/>
+        android:width="24.0dp"
+        android:height="24.0dp"/>
 
     <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
 
     <path
         android:fill="#FFFFFFFF"
-        android:pathData="M12.0,2.0C8.13,2.0 5.0,5.13 5.0,9.0c0.0,5.25 7.0,13.0 7.0,13.0s7.0,-7.75 7.0,-13.0C19.0,5.13 15.87,2.0 12.0,2.0zM12.0,11.5c-1.38,0.0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5c1.38,0.0 2.5,1.12 2.5,2.5S13.38,11.5 12.0,11.5z"/>
+        android:pathData="M30.0,6.0L30.0,2.0L18.0,2.0l0.0,4.0l-8.0,0.0l0.0,40.0l28.0,0.0L38.0,6.0L30.0,6.0zM26.0,37.0l-4.0,0.0l0.0,-4.0l4.0,0.0L26.0,37.0zM26.0,30.0l-4.0,0.0L22.0,15.0l4.0,0.0L26.0,30.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_01.xml b/packages/SystemUI/res/drawable/ic_power_saver.xml
similarity index 66%
copy from packages/SystemUI/res/drawable/ic_qs_location_01.xml
copy to packages/SystemUI/res/drawable/ic_power_saver.xml
index ff37d9a..26e7375 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_01.xml
+++ b/packages/SystemUI/res/drawable/ic_power_saver.xml
@@ -15,14 +15,14 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android" >
     <size
-        android:width="64dp"
-        android:height="64dp"/>
+        android:width="24.0dp"
+        android:height="24.0dp"/>
 
     <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
 
     <path
         android:fill="#FFFFFFFF"
-        android:pathData="M12.0,2.0C8.13,2.0 5.0,5.13 5.0,9.0c0.0,5.25 7.0,13.0 7.0,13.0s7.0,-7.75 7.0,-13.0C19.0,5.13 15.87,2.0 12.0,2.0zM12.0,11.5c-1.38,0.0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5c1.38,0.0 2.5,1.12 2.5,2.5S13.38,11.5 12.0,11.5z"/>
+        android:pathData="M30.0,6.0L30.0,2.0L18.0,2.0l0.0,4.0l-8.0,0.0l0.0,40.0l28.0,0.0L38.0,6.0L30.0,6.0zM32.0,28.0l-6.0,0.0l0.0,6.0l-4.0,0.0l0.0,-6.0l-6.0,0.0l0.0,-4.0l6.0,0.0l0.0,-6.0l4.0,0.0l0.0,6.0l6.0,0.0L32.0,28.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_color_inversion.xml b/packages/SystemUI/res/drawable/ic_qs_color_inversion.xml
deleted file mode 100644
index dc30a53..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_color_inversion.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:fill="#FFFFFFFF"
-        android:pathData="M18.939,7.244c-5.887,-5.885 -6.214,-6.214 -6.222,-6.222l-0.707,-0.737L5.088,7.207c-2.914,2.915 -3.74,6.629 -2.266,10.19c1.541,3.719 5.312,6.316 9.174,6.317l0.0,0.0c3.861,-0.001 7.636,-2.603 9.179,-6.328C22.646,13.834 21.832,10.138 18.939,7.244zM4.67,16.632c-1.149,-2.776 -0.481,-5.696 1.832,-8.011l5.494,-5.492c0.0,0.002 0.002,0.003 0.003,0.004l0.0,18.582c-0.001,0.0 -0.002,0.0 -0.003,0.0C8.922,21.714 5.91,19.624 4.67,16.632z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
new file mode 100644
index 0000000..b6a5cad
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+    <size
+        android:width="64dp"
+        android:height="64dp"/>
+
+    <viewport
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
+
+    <path
+        android:fill="#4DFFFFFF"
+        android:pathData="M41.3,41.7L36.6,37.0L24.0,24.5l-7.1,-7.1L14.0,14.5L8.5,9.0L6.0,11.5l5.6,5.6c-5.1,6.3 -4.7,15.5 1.1,21.4c3.1,3.1 7.2,4.7 11.3,4.7c3.6,0.0 7.1,-1.2 10.1,-3.6l5.4,5.4l2.5,-2.5L41.3,41.7zM24.0,39.2c-3.2,0.0 -6.2,-1.2 -8.5,-3.5c-2.3,-2.3 -3.5,-5.3 -3.5,-8.5c0.0,-2.6 0.9,-5.1 2.4,-7.2l9.6,9.6L24.0,39.2zM24.0,10.2l0.0,9.2l14.5,14.5c2.7,-5.9 1.7,-13.1 -3.2,-18.0L24.0,4.5l0.0,0.0l0.0,0.0L16.6,12.0l2.8,2.8L24.0,10.2z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_05.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
similarity index 68%
rename from packages/SystemUI/res/drawable/ic_qs_location_05.xml
rename to packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
index 1a21e2f..e8d59e0 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_05.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
@@ -19,10 +19,10 @@
         android:height="64dp"/>
 
     <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
 
     <path
         android:fill="#FFFFFFFF"
-        android:pathData="M12.0,13.0c-1.74,0.0 -3.15,1.41 -3.15,3.15C8.85,18.51 12.0,22.0 12.0,22.0s3.15,-3.49 3.15,-5.85C15.15,14.41 13.74,13.0 12.0,13.0zM12.0,17.27c-0.62,0.0 -1.13,-0.5 -1.13,-1.12c0.0,-0.62 0.5,-1.12 1.13,-1.12c0.62,0.0 1.12,0.5 1.12,1.12C13.12,16.77 12.62,17.27 12.0,17.27z"/>
+        android:pathData="M35.3,15.9L24.0,4.5l0.0,0.0l0.0,0.0L12.7,15.9c-6.2,6.2 -6.2,16.4 0.0,22.6c3.1,3.1 7.2,4.7 11.3,4.7s8.2,-1.6 11.3,-4.7C41.6,32.2 41.6,22.1 35.3,15.9zM24.0,39.2L24.0,39.2c-3.2,0.0 -6.2,-1.2 -8.5,-3.5c-2.3,-2.3 -3.5,-5.3 -3.5,-8.5s1.2,-6.2 3.5,-8.5l8.5,-8.5L24.0,39.2z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_02.xml b/packages/SystemUI/res/drawable/ic_qs_location_02.xml
deleted file mode 100644
index bb4465f..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_02.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:fill="#FFFFFFFF"
-        android:pathData="M12.0,4.0c-3.48,0.0 -6.3,2.82 -6.3,6.3C5.7,15.02 12.0,22.0 12.0,22.0s6.3,-6.98 6.3,-11.7C18.3,6.82 15.48,4.0 12.0,4.0zM12.0,12.55c-1.24,0.0 -2.25,-1.01 -2.25,-2.25S10.76,8.05 12.0,8.05c1.24,0.0 2.25,1.01 2.25,2.25S13.24,12.55 12.0,12.55z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_03.xml b/packages/SystemUI/res/drawable/ic_qs_location_03.xml
deleted file mode 100644
index 956a8c3..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_03.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:fill="#FFFFFFFF"
-        android:pathData="M12.0,7.0c-2.9,0.0 -5.25,2.35 -5.25,5.25C6.75,16.19 12.0,22.0 12.0,22.0s5.25,-5.81 5.25,-9.75C17.25,9.35 14.9,7.0 12.0,7.0zM12.0,14.12c-1.04,0.0 -1.88,-0.84 -1.88,-1.88s0.84,-1.88 1.88,-1.88c1.04,0.0 1.87,0.84 1.87,1.88S13.04,14.12 12.0,14.12z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_04.xml b/packages/SystemUI/res/drawable/ic_qs_location_04.xml
deleted file mode 100644
index 0c0fb3b..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_04.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:fill="#FFFFFFFF"
-        android:pathData="M12.0,10.0c-2.32,0.0 -4.2,1.88 -4.2,4.2C7.8,17.35 12.0,22.0 12.0,22.0s4.2,-4.65 4.2,-7.8C16.2,11.88 14.32,10.0 12.0,10.0zM12.0,15.7c-0.83,0.0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5c0.83,0.0 1.5,0.67 1.5,1.5S12.83,15.7 12.0,15.7z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_06.xml b/packages/SystemUI/res/drawable/ic_qs_location_06.xml
deleted file mode 100644
index 5642a8a2..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_06.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:fill="#FFFFFFFF"
-        android:pathData="M12.0,16.0c-1.16,0.0 -2.1,0.94 -2.1,2.1C9.9,19.67 12.0,22.0 12.0,22.0s2.1,-2.33 2.1,-3.9C14.1,16.94 13.16,16.0 12.0,16.0zM12.0,18.85c-0.41,0.0 -0.75,-0.34 -0.75,-0.75s0.34,-0.75 0.75,-0.75c0.41,0.0 0.75,0.34 0.75,0.75S12.41,18.85 12.0,18.85z"/>
-    <path
-        android:pathData="M11.99,15c-1.35,0,-2.45,1.1,-2.45,2.45      c0,1.84,2.45,4.55,2.45,4.55s2.45,-2.71,2.45,-4.55C14.44,16.1,13.34,15,11.99,15z M11.99,18.33c-0.48,0,-0.88,-0.39,-0.88,-0.88      s0.39,-0.88,0.88,-0.88c0.48,0,0.87,0.39,0.87,0.88S12.47,18.33,11.99,18.33z"
-        android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_07.xml b/packages/SystemUI/res/drawable/ic_qs_location_07.xml
deleted file mode 100644
index 1ad2ebc..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_07.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:pathData="M12,9c-2.51,0,-4.55,2.04,-4.55,4.55       C7.45,16.96,12,22,12,22s4.55,-5.04,4.55,-8.45C16.55,11.04,14.51,9,12,9z M12,15.18c-0.9,0,-1.63,-0.73,-1.63,-1.62       s0.73,-1.62,1.63,-1.62c0.9,0,1.62,0.73,1.62,1.62S12.9,15.18,12,15.18z"
-        android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_08.xml b/packages/SystemUI/res/drawable/ic_qs_location_08.xml
deleted file mode 100644
index 179bc66..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_08.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:pathData="M12,6c-3.09,0,-5.6,2.51,-5.6,5.6       C6.4,15.8,12,22,12,22s5.6,-6.2,5.6,-10.4C17.6,8.51,15.09,6,12,6z M12,13.6c-1.1,0,-2,-0.9,-2,-2s0.9,-2,2,-2c1.1,0,2,0.9,2,2       S13.1,13.6,12,13.6z"
-        android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_09.xml b/packages/SystemUI/res/drawable/ic_qs_location_09.xml
deleted file mode 100644
index 6169af5..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_09.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:pathData="M12,4c-3.48,0,-6.3,2.82,-6.3,6.3       C5.7,15.02,12,22,12,22s6.3,-6.98,6.3,-11.7C18.3,6.82,15.48,4,12,4z M12,12.55c-1.24,0,-2.25,-1.01,-2.25,-2.25S10.76,8.05,12,8.05       c1.24,0,2.25,1.01,2.25,2.25S13.24,12.55,12,12.55z"
-        android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_10.xml b/packages/SystemUI/res/drawable/ic_qs_location_10.xml
deleted file mode 100644
index 93e2eb4..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_location_10.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android" >
-    <size
-        android:width="64dp"
-        android:height="64dp"/>
-
-    <viewport
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"/>
-
-    <path
-        android:pathData="M12,3C8.33,3,5.35,5.98,5.35,9.65       C5.35,14.64,12,22,12,22s6.65,-7.36,6.65,-12.35C18.65,5.98,15.67,3,12,3z M12,12.02c-1.31,0,-2.38,-1.06,-2.38,-2.38       S10.69,7.28,12,7.28c1.31,0,2.37,1.06,2.37,2.37S13.31,12.02,12,12.02z"
-        android:fill="#4DFFFFFF"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_off.xml b/packages/SystemUI/res/drawable/ic_qs_location_off.xml
index d28d347..26ebfbf 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_off.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_off.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
 Copyright (C) 2014 The Android Open Source Project
 
@@ -14,18 +13,19 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="true">
-    <item android:drawable="@drawable/ic_qs_location_01" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_02" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_03" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_04" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_05" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_06" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_07" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_08" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_09" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_10" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_11" android:duration="16" />
-</animation-list>
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+    <size
+        android:width="64dp"
+        android:height="64dp"/>
+
+    <viewport
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
+
+    <path
+        android:fill="#4DFFFFFF"
+        android:pathData="M24.0,13.0c2.8,0.0 5.0,2.2 5.0,5.0c0.0,1.5 -0.7,2.8 -1.7,3.7l7.3,7.3c2.0,-3.7 3.4,-7.6 3.4,-11.0c0.0,-7.7 -6.3,-14.0 -14.0,-14.0c-4.0,0.0 -7.5,1.6 -10.1,4.3l6.4,6.4C21.2,13.6 22.5,13.0 24.0,13.0zM32.7,32.2l-9.3,-9.3l-0.2,-0.2L6.5,6.0L4.0,8.5l6.4,6.4c-0.2,1.0 -0.4,2.0 -0.4,3.1c0.0,10.5 14.0,26.0 14.0,26.0s3.3,-3.7 6.8,-8.7l6.7,6.7l2.5,-2.5L32.7,32.2z"/>
+    <path
+        android:pathData="M23.5,22.9l0.0,0.0 -0.20000076,-0.19999886z"
+        android:fill="#4DFFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_on.xml b/packages/SystemUI/res/drawable/ic_qs_location_on.xml
index 72512ac..bc73005 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_location_on.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
 Copyright (C) 2014 The Android Open Source Project
 
@@ -14,18 +13,16 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="true">
-    <item android:drawable="@drawable/ic_qs_location_11" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_10" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_09" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_08" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_07" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_06" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_05" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_04" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_03" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_02" android:duration="16" />
-    <item android:drawable="@drawable/ic_qs_location_01" android:duration="16" />
-</animation-list>
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+    <size
+        android:width="64dp"
+        android:height="64dp"/>
+
+    <viewport
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0"/>
+
+    <path
+        android:fill="#FFFFFFFF"
+        android:pathData="M24.0,4.0c-7.7,0.0 -14.0,6.3 -14.0,14.0c0.0,10.5 14.0,26.0 14.0,26.0s14.0,-15.5 14.0,-26.0C38.0,10.3 31.7,4.0 24.0,4.0zM24.0,23.0c-2.8,0.0 -5.0,-2.2 -5.0,-5.0s2.2,-5.0 5.0,-5.0c2.8,0.0 5.0,2.2 5.0,5.0S26.8,23.0 24.0,23.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_11.xml b/packages/SystemUI/res/drawable/stat_sys_no_sim.xml
similarity index 71%
rename from packages/SystemUI/res/drawable/ic_qs_location_11.xml
rename to packages/SystemUI/res/drawable/stat_sys_no_sim.xml
index 09a3e63..70948b7 100644
--- a/packages/SystemUI/res/drawable/ic_qs_location_11.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_no_sim.xml
@@ -15,14 +15,14 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android" >
     <size
-        android:width="64dp"
-        android:height="64dp"/>
+        android:width="18dp"
+        android:height="18dp"/>
 
     <viewport
         android:viewportWidth="24.0"
         android:viewportHeight="24.0"/>
 
     <path
-        android:pathData="M12,2C8.13,2,5,5.13,5,9c0,5.25,7,13,7,13s7,-7.75,7,-13       C19,5.13,15.87,2,12,2z M12,11.5c-1.38,0,-2.5,-1.12,-2.5,-2.5s1.12,-2.5,2.5,-2.5c1.38,0,2.5,1.12,2.5,2.5S13.38,11.5,12,11.5z"
-        android:fill="#4DFFFFFF"/>
+        android:fill="#4DFFFFFF"
+        android:pathData="M19.0,5.0c0.0,-1.1 -0.9,-2.0 -2.0,-2.0l-7.0,0.0L7.7,5.3L19.0,16.7L19.0,5.0zM3.7,3.9L2.4,5.2L5.0,7.8L5.0,19.0c0.0,1.1 0.9,2.0 2.0,2.0l10.0,0.0c0.4,0.0 0.7,-0.1 1.0,-0.3l1.9,1.9l1.3,-1.3L3.7,3.9z"/>
 </vector>
diff --git a/packages/SystemUI/res/layout/battery_low.xml b/packages/SystemUI/res/layout/battery_low.xml
deleted file mode 100644
index 2373355..0000000
--- a/packages/SystemUI/res/layout/battery_low.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/layout/keyguard.xml
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/padding"
-    android:orientation="vertical"
-    android:gravity="center"
-    android:padding="16dp"
-    >
-
-    <TextView android:id="@+id/subtitle"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:textColor="#ffffffff"
-        android:gravity="start"
-        android:text="@string/battery_low_subtitle"
-        />
-    
-    <TextView android:id="@+id/level_percent"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="18sp"
-        android:textColor="#ffffffff"
-        android:gravity="start"
-        android:paddingBottom="16dp"
-        />
-
-    <ImageView android:id="@+id/image"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:src="@drawable/battery_low_battery"
-        />
-
-</LinearLayout>
-
-
diff --git a/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml b/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
index 84d64b9..e220a16 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_speed_bump.xml
@@ -18,48 +18,13 @@
 <com.android.systemui.statusbar.SpeedBumpView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:focusable="true"
-    android:clickable="true"
+    android:layout_height="@dimen/speed_bump_height"
     android:visibility="gone"
     >
-    <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/speed_bump_height_collapsed"
-            android:layout_gravity="top"
-            android:orientation="horizontal">
-        <com.android.systemui.statusbar.AlphaOptimizedView
-            android:id="@+id/speedbump_line_left"
-            android:layout_width="0dp"
-            android:layout_height="1dp"
-            android:layout_weight="1"
-            android:background="#6fdddddd"
-            android:layout_gravity="center_vertical"/>
-        <com.android.systemui.statusbar.SpeedBumpDotsLayout
-                android:id="@+id/speed_bump_dots_layout"
-                android:layout_width="34dp"
-                android:layout_marginStart="8dp"
-                android:layout_marginEnd="8dp"
-                android:layout_height="match_parent"
-                android:layout_weight="0"/>
-        <com.android.systemui.statusbar.AlphaOptimizedView
-            android:id="@+id/speedbump_line_right"
-            android:layout_width="0dp"
-            android:layout_height="1dp"
-            android:layout_weight="1"
-            android:background="#6fdddddd"
-            android:layout_gravity="center_vertical"/>
-    </LinearLayout>
-    <TextView
-            android:id="@+id/speed_bump_text"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="top|center_horizontal"
-            android:fontFamily="sans-serif-condensed"
-            android:textSize="15sp"
-            android:singleLine="true"
-            android:textColor="#eeeeee"
-            android:visibility="invisible"
-            android:text="@string/speed_bump_explanation"
-            android:paddingTop="4dp" />
+    <com.android.systemui.statusbar.AlphaOptimizedView
+        android:id="@+id/speedbump_line"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="#6fdddddd"
+        android:layout_gravity="center_vertical"/>
 </com.android.systemui.statusbar.SpeedBumpView>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
index 1ce4983..6628f3b 100644
--- a/packages/SystemUI/res/values/arrays.xml
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -42,13 +42,11 @@
 
     <!-- BatteryMeterView parameters -->
     <array name="batterymeter_color_levels">
-        <item>4</item>
         <item>15</item>
         <item>100</item>
     </array>
     <array name="batterymeter_color_values">
         <item>#FFFF3300</item>
-        <item>#FFFF3300</item>
         <item>#FFFFFFFF</item>
     </array>
     <array name="batterymeter_bolt_points">
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index bb6f1a9..8c1a9c7 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -45,18 +45,6 @@
     <!-- Tint color for the content on the notification overflow card. -->
     <color name="keyguard_overflow_content_color">#ff686868</color>
 
-    <!-- The color of the red speed bump dot -->
-    <color name="speed_bump_dot_red">#ffd50000</color>
-
-    <!-- The color of the blue speed bump dot -->
-    <color name="speed_bump_dot_blue">#ff2962ff</color>
-
-    <!-- The color of the yellow speed bump dot -->
-    <color name="speed_bump_dot_yellow">#ffffd600</color>
-
-    <!-- The color of the green speed bump dot -->
-    <color name="speed_bump_dot_green">#ff00c853</color>
-
     <!-- The default recents task bar background color. -->
     <color name="recents_task_bar_default_background_color">#e6444444</color>
     <!-- The default recents task bar text color. -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3f52740..836cf82 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -275,14 +275,8 @@
     <!-- The minimum amount of top overscroll to go to the quick settings. -->
     <dimen name="min_top_overscroll_to_qs">36dp</dimen>
 
-    <!-- The height of the collapsed speed bump view. -->
-    <dimen name="speed_bump_height_collapsed">24dp</dimen>
-
-    <!-- The padding inset the explanation text needs compared to the collapsed height -->
-    <dimen name="speed_bump_text_padding_inset">10dp</dimen>
-
-    <!-- The height of the speed bump dots. -->
-    <dimen name="speed_bump_dots_height">5dp</dimen>
+    <!-- The height of the speed bump view. -->
+    <dimen name="speed_bump_height">16dp</dimen>
 
     <!-- The total height of the stack in its collapsed size (i.e. when quick settings is open) -->
     <dimen name="collapsed_stack_height">94dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index de297e5..260f59c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -59,25 +59,43 @@
     <string name="status_bar_latest_events_title">Notifications</string>
 
     <!-- When the battery is low, this is displayed to the user in a dialog.  The title of the low battery alert.  [CHAR LIMIT=NONE]-->
-    <string name="battery_low_title">Connect charger</string>
-
-    <!-- When the battery is low, this is displayed to the user in a dialog. The subtitle of the low battery alert. [CHAR LIMIT=NONE] -->
-    <string name="battery_low_subtitle">The battery is getting low.</string>
+    <string name="battery_low_title">Battery is low</string>
 
     <!-- A message that appears when the battery level is getting low in a dialog.  This is
         appened to the subtitle of the low battery alert.  "number" is the percentage of battery
         remaining [CHAR LIMIT=none]-->
     <string name="battery_low_percent_format"><xliff:g id="number">%d%%</xliff:g> remaining</string>
 
+    <!-- Same as battery_low_percent_format, with a notice about battery saver if on. [CHAR LIMIT=none]-->
+    <string name="battery_low_percent_format_saver_started"><xliff:g id="number">%d%%</xliff:g> remaining. Battery saver is on.</string>
+
     <!-- A message that appears when a USB charger is plugged in and the device does not
     support charging on it.  That is, a charger that fits into the USB port and goes into
     a wall socket, not into a computer. (This happens because some devices require more
     current than the USB spec allows.  [CHAR LIMIT=NONE] -->
     <string name="invalid_charger">USB charging not supported.\nUse only the supplied charger.</string>
 
+    <!-- First line of invalid_charger, used in the notification form.  [CHAR LIMIT=NONE]-->
+    <string name="invalid_charger_title">USB charging not supported.</string>
+
+    <!-- Second line of invalid_charger, used in the notification form.  [CHAR LIMIT=NONE]-->
+    <string name="invalid_charger_text">Use only the supplied charger.</string>
+
     <!-- When the battery is low, this is the label of the button to go to the
          power usage activity to find out what drained the battery.  [CHAR LIMIT=30] -->
-    <string name="battery_low_why">Battery use</string>
+    <string name="battery_low_why">Settings</string>
+
+    <!-- Battery saver confirmation dialog title [CHAR LIMIT=NONE]-->
+    <string name="battery_saver_confirmation_title">Start battery saver?</string>
+
+    <!-- Battery saver confirmation dialog ok text [CHAR LIMIT=40]-->
+    <string name="battery_saver_confirmation_ok">Start</string>
+
+    <!-- Battery saver notification action [CHAR LIMIT=NONE]-->
+    <string name="battery_saver_start_action">Start battery saver</string>
+
+    <!-- Battery saver confirmation dialog text [CHAR LIMIT=NONE]-->
+    <string name="battery_saver_confirmation_text">To help improve battery life, Battery saver will reduce your device’s performance.\n\nBattery saver will be disabled when your device is plugged in.</string>
 
     <!-- Name of the button that links to the Settings app. [CHAR LIMIT=NONE] -->
     <string name="status_bar_settings_settings_button">Settings</string>
@@ -595,4 +613,13 @@
         <item quantity="one">For one hour</item>
         <item quantity="other">For %d hours</item>
     </plurals>
+
+    <!-- Battery saver notification title. [CHAR LIMIT=60]-->
+    <string name="battery_saver_notification_title">Battery saver is on</string>
+
+    <!-- Battery saver notification text. [CHAR LIMIT=60] -->
+    <string name="battery_saver_notification_text">Device performance is reduced.</string>
+
+    <!-- Battery saver notification action text. [CHAR LIMIT=60] -->
+    <string name="battery_saver_notification_action_text">Open battery saver settings</string>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 19d06be..5e48258 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -25,8 +25,6 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Path;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
 import android.graphics.RectF;
 import android.graphics.Typeface;
 import android.os.BatteryManager;
@@ -44,7 +42,6 @@
     private static final boolean SHOW_100_PERCENT = false;
 
     private static final int FULL = 96;
-    private static final int EMPTY = 4;
 
     private static final float SUBPIXEL = 0.4f;  // inset rects for softer edges
     private static final float BOLT_LEVEL_THRESHOLD = 0.3f;  // opaque bolt below this fraction
@@ -58,6 +55,7 @@
     private int mHeight;
     private int mWidth;
     private String mWarningString;
+    private final int mCriticalLevel;
     private final int mChargeColor;
     private final float[] mBoltPoints;
     private final Path mBoltPath = new Path();
@@ -197,6 +195,8 @@
         mShowPercent = ENABLE_PERCENT && 0 != Settings.System.getInt(
                 context.getContentResolver(), "status_bar_show_battery_percent", 0);
         mWarningString = context.getString(R.string.battery_meter_very_low_overlay_symbol);
+        mCriticalLevel = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_criticalBatteryWarningLevel);
 
         mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
         mFramePaint.setColor(frameColor);
@@ -303,7 +303,7 @@
 
         if (level >= FULL) {
             drawFrac = 1f;
-        } else if (level <= EMPTY) {
+        } else if (level <= mCriticalLevel) {
             drawFrac = 0f;
         }
 
@@ -360,7 +360,7 @@
         boolean pctOpaque = false;
         float pctX = 0, pctY = 0;
         String pctText = null;
-        if (!tracker.plugged && level > EMPTY && mShowPercent
+        if (!tracker.plugged && level > mCriticalLevel && mShowPercent
                 && !(tracker.level == 100 && !SHOW_100_PERCENT)) {
             mTextPaint.setColor(getColorForLevel(level));
             mTextPaint.setTextSize(height *
@@ -390,7 +390,7 @@
         c.drawPath(mShapePath, mBatteryPaint);
 
         if (!tracker.plugged) {
-            if (level <= EMPTY) {
+            if (level <= mCriticalLevel) {
                 // draw the warning text
                 final float x = mWidth * 0.5f;
                 final float y = (mHeight + mWarningTextHeight) * 0.48f;
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
index feec87c..2943494 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.power;
 
+import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -25,13 +26,13 @@
 import android.media.Ringtone;
 import android.media.RingtoneManager;
 import android.net.Uri;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
-import android.view.View;
+import android.view.ContextThemeWrapper;
 import android.view.WindowManager;
-import android.widget.TextView;
 
 import com.android.systemui.R;
 
@@ -46,13 +47,14 @@
     private int mBatteryLevel;
     private int mBucket;
     private long mScreenOffTime;
+    private boolean mSaver;
+    private int mSaverTriggerLevel;
 
     private AlertDialog mInvalidChargerDialog;
     private AlertDialog mLowBatteryDialog;
-    private TextView mBatteryLevelTextView;
 
     public PowerDialogWarnings(Context context) {
-        mContext = context;
+        mContext = new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light);
     }
 
     @Override
@@ -77,7 +79,7 @@
 
     @Override
     public void updateLowBatteryWarning() {
-        if (mBatteryLevelTextView != null) {
+        if (mLowBatteryDialog != null) {
             showLowBatteryWarning(false /*playSound*/);
         }
     }
@@ -93,27 +95,22 @@
     @Override
     public void showLowBatteryWarning(boolean playSound) {
         Slog.i(TAG,
-                ((mBatteryLevelTextView == null) ? "showing" : "updating")
+                ((mLowBatteryDialog == null) ? "showing" : "updating")
                 + " low battery warning: level=" + mBatteryLevel
                 + " [" + mBucket + "]");
 
-        CharSequence levelText = mContext.getString(
-                R.string.battery_low_percent_format, mBatteryLevel);
+        final int textRes = mSaver ? R.string.battery_low_percent_format_saver_started
+                : R.string.battery_low_percent_format;
+        final CharSequence levelText = mContext.getString(textRes, mBatteryLevel);
 
-        if (mBatteryLevelTextView != null) {
-            mBatteryLevelTextView.setText(levelText);
+        if (mLowBatteryDialog != null) {
+            mLowBatteryDialog.setMessage(levelText);
         } else {
-            View v = View.inflate(mContext, R.layout.battery_low, null);
-            mBatteryLevelTextView = (TextView)v.findViewById(R.id.level_percent);
-
-            mBatteryLevelTextView.setText(levelText);
-
             AlertDialog.Builder b = new AlertDialog.Builder(mContext);
-                b.setCancelable(true);
-                b.setTitle(R.string.battery_low_title);
-                b.setView(v);
-                b.setIconAttribute(android.R.attr.alertDialogIcon);
-                b.setPositiveButton(android.R.string.ok, null);
+            b.setCancelable(true);
+            b.setTitle(R.string.battery_low_title);
+            b.setMessage(levelText);
+            b.setPositiveButton(android.R.string.ok, null);
 
             final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -125,6 +122,11 @@
                         new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
+                        try {
+                            ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+                        } catch (RemoteException e) {
+                            // we tried
+                        }
                         mContext.startActivityAsUser(intent, UserHandle.CURRENT);
                         dismissLowBatteryWarning();
                     }
@@ -136,10 +138,9 @@
                     @Override
                     public void onDismiss(DialogInterface dialog) {
                         mLowBatteryDialog = null;
-                        mBatteryLevelTextView = null;
                     }
                 });
-            d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+            d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
             d.getWindow().getAttributes().privateFlags |=
                     WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
             d.show();
@@ -198,21 +199,32 @@
         dismissLowBatteryWarning();
 
         AlertDialog.Builder b = new AlertDialog.Builder(mContext);
-            b.setCancelable(true);
-            b.setMessage(R.string.invalid_charger);
-            b.setIconAttribute(android.R.attr.alertDialogIcon);
-            b.setPositiveButton(android.R.string.ok, null);
+        b.setCancelable(true);
+        b.setTitle(R.string.invalid_charger_title);
+        b.setMessage(R.string.invalid_charger_text);
+        b.setPositiveButton(android.R.string.ok, null);
 
         AlertDialog d = b.create();
             d.setOnDismissListener(new DialogInterface.OnDismissListener() {
                     public void onDismiss(DialogInterface dialog) {
                         mInvalidChargerDialog = null;
-                        mBatteryLevelTextView = null;
                     }
                 });
 
-        d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+        d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+        d.getWindow().getAttributes().privateFlags |=
+                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
         d.show();
         mInvalidChargerDialog = d;
     }
+
+    @Override
+    public void showSaverMode(boolean mode) {
+        mSaver = mode;
+    }
+
+    @Override
+    public void setSaverTrigger(int level) {
+        mSaverTriggerLevel = level;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
new file mode 100644
index 0000000..3fa8b99
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.power;
+
+import android.app.AlertDialog;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.Slog;
+import android.view.ContextThemeWrapper;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.R;
+
+import java.io.PrintWriter;
+
+public class PowerNotificationWarnings implements PowerUI.WarningsUI {
+    private static final String TAG = PowerUI.TAG + ".Notification";
+    private static final boolean DEBUG = PowerUI.DEBUG;
+
+    private static final String TAG_NOTIFICATION = "low_battery";
+    private static final int ID_NOTIFICATION = 100;
+    private static final int AUTO_DISMISS_MS = 10000;
+
+    private static final int SHOWING_NOTHING = 0;
+    private static final int SHOWING_WARNING = 1;
+    private static final int SHOWING_SAVER = 2;
+    private static final int SHOWING_INVALID_CHARGER = 3;
+    private static final String[] SHOWING_STRINGS = {
+        "SHOWING_NOTHING",
+        "SHOWING_WARNING",
+        "SHOWING_SAVER",
+        "SHOWING_INVALID_CHARGER",
+    };
+
+    private static final String ACTION_SHOW_FALLBACK_WARNING = "PNW.warningFallback";
+    private static final String ACTION_SHOW_FALLBACK_CHARGER = "PNW.chargerFallback";
+    private static final String ACTION_SHOW_BATTERY_SETTINGS = "PNW.batterySettings";
+    private static final String ACTION_START_SAVER = "PNW.startSaver";
+
+    private final Context mContext;
+    private final Context mLightContext;
+    private final NotificationManager mNoMan;
+    private final Handler mHandler = new Handler();
+    private final PowerDialogWarnings mFallbackDialogs;
+    private final Receiver mReceiver = new Receiver();
+    private final Intent mOpenBatterySettings = settings(Intent.ACTION_POWER_USAGE_SUMMARY);
+    private final Intent mOpenSaverSettings = settings(Settings.ACTION_BATTERY_SAVER_SETTINGS);
+
+    private int mBatteryLevel;
+    private int mBucket;
+    private long mScreenOffTime;
+    private int mShowing;
+
+    private boolean mSaver;
+    private int mSaverTriggerLevel;
+    private boolean mWarning;
+    private boolean mPlaySound;
+    private boolean mInvalidCharger;
+
+    public PowerNotificationWarnings(Context context) {
+        mContext = context;
+        mLightContext = new ContextThemeWrapper(mContext,
+                android.R.style.Theme_DeviceDefault_Light);
+        mNoMan = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+        mFallbackDialogs = new PowerDialogWarnings(context);
+        mReceiver.init();
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+        pw.print("mSaver="); pw.println(mSaver);
+        pw.print("mWarning="); pw.println(mWarning);
+        pw.print("mPlaySound="); pw.println(mPlaySound);
+        pw.print("mInvalidCharger="); pw.println(mInvalidCharger);
+        pw.print("mShowing="); pw.println(SHOWING_STRINGS[mShowing]);
+    }
+
+    @Override
+    public void update(int batteryLevel, int bucket, long screenOffTime) {
+        mBatteryLevel = batteryLevel;
+        mBucket = bucket;
+        mScreenOffTime = screenOffTime;
+        mFallbackDialogs.update(batteryLevel, bucket, screenOffTime);
+    }
+
+    @Override
+    public void showSaverMode(boolean mode) {
+        mSaver = mode;
+        updateNotification();
+    }
+
+    @Override
+    public void setSaverTrigger(int level) {
+        mSaverTriggerLevel = level;
+        updateNotification();
+    }
+
+    private void cancelOther(int showing) {
+        if (mShowing != SHOWING_NOTHING && mShowing != showing) {
+            mNoMan.cancel(TAG_NOTIFICATION, ID_NOTIFICATION);  // workaround no HUN on updates
+        }
+    }
+
+    private void updateNotification() {
+        Slog.d(TAG, "updateNotification mWarning=" + mWarning
+                + " mSaver=" + mSaver + " mInvalidCharger=" + mInvalidCharger);
+        if (mInvalidCharger) {
+            cancelOther(SHOWING_INVALID_CHARGER);
+            showInvalidChargerNotification();
+            mShowing = SHOWING_INVALID_CHARGER;
+        } else if (mWarning) {
+            cancelOther(SHOWING_WARNING);
+            showWarningNotification();
+            mShowing = SHOWING_WARNING;
+        } else if (mSaver) {
+            cancelOther(SHOWING_SAVER);
+            showSaverNotification();
+            mShowing = SHOWING_SAVER;
+        } else {
+            mNoMan.cancel(TAG_NOTIFICATION, ID_NOTIFICATION);
+            mShowing = SHOWING_NOTHING;
+        }
+    }
+
+    private void showInvalidChargerNotification() {
+        final Notification.Builder nb = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.ic_power_low)
+                .setShowWhen(false)
+                .setOngoing(true)
+                .setContentTitle(mContext.getString(R.string.invalid_charger_title))
+                .setContentText(mContext.getString(R.string.invalid_charger_text))
+                .setPriority(Notification.PRIORITY_MAX)
+                .setCategory(Notification.CATEGORY_SYSTEM)
+                .setFullScreenIntent(pendingBroadcast(ACTION_SHOW_FALLBACK_CHARGER), true);
+        final Notification n = nb.build();
+        if (n.headsUpContentView != null) {
+            n.headsUpContentView.setViewVisibility(com.android.internal.R.id.right_icon, View.GONE);
+        }
+        mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, n, UserHandle.CURRENT);
+    }
+
+    private void showWarningNotification() {
+        final int textRes = mSaver ? R.string.battery_low_percent_format_saver_started
+                : R.string.battery_low_percent_format;
+        final Notification.Builder nb = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.ic_power_low)
+                .setShowWhen(false)
+                .setContentTitle(mContext.getString(R.string.battery_low_title))
+                .setContentText(mContext.getString(textRes, mBatteryLevel))
+                .setOngoing(true)
+                .setPriority(Notification.PRIORITY_MAX)
+                .setCategory(Notification.CATEGORY_SYSTEM)
+                .setFullScreenIntent(pendingBroadcast(ACTION_SHOW_FALLBACK_WARNING), true);
+        if (hasBatterySettings()) {
+            nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
+        }
+        if (!mSaver && mSaverTriggerLevel <= 0) {
+            nb.addAction(R.drawable.ic_power_saver,
+                    mContext.getString(R.string.battery_saver_start_action),
+                    pendingBroadcast(ACTION_START_SAVER));
+        }
+        if (mPlaySound) {
+            attachLowBatterySound(nb);
+        }
+        final Notification n = nb.build();
+        if (n.headsUpContentView != null) {
+            n.headsUpContentView.setViewVisibility(com.android.internal.R.id.right_icon, View.GONE);
+        }
+        mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, n, UserHandle.CURRENT);
+    }
+
+    private void showSaverNotification() {
+        final Notification.Builder nb = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.ic_power_saver)
+                .setContentTitle(mContext.getString(R.string.battery_saver_notification_title))
+                .setContentText(mContext.getString(R.string.battery_saver_notification_text))
+                .setOngoing(true)
+                .setShowWhen(false)
+                .setCategory(Notification.CATEGORY_SYSTEM);
+        if (hasSaverSettings()) {
+            nb.addAction(0,
+                    mContext.getString(R.string.battery_saver_notification_action_text),
+                    pendingActivity(mOpenSaverSettings));
+            nb.setContentIntent(pendingActivity(mOpenSaverSettings));
+        }
+        mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, nb.build(), UserHandle.CURRENT);
+    }
+
+    private PendingIntent pendingActivity(Intent intent) {
+        return PendingIntent.getActivityAsUser(mContext,
+                0, intent, 0, null, UserHandle.CURRENT);
+    }
+
+    private PendingIntent pendingBroadcast(String action) {
+        return PendingIntent.getBroadcastAsUser(mContext,
+                0, new Intent(action), 0, UserHandle.CURRENT);
+    }
+
+    private static Intent settings(String action) {
+        return new Intent(action).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
+                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+                | Intent.FLAG_ACTIVITY_NO_HISTORY
+                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+    }
+
+    @Override
+    public boolean isInvalidChargerWarningShowing() {
+        return mInvalidCharger;
+    }
+
+    @Override
+    public void updateLowBatteryWarning() {
+        updateNotification();
+        mFallbackDialogs.updateLowBatteryWarning();
+    }
+
+    @Override
+    public void dismissLowBatteryWarning() {
+        Slog.i(TAG, "dismissing low battery warning: level=" + mBatteryLevel);
+        dismissLowBatteryNotification();
+        mFallbackDialogs.dismissLowBatteryWarning();
+    }
+
+    private void dismissLowBatteryNotification() {
+        Slog.i(TAG, "dismissing low battery notification");
+        mWarning = false;
+        updateNotification();
+    }
+
+    private boolean hasBatterySettings() {
+        return mOpenBatterySettings.resolveActivity(mContext.getPackageManager()) != null;
+    }
+
+    private boolean hasSaverSettings() {
+        return mOpenSaverSettings.resolveActivity(mContext.getPackageManager()) != null;
+    }
+
+    @Override
+    public void showLowBatteryWarning(boolean playSound) {
+        Slog.i(TAG,
+                "show low battery warning: level=" + mBatteryLevel
+                + " [" + mBucket + "]");
+        mPlaySound = playSound;
+        mWarning = true;
+        updateNotification();
+        mHandler.removeCallbacks(mDismissLowBatteryNotification);
+        mHandler.postDelayed(mDismissLowBatteryNotification, AUTO_DISMISS_MS);
+    }
+
+    private void attachLowBatterySound(Notification.Builder b) {
+        final ContentResolver cr = mContext.getContentResolver();
+
+        final int silenceAfter = Settings.Global.getInt(cr,
+                Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0);
+        final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime;
+        if (silenceAfter > 0
+                && mScreenOffTime > 0
+                && offTime > silenceAfter) {
+            Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter
+                    + "ms): not waking up the user with low battery sound");
+            return;
+        }
+
+        if (DEBUG) {
+            Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated
+        }
+
+        if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) {
+            final String soundPath = Settings.Global.getString(cr,
+                    Settings.Global.LOW_BATTERY_SOUND);
+            if (soundPath != null) {
+                final Uri soundUri = Uri.parse("file://" + soundPath);
+                if (soundUri != null) {
+                    b.setSound(soundUri, AudioManager.STREAM_SYSTEM);
+                    Slog.d(TAG, "playing sound " + soundUri);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void dismissInvalidChargerWarning() {
+        mInvalidCharger = false;
+        updateNotification();
+    }
+
+    @Override
+    public void showInvalidChargerWarning() {
+        mInvalidCharger = true;
+        updateNotification();
+    }
+
+    private void showStartSaverConfirmation() {
+        final AlertDialog d = new AlertDialog.Builder(mLightContext)
+                .setTitle(R.string.battery_saver_confirmation_title)
+                .setMessage(R.string.battery_saver_confirmation_text)
+                .setNegativeButton(android.R.string.cancel, null)
+                .setPositiveButton(R.string.battery_saver_confirmation_ok, mStartSaverMode)
+                .create();
+
+        d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+        d.getWindow().getAttributes().privateFlags |=
+                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        d.show();
+    }
+
+    private void setSaverSetting(boolean mode) {
+        final int val = mode ? 1 : 0;
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.LOW_POWER_MODE, val);
+    }
+
+    private final class Receiver extends BroadcastReceiver {
+
+        public void init() {
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(ACTION_SHOW_FALLBACK_WARNING);
+            filter.addAction(ACTION_SHOW_FALLBACK_CHARGER);
+            filter.addAction(ACTION_SHOW_BATTERY_SETTINGS);
+            filter.addAction(ACTION_START_SAVER);
+            mContext.registerReceiver(this, filter, null, mHandler);
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            Log.d(TAG, "got " + action);
+            if (action.equals(ACTION_SHOW_FALLBACK_WARNING)) {
+                mFallbackDialogs.showLowBatteryWarning(false /*playSound*/);
+            } else if (action.equals(ACTION_SHOW_FALLBACK_CHARGER)) {
+                mFallbackDialogs.showInvalidChargerWarning();
+            } else if (action.equals(ACTION_SHOW_BATTERY_SETTINGS)) {
+                dismissLowBatteryNotification();
+                mContext.startActivityAsUser(mOpenBatterySettings, UserHandle.CURRENT);
+            } else if (action.equals(ACTION_START_SAVER)) {
+                dismissLowBatteryNotification();
+                showStartSaverConfirmation();
+            }
+        }
+    }
+
+    private final OnClickListener mStartSaverMode = new OnClickListener() {
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            AsyncTask.execute(new Runnable() {
+                @Override
+                public void run() {
+                    setSaverSetting(true);
+                }
+            });
+        }
+    };
+
+    private final Runnable mDismissLowBatteryNotification = new Runnable() {
+        @Override
+        public void run() {
+            dismissLowBatteryNotification();
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 0fb0f8b..1bb7edb 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -17,13 +17,17 @@
 package com.android.systemui.power;
 
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
 import android.os.BatteryManager;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.SystemClock;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
 
@@ -35,13 +39,15 @@
 
 public class PowerUI extends SystemUI {
     static final String TAG = "PowerUI";
-
     static final boolean DEBUG = false;
 
-    private WarningsUI mWarnings;
 
     private final Handler mHandler = new Handler();
+    private final SettingsObserver mObserver = new SettingsObserver(mHandler);
+    private final Receiver mReceiver = new Receiver();
 
+    private PowerManager mPowerManager;
+    private WarningsUI mWarnings;
     private int mBatteryLevel = 100;
     private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
     private int mPlugType = 0;
@@ -53,24 +59,54 @@
     private long mScreenOffTime = -1;
 
     public void start() {
+        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
+        mWarnings = new PowerNotificationWarnings(mContext);
 
-        mLowBatteryAlertCloseLevel = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);
-        mLowBatteryReminderLevels[0] = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_lowBatteryWarningLevel);
-        mLowBatteryReminderLevels[1] = mContext.getResources().getInteger(
+        ContentObserver obs = new ContentObserver(mHandler) {
+            @Override
+            public void onChange(boolean selfChange) {
+                updateBatteryWarningLevels();
+            }
+        };
+        final ContentResolver resolver = mContext.getContentResolver();
+        resolver.registerContentObserver(Settings.Global.getUriFor(
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
+                false, obs, UserHandle.USER_ALL);
+        updateBatteryWarningLevels();
+        mReceiver.init();
+        mObserver.init();
+    }
+
+    private void setSaverMode(boolean mode) {
+        mWarnings.showSaverMode(mode);
+    }
+
+    private void setSaverTrigger(int level) {
+        mWarnings.setSaverTrigger(level);
+    }
+
+    void updateBatteryWarningLevels() {
+        int critLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
 
-        final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-        mScreenOffTime = pm.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
-        mWarnings = new PowerDialogWarnings(mContext);
+        final ContentResolver resolver = mContext.getContentResolver();
+        int defWarnLevel = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_lowBatteryWarningLevel);
+        int warnLevel = Settings.Global.getInt(resolver,
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);
+        if (warnLevel == 0) {
+            warnLevel = defWarnLevel;
+        }
+        if (warnLevel < critLevel) {
+            warnLevel = critLevel;
+        }
 
-        // Register for Intent broadcasts for...
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        filter.addAction(Intent.ACTION_SCREEN_ON);
-        mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
+        mLowBatteryReminderLevels[0] = warnLevel;
+        mLowBatteryReminderLevels[1] = critLevel;
+        mLowBatteryAlertCloseLevel = mLowBatteryReminderLevels[0]
+                + mContext.getResources().getInteger(
+                        com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
     }
 
     /**
@@ -87,7 +123,7 @@
         if (level >= mLowBatteryAlertCloseLevel) {
             return 1;
         }
-        if (level >= mLowBatteryReminderLevels[0]) {
+        if (level > mLowBatteryReminderLevels[0]) {
             return 0;
         }
         final int N = mLowBatteryReminderLevels.length;
@@ -99,7 +135,23 @@
         throw new RuntimeException("not possible!");
     }
 
-    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+    private final class Receiver extends BroadcastReceiver {
+
+        public void init() {
+            // Register for Intent broadcasts for...
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+            filter.addAction(Intent.ACTION_SCREEN_OFF);
+            filter.addAction(Intent.ACTION_SCREEN_ON);
+            filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+            mContext.registerReceiver(this, filter, null, mHandler);
+            updateSaverMode();
+        }
+
+        private void updateSaverMode() {
+            setSaverMode(mPowerManager.isPowerSaveMode());
+        }
+
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
@@ -160,6 +212,8 @@
                 mScreenOffTime = SystemClock.elapsedRealtime();
             } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
                 mScreenOffTime = -1;
+            } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
+                updateSaverMode();
             } else {
                 Slog.w(TAG, "unknown intent: " + intent);
             }
@@ -197,6 +251,8 @@
 
     public interface WarningsUI {
         void update(int batteryLevel, int bucket, long screenOffTime);
+        void setSaverTrigger(int level);
+        void showSaverMode(boolean mode);
         void dismissLowBatteryWarning();
         void showLowBatteryWarning(boolean playSound);
         void dismissInvalidChargerWarning();
@@ -205,5 +261,29 @@
         boolean isInvalidChargerWarningShowing();
         void dump(PrintWriter pw);
     }
+
+    private final class SettingsObserver extends ContentObserver {
+        private final Uri LOW_POWER_MODE_TRIGGER_LEVEL_URI =
+                Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL);
+
+        public SettingsObserver(Handler handler) {
+            super(handler);
+        }
+
+        public void init() {
+            onChange(true, LOW_POWER_MODE_TRIGGER_LEVEL_URI);
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.registerContentObserver(LOW_POWER_MODE_TRIGGER_LEVEL_URI, false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (LOW_POWER_MODE_TRIGGER_LEVEL_URI.equals(uri)) {
+                final int level = Settings.Global.getInt(mContext.getContentResolver(),
+                        Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+                setSaverTrigger(level);
+            }
+        }
+    }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index c76ee8c..786cd9e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -287,6 +287,7 @@
         public boolean activityIn;
         public boolean activityOut;
         public int overlayIconId;
+        public boolean filter;
 
         @Override
         public boolean copyTo(State other) {
@@ -300,6 +301,7 @@
             o.activityIn = activityIn;
             o.activityOut = activityOut;
             o.overlayIconId = overlayIconId;
+            o.filter = filter;
             return super.copyTo(other) || changed;
         }
 
@@ -311,6 +313,7 @@
             rt.insert(rt.length() - 1, ",activityIn=" + activityIn);
             rt.insert(rt.length() - 1, ",activityOut=" + activityOut);
             rt.insert(rt.length() - 1, ",overlayIconId=" + overlayIconId);
+            rt.insert(rt.length() - 1, ",filter=" + filter);
             return rt;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index 901cc10..d5fe033 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -93,12 +93,12 @@
         final SignalState s = (SignalState) state;
         mSignal.setImageDrawable(null);  // force refresh
         mSignal.setImageResource(s.iconId);
-        mSignal.setColorFilter(FILTER);
+        mSignal.setColorFilter(s.filter ? FILTER : null);
         if (s.overlayIconId > 0) {
             mOverlay.setVisibility(VISIBLE);
             mOverlay.setImageDrawable(null);  // force refresh
             mOverlay.setImageResource(s.overlayIconId);
-            mOverlay.setColorFilter(FILTER);
+            mOverlay.setColorFilter(s.filter ? FILTER : null);
         } else {
             mOverlay.setVisibility(GONE);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 182a0ce..6d91d33 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -72,12 +72,15 @@
         if (cb == null) return;
 
         final Resources r = mContext.getResources();
-        state.iconId = cb.enabled && (cb.mobileSignalIconId > 0)
+        state.iconId = cb.noSim
+                ? R.drawable.stat_sys_no_sim
+                : cb.enabled && (cb.mobileSignalIconId > 0)
                 ? cb.mobileSignalIconId
                 : R.drawable.ic_qs_signal_no_signal;
         state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiEnabled
                 ? cb.dataTypeIconId
                 : 0;
+        state.filter = state.iconId != R.drawable.stat_sys_no_sim;
         state.activityIn = cb.enabled && cb.activityIn;
         state.activityOut = cb.enabled && cb.activityOut;
 
@@ -117,6 +120,7 @@
         boolean activityIn;
         boolean activityOut;
         String enabledDesc;
+        boolean noSim;
     }
 
     private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() {
@@ -134,7 +138,7 @@
                 int mobileSignalIconId,
                 String mobileSignalContentDescriptionId, int dataTypeIconId,
                 boolean activityIn, boolean activityOut,
-                String dataTypeContentDescriptionId, String description) {
+                String dataTypeContentDescriptionId, String description, boolean noSim) {
             final CallbackInfo info = new CallbackInfo();  // TODO pool?
             info.enabled = enabled;
             info.wifiEnabled = mWifiEnabled;
@@ -145,6 +149,7 @@
             info.activityIn = activityIn;
             info.activityOut = activityOut;
             info.enabledDesc = description;
+            info.noSim = noSim;
             refreshState(info);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 5301362..7c2c7c3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -71,6 +71,6 @@
         state.visible = mVisible;
         state.value = enabled;
         state.label = mContext.getString(R.string.quick_settings_inversion_label);
-        state.iconId = R.drawable.ic_qs_color_inversion;
+        state.iconId = enabled ? R.drawable.ic_qs_inversion_on : R.drawable.ic_qs_inversion_off;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index db9b054..04f1eb5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -16,9 +16,6 @@
 
 package com.android.systemui.qs.tiles;
 
-import android.content.res.Resources;
-import android.graphics.drawable.AnimationDrawable;
-
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.LocationController;
@@ -63,28 +60,15 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         final boolean locationEnabled =  mController.isLocationEnabled();
         state.visible = true;
-        if (state.value != locationEnabled) {
-            state.value = locationEnabled;
-            final Resources res = mContext.getResources();
-            final AnimationDrawable d = (AnimationDrawable) res.getDrawable(locationEnabled
-                    ? R.drawable.ic_qs_location_on
-                    : R.drawable.ic_qs_location_off);
-            state.icon = d;
-            mUiHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    d.start();
-                }
-            });
-        }
+        state.value = locationEnabled;
         if (locationEnabled) {
-            if (state.icon == null) state.iconId = R.drawable.ic_qs_location_01;
+            state.iconId = R.drawable.ic_qs_location_on;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location,
                     mContext.getString(R.string.accessibility_desc_on));
         } else {
-            if (state.icon == null) state.iconId = R.drawable.ic_qs_location_11;
+            state.iconId = R.drawable.ic_qs_location_off;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 6b73002..a236497 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -87,6 +87,7 @@
         state.connected = wifiConnected;
         state.activityIn = cb.enabled && cb.activityIn;
         state.activityOut = cb.enabled && cb.activityOut;
+        state.filter = true;
         final String signalContentDescription;
         final Resources r = mContext.getResources();
         if (wifiConnected) {
@@ -159,7 +160,7 @@
                 int mobileSignalIconId,
                 String mobileSignalContentDescriptionId, int dataTypeIconId,
                 boolean activityIn, boolean activityOut,
-                String dataTypeContentDescriptionId, String description) {
+                String dataTypeContentDescriptionId, String description, boolean noSim) {
             // noop
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
index 0c2c11d..113efe3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
@@ -121,6 +121,7 @@
             // Send a broadcast to hide recents
             Intent intent = new Intent(RecentsService.ACTION_HIDE_RECENTS_ACTIVITY);
             intent.setPackage(context.getPackageName());
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             if (msg.arg1 != 0) {
                 intent.putExtra(RecentsService.EXTRA_TRIGGERED_FROM_ALT_TAB, true);
             }
@@ -129,6 +130,7 @@
             // Send a broadcast to toggle recents
             Intent intent = new Intent(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
             intent.setPackage(context.getPackageName());
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             context.sendBroadcast(intent);
 
             // Time this path
@@ -140,6 +142,7 @@
             // Send a broadcast to start the enter animation
             Intent intent = new Intent(RecentsService.ACTION_START_ENTER_ANIMATION);
             intent.setPackage(context.getPackageName());
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             context.sendBroadcast(intent);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index b91e129..8d19f50 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -158,7 +158,7 @@
     private final Runnable mTapTimeoutRunnable = new Runnable() {
         @Override
         public void run() {
-            makeInactive();
+            makeInactive(true /* animate */);
         }
     };
 
@@ -183,7 +183,7 @@
                 break;
             case MotionEvent.ACTION_MOVE:
                 if (!isWithinTouchSlop(event)) {
-                    makeInactive();
+                    makeInactive(true /* animate */);
                     return false;
                 }
                 break;
@@ -193,14 +193,17 @@
                         makeActive();
                         postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
                     } else {
-                        performClick();
+                        boolean performed = performClick();
+                        if (performed) {
+                            removeCallbacks(mTapTimeoutRunnable);
+                        }
                     }
                 } else {
-                    makeInactive();
+                    makeInactive(true /* animate */);
                 }
                 break;
             case MotionEvent.ACTION_CANCEL:
-                makeInactive();
+                makeInactive(true /* animate */);
                 break;
             default:
                 break;
@@ -257,10 +260,14 @@
     /**
      * Cancels the hotspot and makes the notification inactive.
      */
-    private void makeInactive() {
+    public void makeInactive(boolean animate) {
         if (mActivated) {
             if (mDimmed) {
-                startActivateAnimation(true /* reverse */);
+                if (animate) {
+                    startActivateAnimation(true /* reverse */);
+                } else {
+                    mBackgroundNormal.setVisibility(View.INVISIBLE);
+                }
             }
             mActivated = false;
         }
@@ -351,6 +358,7 @@
             mBackgroundDimmed.setVisibility(View.INVISIBLE);
             mBackgroundNormal.setVisibility(View.VISIBLE);
             mBackgroundNormal.setAlpha(1f);
+            removeCallbacks(mTapTimeoutRunnable);
         }
     }
 
@@ -581,7 +589,7 @@
     }
 
     public interface OnActivatedListener {
-        void onActivated(View view);
-        void onActivationReset(View view);
+        void onActivated(ActivatableNotificationView view);
+        void onActivationReset(ActivatableNotificationView view);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 508c34e..5a9fe91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -48,7 +48,7 @@
 import android.service.dreams.DreamService;
 import android.service.dreams.IDreamManager;
 import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
 import android.util.Log;
@@ -80,11 +80,10 @@
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.NotificationData.Entry;
 import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
+import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.Locale;
 
 import static com.android.keyguard.KeyguardHostView.OnDismissAction;
@@ -106,6 +105,7 @@
     protected static final int MSG_SHOW_HEADS_UP = 1026;
     protected static final int MSG_HIDE_HEADS_UP = 1027;
     protected static final int MSG_ESCALATE_HEADS_UP = 1028;
+    protected static final int MSG_DECAY_HEADS_UP = 1029;
 
     protected static final boolean ENABLE_HEADS_UP = true;
     // scores above this threshold should be displayed in heads up mode.
@@ -129,7 +129,9 @@
     protected NotificationData mNotificationData = new NotificationData();
     protected NotificationStackScrollLayout mStackScroller;
 
-    protected NotificationData.Entry mInterruptingNotificationEntry;
+    // for heads up notifications
+    protected HeadsUpNotificationView mHeadsUpNotificationView;
+    protected int mHeadsUpNotificationDecay;
     protected long mInterruptingNotificationTime;
 
     // used to notify status bar for suppressing notification LED
@@ -291,7 +293,7 @@
         public void onListenerConnected() {
             if (DEBUG) Log.d(TAG, "onListenerConnected");
             final StatusBarNotification[] notifications = getActiveNotifications();
-            final Ranking currentRanking = getCurrentRanking();
+            final RankingMap currentRanking = getCurrentRanking();
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
@@ -303,41 +305,40 @@
         }
 
         @Override
-        public void onNotificationPosted(final StatusBarNotification sbn) {
+        public void onNotificationPosted(final StatusBarNotification sbn,
+                final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
-            final Ranking currentRanking = getCurrentRanking();
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
                     if (mNotificationData.findByKey(sbn.getKey()) != null) {
-                        updateNotificationInternal(sbn, currentRanking);
+                        updateNotificationInternal(sbn, rankingMap);
                     } else {
-                        addNotificationInternal(sbn, currentRanking);
+                        addNotificationInternal(sbn, rankingMap);
                     }
                 }
             });
         }
 
         @Override
-        public void onNotificationRemoved(final StatusBarNotification sbn) {
+        public void onNotificationRemoved(final StatusBarNotification sbn,
+                final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
-            final Ranking currentRanking = getCurrentRanking();
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    removeNotificationInternal(sbn.getKey(), currentRanking);
+                    removeNotificationInternal(sbn.getKey(), rankingMap);
                 }
             });
         }
 
         @Override
-        public void onNotificationRankingUpdate() {
+        public void onNotificationRankingUpdate(final RankingMap rankingMap) {
             if (DEBUG) Log.d(TAG, "onRankingUpdate");
-            final Ranking currentRanking = getCurrentRanking();
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    updateRankingInternal(currentRanking);
+                    updateRankingInternal(rankingMap);
                 }
             });
         }
@@ -505,8 +506,8 @@
 
     protected View updateNotificationVetoButton(View row, StatusBarNotification n) {
         View vetoButton = row.findViewById(R.id.veto);
-        if (n.isClearable() || (mInterruptingNotificationEntry != null
-                && mInterruptingNotificationEntry.row == row)) {
+        if (n.isClearable() || (mHeadsUpNotificationView.getEntry() != null
+                && mHeadsUpNotificationView.getEntry().row == row)) {
             final String _pkg = n.getPackageName();
             final String _tag = n.getTag();
             final int _id = n.getId();
@@ -765,6 +766,12 @@
 
     public abstract void resetHeadsUpDecayTimer();
 
+    public abstract void scheduleHeadsUpOpen();
+
+    public abstract void scheduleHeadsUpClose();
+
+    public abstract void scheduleHeadsUpEscalation();
+
     /**
      * Save the current "public" (locked and secure) state of the lockscreen.
      */
@@ -796,6 +803,18 @@
         return mUsersAllowingPrivateNotifications.get(userHandle);
     }
 
+    public void onNotificationClear(StatusBarNotification notification) {
+        try {
+            mBarService.onNotificationClear(
+                    notification.getPackageName(),
+                    notification.getTag(),
+                    notification.getId(),
+                    notification.getUserId());
+        } catch (android.os.RemoteException ex) {
+            // oh well
+        }
+    }
+
     protected class H extends Handler {
         public void handleMessage(Message m) {
             Intent intent;
@@ -1101,7 +1120,7 @@
 
                     try {
                         if (mIsHeadsUp) {
-                            mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+                            mHeadsUpNotificationView.clear();
                         }
                         mBarService.onNotificationClick(mNotificationKey);
                     } catch (RemoteException ex) {
@@ -1157,7 +1176,7 @@
         }
     }
 
-    protected StatusBarNotification removeNotificationViews(String key, Ranking ranking) {
+    protected StatusBarNotification removeNotificationViews(String key, RankingMap ranking) {
         NotificationData.Entry entry = mNotificationData.remove(key, ranking);
         if (entry == null) {
             Log.w(TAG, "removeNotification for unknown key: " + key);
@@ -1197,7 +1216,7 @@
         return entry;
     }
 
-    protected void addNotificationViews(Entry entry, Ranking ranking) {
+    protected void addNotificationViews(Entry entry, RankingMap ranking) {
         if (entry == null) {
             return;
         }
@@ -1206,7 +1225,7 @@
         updateNotifications();
     }
 
-    private void addNotificationViews(StatusBarNotification notification, Ranking ranking) {
+    private void addNotificationViews(StatusBarNotification notification, RankingMap ranking) {
         addNotificationViews(createNotificationViews(notification), ranking);
     }
 
@@ -1292,9 +1311,9 @@
     }
 
     public abstract void addNotificationInternal(StatusBarNotification notification,
-            Ranking ranking);
+            RankingMap ranking);
 
-    protected abstract void updateRankingInternal(Ranking ranking);
+    protected abstract void updateRankingInternal(RankingMap ranking);
 
     @Override
     public void removeNotification(String key) {
@@ -1303,7 +1322,7 @@
         }
     }
 
-    public abstract void removeNotificationInternal(String key, Ranking ranking);
+    public abstract void removeNotificationInternal(String key, RankingMap ranking);
 
     public void updateNotification(StatusBarNotification notification) {
         if (!USE_NOTIFICATION_LISTENER) {
@@ -1311,7 +1330,7 @@
         }
     }
 
-    public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+    public void updateNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
         if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
 
         final NotificationData.Entry oldEntry = mNotificationData.findByKey(notification.getKey());
@@ -1394,15 +1413,15 @@
             try {
                 updateNotificationViews(oldEntry, notification);
 
-                if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null
-                        && oldNotification == mInterruptingNotificationEntry.notification) {
+                if (ENABLE_HEADS_UP && mHeadsUpNotificationView.getEntry() != null
+                        && oldNotification == mHeadsUpNotificationView.getEntry().notification) {
                     if (!shouldInterrupt(notification)) {
                         if (DEBUG) Log.d(TAG, "no longer interrupts!");
-                        mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+                        scheduleHeadsUpClose();
                     } else {
                         if (DEBUG) Log.d(TAG, "updating the current heads up:" + notification);
-                        mInterruptingNotificationEntry.notification = notification;
-                        updateHeadsUpViews(mInterruptingNotificationEntry, notification);
+                        mHeadsUpNotificationView.getEntry().notification = notification;
+                        updateHeadsUpViews(mHeadsUpNotificationView.getEntry(), notification);
                     }
                 }
 
@@ -1511,8 +1530,8 @@
     }
 
     protected void notifyHeadsUpScreenOn(boolean screenOn) {
-        if (!screenOn && mInterruptingNotificationEntry != null) {
-            mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP);
+        if (!screenOn) {
+            scheduleHeadsUpEscalation();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
index 4233ab8..bfa74fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
@@ -21,6 +21,7 @@
 import android.os.Process;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -58,17 +59,18 @@
         updateSyntheticNotification();
     }
 
-    public boolean tryIntercept(StatusBarNotification notification, Ranking ranking) {
-        if (ranking == null) return false;
+    public boolean tryIntercept(StatusBarNotification notification, RankingMap rankingMap) {
+        if (rankingMap == null) return false;
         if (shouldDisplayIntercepted()) return false;
         if (mReleased.contains(notification.getKey())) return false;
-        if (!ranking.isInterceptedByDoNotDisturb(notification.getKey())) return false;
+        Ranking ranking = rankingMap.getRanking(notification.getKey());
+        if (!ranking.isInterceptedByDoNotDisturb()) return false;
         mIntercepted.put(notification.getKey(), notification);
         updateSyntheticNotification();
         return true;
     }
 
-    public void retryIntercepts(Ranking ranking) {
+    public void retryIntercepts(RankingMap ranking) {
         if (ranking == null) return;
 
         final int N = mIntercepted.size();
@@ -111,7 +113,7 @@
             return;
         }
         final Notification n = new Notification.Builder(mContext)
-                .setSmallIcon(R.drawable.ic_qs_zen_on)
+                .setSmallIcon(R.drawable.ic_notify_zen)
                 .setContentTitle(mContext.getResources().getQuantityString(
                         R.plurals.zen_mode_notification_title,
                         mIntercepted.size(), mIntercepted.size()))
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 631e19c..c313c58 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -18,6 +18,7 @@
 
 import android.app.Notification;
 import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.view.View;
 
@@ -70,12 +71,16 @@
     }
 
     private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
-    private Ranking mRanking;
+    private RankingMap mRanking;
     private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() {
         @Override
         public int compare(Entry a, Entry b) {
             if (mRanking != null) {
-                return mRanking.getRank(a.key) - mRanking.getRank(b.key);
+                Ranking aRanking = mRanking.getRanking(a.key);
+                Ranking bRanking = mRanking.getRanking(b.key);
+                int aRank = aRanking != null ? aRanking.getRank() : -1;
+                int bRank = bRanking != null ? bRanking.getRank() : -1;
+                return aRank - bRank;
             }
 
             final StatusBarNotification na = a.notification;
@@ -108,12 +113,12 @@
         return null;
     }
 
-    public void add(Entry entry, Ranking ranking) {
+    public void add(Entry entry, RankingMap ranking) {
         mEntries.add(entry);
         updateRankingAndSort(ranking);
     }
 
-    public Entry remove(String key, Ranking ranking) {
+    public Entry remove(String key, RankingMap ranking) {
         Entry e = findByKey(key);
         if (e == null) {
             return null;
@@ -123,7 +128,7 @@
         return e;
     }
 
-    public void updateRanking(Ranking ranking) {
+    public void updateRanking(RankingMap ranking) {
         updateRankingAndSort(ranking);
     }
 
@@ -137,12 +142,13 @@
                 }
             }
         } else {
-            return mRanking.isAmbient(key);
+            Ranking ranking = mRanking.getRanking(key);
+            return ranking != null && ranking.isAmbient();
         }
         return false;
     }
 
-    private void updateRankingAndSort(Ranking ranking) {
+    private void updateRankingAndSort(RankingMap ranking) {
         if (ranking != null) {
             mRanking = ranking;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java
deleted file mode 100644
index 1503072..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotView.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Outline;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * An single dot of the {@link com.android.systemui.statusbar.SpeedBumpDotsLayout}
- */
-public class SpeedBumpDotView extends View {
-
-    private final Paint mPaint = new Paint();
-
-    public SpeedBumpDotView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mPaint.setAntiAlias(true);
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        float radius = getWidth() / 2.0f;
-        canvas.drawCircle(radius, radius, radius, mPaint);
-    }
-
-    @Override
-    public boolean hasOverlappingRendering() {
-        return false;
-    }
-
-    public void setColor(int color) {
-        mPaint.setColor(color);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java
deleted file mode 100644
index cac6327..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsAlgorithm.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.content.Context;
-import android.view.View;
-import com.android.systemui.R;
-
-/**
- * The Algorithm of the {@link com.android.systemui.statusbar.SpeedBumpDotsLayout} which can be
- * queried for {@link * com.android.systemui.statusbar.SpeedBumpDotsState}
- */
-public class SpeedBumpDotsAlgorithm {
-
-    private final float mDotRadius;
-
-    public SpeedBumpDotsAlgorithm(Context context) {
-        mDotRadius = context.getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height)
-                / 2.0f;
-    }
-
-    public void getState(SpeedBumpDotsState resultState) {
-
-        // First reset the current state and ensure that every View has a ViewState
-        resultState.resetViewStates();
-
-        SpeedBumpDotsLayout hostView = resultState.getHostView();
-        boolean currentlyVisible = hostView.isCurrentlyVisible();
-        resultState.setActiveState(currentlyVisible
-                ? SpeedBumpDotsState.SHOWN
-                : SpeedBumpDotsState.HIDDEN);
-        int hostWidth = hostView.getWidth();
-        float layoutWidth = hostWidth - 2 * mDotRadius;
-        int childCount = hostView.getChildCount();
-        float paddingBetween = layoutWidth / (childCount - 1);
-        float centerY = hostView.getHeight() / 2.0f;
-        for (int i = 0; i < childCount; i++) {
-            View child = hostView.getChildAt(i);
-            SpeedBumpDotsState.ViewState viewState = resultState.getViewStateForView(child);
-            if (currentlyVisible) {
-                float xTranslation = i * paddingBetween;
-                viewState.xTranslation = xTranslation;
-                viewState.yTranslation = calculateYTranslation(hostView, centerY, xTranslation,
-                        layoutWidth);
-            } else {
-                viewState.xTranslation = layoutWidth / 2;
-                viewState.yTranslation = centerY - mDotRadius;
-            }
-            viewState.alpha = currentlyVisible ? 1.0f : 0.0f;
-            viewState.scale = currentlyVisible ? 1.0f : 0.5f;
-        }
-    }
-
-    private float calculateYTranslation(SpeedBumpDotsLayout hostView, float centerY,
-            float xTranslation, float layoutWidth) {
-        float t = hostView.getAnimationProgress();
-        if (t == 0.0f || t == 1.0f) {
-            return centerY - mDotRadius;
-        }
-        float damping = (0.5f -Math.abs(0.5f - t)) * 1.3f;
-        float partialOffset = xTranslation / layoutWidth;
-        float indentFactor = (float) (Math.sin((t + partialOffset * 1.5f) * - Math.PI) * damping);
-        return (1.0f - indentFactor) * centerY - mDotRadius;
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java
deleted file mode 100644
index ddf5215..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsLayout.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.animation.TimeAnimator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import com.android.systemui.R;
-
-/**
- * A layout with a certain number of dots which are integrated in the
- * {@link com.android.systemui.statusbar.SpeedBumpView}
- */
-public class SpeedBumpDotsLayout extends ViewGroup {
-
-    private static final float DOT_CLICK_ANIMATION_LENGTH = 300;
-    private final int mDotSize;
-    private final SpeedBumpDotsAlgorithm mAlgorithm = new SpeedBumpDotsAlgorithm(getContext());
-    private final SpeedBumpDotsState mCurrentState = new SpeedBumpDotsState(this);
-    private boolean mIsCurrentlyVisible = true;
-    private final ValueAnimator mClickAnimator;
-    private float mAnimationProgress;
-    private ValueAnimator.AnimatorUpdateListener mClickUpdateListener
-            = new ValueAnimator.AnimatorUpdateListener() {
-        @Override
-        public void onAnimationUpdate(ValueAnimator animation) {
-            mAnimationProgress = animation.getAnimatedFraction();
-            updateChildren();
-        }
-    };
-
-    public SpeedBumpDotsLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mDotSize = getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height);
-        createDots(context, attrs);
-        mClickAnimator = TimeAnimator.ofFloat(0, DOT_CLICK_ANIMATION_LENGTH);
-        mClickAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
-        mClickAnimator.addUpdateListener(mClickUpdateListener);
-    }
-
-    private void createDots(Context context, AttributeSet attrs) {
-        SpeedBumpDotView blueDot = new SpeedBumpDotView(context, attrs);
-        blueDot.setColor(getResources().getColor(R.color.speed_bump_dot_blue));
-        addView(blueDot);
-
-        SpeedBumpDotView redDot = new SpeedBumpDotView(context, attrs);
-        redDot.setColor(getResources().getColor(R.color.speed_bump_dot_red));
-        addView(redDot);
-
-        SpeedBumpDotView yellowDot = new SpeedBumpDotView(context, attrs);
-        yellowDot.setColor(getResources().getColor(R.color.speed_bump_dot_yellow));
-        addView(yellowDot);
-
-        SpeedBumpDotView greenDot = new SpeedBumpDotView(context, attrs);
-        greenDot.setColor(getResources().getColor(R.color.speed_bump_dot_green));
-        addView(greenDot);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        int childWidthSpec = MeasureSpec.makeMeasureSpec(mDotSize,
-                MeasureSpec.getMode(widthMeasureSpec));
-        int childHeightSpec = MeasureSpec.makeMeasureSpec(mDotSize,
-                MeasureSpec.getMode(heightMeasureSpec));
-        measureChildren(childWidthSpec, childHeightSpec);
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View child = getChildAt(i);
-            child.layout(0, 0, mDotSize, mDotSize);
-        }
-        if (changed) {
-            updateChildren();
-        }
-    }
-
-    private void updateChildren() {
-        mAlgorithm.getState(mCurrentState);
-        mCurrentState.apply();
-    }
-
-    public void performVisibilityAnimation(boolean visible) {
-        if (mClickAnimator.isRunning()) {
-            mClickAnimator.cancel();
-        }
-        mIsCurrentlyVisible = visible;
-        mAlgorithm.getState(mCurrentState);
-        mCurrentState.animateToState();
-    }
-
-    public void setInvisible() {
-        mIsCurrentlyVisible = false;
-        mAlgorithm.getState(mCurrentState);
-        mCurrentState.apply();
-    }
-
-    public boolean isCurrentlyVisible() {
-        return mIsCurrentlyVisible;
-    }
-
-    public void performDotClickAnimation() {
-        if (mClickAnimator.isRunning()) {
-            // don't perform an animation if it's running already
-            return;
-        }
-        mClickAnimator.start();
-    }
-
-
-    public float getAnimationProgress() {
-        return mAnimationProgress;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java
deleted file mode 100644
index 4febab1..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpDotsState.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar;
-
-import android.view.View;
-import android.view.ViewPropertyAnimator;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A state of a {@link com.android.systemui.statusbar.SpeedBumpDotsLayout}
- */
-public class SpeedBumpDotsState {
-
-    public static final int HIDDEN = 1;
-    public static final int SHOWN = 2;
-    private static final int VISIBILITY_ANIMATION_DELAY_PER_ELEMENT = 80;
-
-    private final SpeedBumpDotsLayout mHostView;
-    private final HashMap<View, ViewState> mStateMap = new HashMap<View, ViewState>();
-    private final Interpolator mFastOutSlowInInterpolator;
-    private int mActiveState = 0;
-
-    public SpeedBumpDotsState(SpeedBumpDotsLayout hostLayout) {
-        mHostView = hostLayout;
-        mFastOutSlowInInterpolator = AnimationUtils
-                .loadInterpolator(hostLayout.getContext(),
-                        android.R.interpolator.fast_out_slow_in);
-    }
-
-    public SpeedBumpDotsLayout getHostView() {
-        return mHostView;
-    }
-
-    public void resetViewStates() {
-        int numChildren = mHostView.getChildCount();
-        for (int i = 0; i < numChildren; i++) {
-            View child = mHostView.getChildAt(i);
-            ViewState viewState = mStateMap.get(child);
-            if (viewState == null) {
-                viewState = new ViewState();
-                mStateMap.put(child, viewState);
-            }
-        }
-    }
-
-    public ViewState getViewStateForView(View requestedView) {
-        return mStateMap.get(requestedView);
-    }
-
-    public void apply() {
-        int childCount = mHostView.getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View child = mHostView.getChildAt(i);
-            ViewState viewState = mStateMap.get(child);
-
-            child.setTranslationX(viewState.xTranslation);
-            child.setTranslationY(viewState.yTranslation);
-            child.setScaleX(viewState.scale);
-            child.setScaleY(viewState.scale);
-            child.setAlpha(viewState.alpha);
-        }
-    }
-
-    public void animateToState() {
-        int childCount = mHostView.getChildCount();
-        int middleIndex = (childCount - 1) / 2;
-        long delayPerElement = VISIBILITY_ANIMATION_DELAY_PER_ELEMENT;
-        boolean isAppearing = getActiveState() == SHOWN;
-        boolean isDisappearing = getActiveState() == HIDDEN;
-        for (int i = 0; i < childCount; i++) {
-            int delayIndex;
-            if (i <= middleIndex) {
-                delayIndex = i * 2;
-            } else {
-                int distToMiddle = i - middleIndex;
-                delayIndex = (childCount - 1) - (distToMiddle - 1) * 2;
-            }
-            long startDelay = 0;
-            if (isAppearing || isDisappearing) {
-                if (isDisappearing) {
-                    delayIndex = childCount - 1 - delayIndex;
-                }
-                startDelay = delayIndex * delayPerElement;
-            }
-            View child = mHostView.getChildAt(i);
-            ViewState viewState = mStateMap.get(child);
-            child.animate().setInterpolator(mFastOutSlowInInterpolator)
-                    .setStartDelay(startDelay)
-                    .alpha(viewState.alpha)
-                    .translationX(viewState.xTranslation)
-                    .translationY(viewState.yTranslation)
-                    .scaleX(viewState.scale).scaleY(viewState.scale);
-        }
-    }
-
-    public int getActiveState() {
-        return mActiveState;
-    }
-
-    public void setActiveState(int mActiveState) {
-        this.mActiveState = mActiveState;
-    }
-
-    public static class ViewState {
-        float xTranslation;
-        float yTranslation;
-        float alpha;
-        float scale;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
index 689d0e9..f80f0fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
@@ -16,71 +16,26 @@
 
 package com.android.systemui.statusbar;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
 import android.content.Context;
-import android.graphics.Outline;
 import android.util.AttributeSet;
-import android.view.View;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
-import android.widget.TextView;
 import com.android.systemui.R;
 
 /**
  * The view representing the separation between important and less important notifications
  */
-public class SpeedBumpView extends ExpandableView implements View.OnClickListener {
+public class SpeedBumpView extends ExpandableView {
 
-    private final int mCollapsedHeight;
-    private final int mDotsHeight;
-    private final int mTextPaddingInset;
-    private SpeedBumpDotsLayout mDots;
-    private AlphaOptimizedView mLineLeft;
-    private AlphaOptimizedView mLineRight;
-    private boolean mIsExpanded;
-    private boolean mDividerVisible = true;
-    private ValueAnimator mCurrentAnimator;
+    private final int mSpeedBumpHeight;
+    private AlphaOptimizedView mLine;
+    private boolean mIsVisible = true;
     private final Interpolator mFastOutSlowInInterpolator;
-    private float mCenterX;
-    private TextView mExplanationText;
-    private boolean mExplanationTextVisible = false;
-    private AnimatorListenerAdapter mHideExplanationListener = new AnimatorListenerAdapter() {
-        private boolean mCancelled;
-
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            if (!mCancelled) {
-                mExplanationText.setVisibility(View.INVISIBLE);
-            }
-        }
-
-        @Override
-        public void onAnimationCancel(Animator animation) {
-            mCancelled = true;
-        }
-
-        @Override
-        public void onAnimationStart(Animator animation) {
-            mCancelled = false;
-        }
-    };
-    private Animator.AnimatorListener mAnimationFinishedListener = new AnimatorListenerAdapter() {
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            mCurrentAnimator = null;
-        }
-    };
 
     public SpeedBumpView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mCollapsedHeight = getResources()
-                .getDimensionPixelSize(R.dimen.speed_bump_height_collapsed);
-        mTextPaddingInset = getResources().getDimensionPixelSize(
-                R.dimen.speed_bump_text_padding_inset);
-        mDotsHeight = getResources().getDimensionPixelSize(R.dimen.speed_bump_dots_height);
-        setOnClickListener(this);
+        mSpeedBumpHeight = getResources()
+                .getDimensionPixelSize(R.dimen.speed_bump_height);
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
                 android.R.interpolator.fast_out_slow_in);
     }
@@ -88,111 +43,41 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mDots = (SpeedBumpDotsLayout) findViewById(R.id.speed_bump_dots_layout);
-        mLineLeft = (AlphaOptimizedView) findViewById(R.id.speedbump_line_left);
-        mLineRight = (AlphaOptimizedView) findViewById(R.id.speedbump_line_right);
-        mExplanationText = (TextView) findViewById(R.id.speed_bump_text);
-        resetExplanationText();
-
+        mLine = (AlphaOptimizedView) findViewById(R.id.speedbump_line);
     }
 
     @Override
     protected int getInitialHeight() {
-        return mCollapsedHeight;
+        return mSpeedBumpHeight;
     }
 
     @Override
     public int getIntrinsicHeight() {
-        if (mCurrentAnimator != null) {
-            // expand animation is running
-            return getActualHeight();
-        }
-        return mIsExpanded ? getHeight() : mCollapsedHeight;
+        return mSpeedBumpHeight;
     }
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
-        Outline outline = new Outline();
-        mCenterX = getWidth() / 2;
-        float centerY = getHeight() / 2;
-        // TODO: hide outline better
-        // Temporary workaround to hide outline on a transparent view
-        int outlineLeft = (int) (mCenterX - getResources().getDisplayMetrics().densityDpi * 8);
-        int outlineTop = (int) (centerY - mDotsHeight / 2);
-        outline.setOval(outlineLeft, outlineTop, outlineLeft + mDotsHeight,
-                outlineTop + mDotsHeight);
-        setOutline(outline);
-        mLineLeft.setPivotX(mLineLeft.getWidth());
-        mLineLeft.setPivotY(mLineLeft.getHeight() / 2);
-        mLineRight.setPivotX(0);
-        mLineRight.setPivotY(mLineRight.getHeight() / 2);
+        mLine.setPivotX(mLine.getWidth() / 2);
+        mLine.setPivotY(mLine.getHeight() / 2);
+        setOutline(null);
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         measureChildren(widthMeasureSpec, heightMeasureSpec);
-        int height = mCollapsedHeight + mExplanationText.getMeasuredHeight() - mTextPaddingInset;
+        int height = mSpeedBumpHeight;
         setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height);
     }
 
     @Override
-    public void onClick(View v) {
-        if (mCurrentAnimator != null) {
-            return;
-        }
-        int startValue = mIsExpanded ? getMaxHeight() : mCollapsedHeight;
-        int endValue = mIsExpanded ? mCollapsedHeight : getMaxHeight();
-        mCurrentAnimator = ValueAnimator.ofInt(startValue, endValue);
-        mCurrentAnimator.setInterpolator(mFastOutSlowInInterpolator);
-        mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                setActualHeight((int) animation.getAnimatedValue());
-            }
-        });
-        mCurrentAnimator.addListener(mAnimationFinishedListener);
-        mCurrentAnimator.start();
-        mIsExpanded = !mIsExpanded;
-        mDots.performDotClickAnimation();
-        animateExplanationTextInternal(mIsExpanded);
-    }
-
-    private void animateExplanationTextInternal(boolean visible) {
-        if (mExplanationTextVisible != visible) {
-            float translationY = 0.0f;
-            float scale = 0.5f;
-            float alpha = 0.0f;
-            boolean needsHideListener = true;
-            if (visible) {
-                mExplanationText.setVisibility(VISIBLE);
-                translationY = mDots.getBottom() - mTextPaddingInset;
-                scale = 1.0f;
-                alpha = 1.0f;
-                needsHideListener = false;
-            }
-            mExplanationText.animate().setInterpolator(mFastOutSlowInInterpolator)
-                    .alpha(alpha)
-                    .scaleX(scale)
-                    .scaleY(scale)
-                    .translationY(translationY)
-                    .setListener(needsHideListener ? mHideExplanationListener : null);
-            mExplanationTextVisible = visible;
-        }
-    }
-
-    @Override
     public boolean isTransparent() {
         return true;
     }
 
     public void performVisibilityAnimation(boolean nowVisible) {
         animateDivider(nowVisible, null /* onFinishedRunnable */);
-
-        // Animate explanation Text
-        if (mIsExpanded) {
-            animateExplanationTextInternal(nowVisible);
-        }
     }
 
     /**
@@ -203,28 +88,16 @@
      *        finished.
      */
     public void animateDivider(boolean nowVisible, Runnable onFinishedRunnable) {
-        if (nowVisible != mDividerVisible) {
+        if (nowVisible != mIsVisible) {
             // Animate dividers
             float endValue = nowVisible ? 1.0f : 0.0f;
-            float endTranslationXLeft = nowVisible ? 0.0f : mCenterX - mLineLeft.getRight();
-            float endTranslationXRight = nowVisible ? 0.0f : mCenterX - mLineRight.getLeft();
-            mLineLeft.animate()
+            mLine.animate()
                     .alpha(endValue)
                     .scaleX(endValue)
                     .scaleY(endValue)
-                    .translationX(endTranslationXLeft)
                     .setInterpolator(mFastOutSlowInInterpolator)
                     .withEndAction(onFinishedRunnable);
-            mLineRight.animate()
-                    .alpha(endValue)
-                    .scaleX(endValue)
-                    .scaleY(endValue)
-                    .translationX(endTranslationXRight)
-                    .setInterpolator(mFastOutSlowInInterpolator);
-
-            // Animate dots
-            mDots.performVisibilityAnimation(nowVisible);
-            mDividerVisible = nowVisible;
+            mIsVisible = nowVisible;
         } else {
             if (onFinishedRunnable != null) {
                 onFinishedRunnable.run();
@@ -233,34 +106,10 @@
     }
 
     public void setInvisible() {
-        float endTranslationXLeft = mCenterX - mLineLeft.getRight();
-        float endTranslationXRight = mCenterX - mLineRight.getLeft();
-        mLineLeft.setAlpha(0.0f);
-        mLineLeft.setScaleX(0.0f);
-        mLineLeft.setScaleY(0.0f);
-        mLineLeft.setTranslationX(endTranslationXLeft);
-        mLineRight.setAlpha(0.0f);
-        mLineRight.setScaleX(0.0f);
-        mLineRight.setScaleY(0.0f);
-        mLineRight.setTranslationX(endTranslationXRight);
-        mDots.setInvisible();
-        resetExplanationText();
-
-        mDividerVisible = false;
-    }
-
-    public void collapse() {
-        if (mIsExpanded) {
-            setActualHeight(mCollapsedHeight);
-            mIsExpanded = false;
-        }
-        resetExplanationText();
-    }
-
-    public void animateExplanationText(boolean nowVisible) {
-        if (mIsExpanded) {
-            animateExplanationTextInternal(nowVisible);
-        }
+        mLine.setAlpha(0.0f);
+        mLine.setScaleX(0.0f);
+        mLine.setScaleY(0.0f);
+        mIsVisible = false;
     }
 
     @Override
@@ -272,17 +121,4 @@
     public void performAddAnimation(long delay) {
         performVisibilityAnimation(true);
     }
-
-    private void resetExplanationText() {
-        mExplanationText.setTranslationY(0);
-        mExplanationText.setVisibility(INVISIBLE);
-        mExplanationText.setAlpha(0.0f);
-        mExplanationText.setScaleX(0.5f);
-        mExplanationText.setScaleY(0.5f);
-        mExplanationTextVisible = false;
-    }
-
-    public boolean isExpanded() {
-        return mIsExpanded;
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
index e312d58..ca49408 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
@@ -246,7 +246,9 @@
     private void startHintTranslationAnimations(float target, long duration,
             Interpolator interpolator) {
         ArrayList<View> targetViews = mCallback.getTranslationViews();
-        for (View targetView : targetViews) {
+        int length = targetViews.size();
+        for (int i = 0; i < length; i++) {
+            View targetView = targetViews.get(i);
             targetView.animate()
                     .setDuration(duration)
                     .setInterpolator(interpolator)
@@ -259,8 +261,16 @@
     }
 
     private void cancelAnimations() {
-        ArrayList<View> targetViews = mCallback.getTranslationViews();
-        for (View target : targetViews) {
+        ArrayList<View> translatingViews = mCallback.getTranslationViews();
+        int length = translatingViews.size();
+        for (int i = 0; i < length; i++) {
+            View target = translatingViews.get(i);
+            target.animate().cancel();
+        }
+        ArrayList<View> fadingViews = mCallback.getFadingViews();
+        length = fadingViews.size();
+        for (int i = 0; i < length; i++) {
+            View target = fadingViews.get(i);
             target.animate().cancel();
         }
         View targetView = mTranslation > 0 ? mLeftIcon : mRightIcon;
@@ -291,6 +301,11 @@
         // translation Animation
         startTranslationAnimations(vel, target);
 
+        // fade animations
+        if (snapBack) {
+            startFadeInAnimations();
+        }
+
         // animate left / right icon
         startIconAnimation(vel, snapBack, target);
 
@@ -346,9 +361,20 @@
         mSwipeAnimator = animator;
     }
 
+    private void startFadeInAnimations() {
+        ArrayList<View> fadingViews = mCallback.getFadingViews();
+        int length = fadingViews.size();
+        for (int i = 0; i < length; i++) {
+            View targetView = fadingViews.get(i);
+            targetView.animate().alpha(1.0f);
+        }
+    }
+
     private void startTranslationAnimations(float vel, float target) {
         ArrayList<View> targetViews = mCallback.getTranslationViews();
-        for (View targetView : targetViews) {
+        int length = targetViews.size();
+        for (int i = 0; i < length; i++) {
+            View targetView = targetViews.get(i);
             ViewPropertyAnimator animator = targetView.animate();
             mFlingAnimationUtils.apply(animator, mTranslation, target, vel);
             animator.translationX(target);
@@ -375,8 +401,18 @@
         translation = leftSwipePossible() ? translation : Math.min(0, translation);
         if (translation != mTranslation || isReset) {
             ArrayList<View> translatedViews = mCallback.getTranslationViews();
-            for (View view : translatedViews) {
-                view.setTranslationX(translation);
+            int length = translatedViews.size();
+            for (int i = 0; i < length; i++) {
+                View target = translatedViews.get(i);
+                target.setTranslationX(translation);
+            }
+            float targetAlpha = 1.0f - Math.abs(translation / mMinTranslationAmount);
+            targetAlpha = Math.max(0.0f, targetAlpha);
+            ArrayList<View> fadingViews = mCallback.getFadingViews();
+            length = fadingViews.size();
+            for (int i = 0; i < length; i++) {
+                View view = fadingViews.get(i);
+                view.setAlpha(targetAlpha);
             }
             if (translation == 0.0f) {
                 boolean animate = !isReset;
@@ -494,6 +530,8 @@
 
         ArrayList<View> getTranslationViews();
 
+        ArrayList<View> getFadingViews();
+
         View getLeftIcon();
 
         View getCenterIcon();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 45d208e..5c686fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -108,6 +108,7 @@
     private KeyguardBottomAreaView mKeyguardBottomArea;
     private boolean mBlockTouches;
     private ArrayList<View> mSwipeTranslationViews = new ArrayList<>();
+    private ArrayList<View> mSwipeFadingViews = new ArrayList<>();
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -152,7 +153,7 @@
                 android.R.interpolator.fast_out_linear_in);
         mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
         mSwipeTranslationViews.add(mNotificationStackScroller);
-        mSwipeTranslationViews.add(mKeyguardStatusView);
+        mSwipeFadingViews.add(mKeyguardStatusView);
         mPageSwiper = new KeyguardPageSwipeHelper(this, getContext());
     }
 
@@ -963,6 +964,11 @@
     }
 
     @Override
+    public ArrayList<View> getFadingViews() {
+        return mSwipeFadingViews;
+    }
+
+    @Override
     public View getLeftIcon() {
         return getLayoutDirection() == LAYOUT_DIRECTION_RTL
                 ? mKeyguardBottomArea.getCameraImageView()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index d7b1d35..d413f63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -64,7 +64,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.Global;
-import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
@@ -103,6 +103,7 @@
 import com.android.systemui.qs.CircularClipper;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DragDownHelper;
@@ -278,10 +279,6 @@
     // the date view
     DateView mDateView;
 
-    // for heads up notifications
-    private HeadsUpNotificationView mHeadsUpNotificationView;
-    private int mHeadsUpNotificationDecay;
-
     // on-screen navigation buttons
     private NavigationBarView mNavigationBarView = null;
     private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
@@ -367,7 +364,7 @@
                 if (!mUseHeadsUp) {
                     Log.d(TAG, "dismissing any existing heads up notification on disable event");
                     setHeadsUpVisibility(false);
-                    mHeadsUpNotificationView.setNotification(null);
+                    mHeadsUpNotificationView.release();
                     removeHeadsUpView();
                 } else {
                     addHeadsUpView();
@@ -1067,7 +1064,7 @@
     }
 
     @Override
-    public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+    public void addNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
         if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
         if (mZenMode != Global.ZEN_MODE_OFF && mIntercepted.tryIntercept(notification, ranking)) {
             // Forward the ranking so we can sort the new notification.
@@ -1078,31 +1075,28 @@
         displayNotification(notification, ranking);
     }
 
-    public void displayNotification(StatusBarNotification notification,
-            Ranking ranking) {
-        Entry shadeEntry = createNotificationViews(notification);
-        if (shadeEntry == null) {
-            return;
-        }
+    public void displayNotification(StatusBarNotification notification, RankingMap ranking) {
         if (mUseHeadsUp && shouldInterrupt(notification)) {
             if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
             Entry interruptionCandidate = new Entry(notification, null);
             ViewGroup holder = mHeadsUpNotificationView.getHolder();
             if (inflateViewsForHeadsUp(interruptionCandidate, holder)) {
                 mInterruptingNotificationTime = System.currentTimeMillis();
-                mInterruptingNotificationEntry = interruptionCandidate;
-                shadeEntry.setInterruption();
 
                 // 1. Populate mHeadsUpNotificationView
-                mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
+                mHeadsUpNotificationView.showNotification(interruptionCandidate);
 
-                // 2. Animate mHeadsUpNotificationView in
-                mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
-
-                // 3. Set alarm to age the notification off
-                resetHeadsUpDecayTimer();
+                // do not show the notification in the shade, yet.
+                return;
             }
-        } else if (notification.getNotification().fullScreenIntent != null) {
+        }
+
+        Entry shadeEntry = createNotificationViews(notification);
+        if (shadeEntry == null) {
+            return;
+        }
+
+        if (notification.getNotification().fullScreenIntent != null) {
             // Stop screensaver if the notification has a full-screen intent.
             // (like an incoming phone call)
             awakenDreams();
@@ -1117,7 +1111,7 @@
             // usual case: status bar visible & not immersive
 
             // show the ticker if there isn't already a heads up
-            if (mInterruptingNotificationEntry == null) {
+            if (mHeadsUpNotificationView.getEntry() == null) {
                 tick(notification, true);
             }
         }
@@ -1127,31 +1121,64 @@
         updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
     }
 
+    public void displayNotificationFromHeadsUp(StatusBarNotification notification) {
+        NotificationData.Entry shadeEntry = createNotificationViews(notification);
+        if (shadeEntry == null) {
+            return;
+        }
+        shadeEntry.setInterruption();
+
+        addNotificationViews(shadeEntry, null);
+        // Recalculate the position of the sliding windows and the titles.
+        setAreThereNotifications();
+        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+    }
+
     @Override
     public void resetHeadsUpDecayTimer() {
-        mHandler.removeMessages(MSG_HIDE_HEADS_UP);
+        mHandler.removeMessages(MSG_DECAY_HEADS_UP);
         if (mUseHeadsUp && mHeadsUpNotificationDecay > 0
                 && mHeadsUpNotificationView.isClearable()) {
-            mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, mHeadsUpNotificationDecay);
+            mHandler.sendEmptyMessageDelayed(MSG_DECAY_HEADS_UP, mHeadsUpNotificationDecay);
         }
     }
 
     @Override
-    public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+    public void scheduleHeadsUpOpen() {
+        mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
+    }
+
+    @Override
+    public void scheduleHeadsUpClose() {
+        mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+    }
+
+    @Override
+    public void scheduleHeadsUpEscalation() {
+        mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP);
+    }
+
+    @Override
+    public void updateNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
         super.updateNotificationInternal(notification, ranking);
         // if we're here, then the notification is already in the shade
         mIntercepted.remove(notification.getKey());
     }
 
     @Override
-    protected void updateRankingInternal(Ranking ranking) {
+    protected void updateRankingInternal(RankingMap ranking) {
         mNotificationData.updateRanking(ranking);
         mIntercepted.retryIntercepts(ranking);
         updateNotifications();
     }
 
     @Override
-    public void removeNotificationInternal(String key, Ranking ranking) {
+    public void removeNotificationInternal(String key, RankingMap ranking) {
+        if (ENABLE_HEADS_UP && mHeadsUpNotificationView.getEntry() != null
+                && key.equals(mHeadsUpNotificationView.getEntry().notification.getKey())) {
+            mHeadsUpNotificationView.clear();
+        }
+
         StatusBarNotification old = removeNotificationViews(key, ranking);
         if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
 
@@ -1164,11 +1191,6 @@
             // Recalculate the position of the sliding windows and the titles.
             updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
 
-            if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null
-                    && old == mInterruptingNotificationEntry.notification) {
-                mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
-            }
-
             if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0
                     && !mNotificationPanel.isTracking() && mState != StatusBarState.KEYGUARD) {
                 animateCollapsePanels();
@@ -1590,7 +1612,12 @@
                 case MSG_SHOW_HEADS_UP:
                     setHeadsUpVisibility(true);
                     break;
+                case MSG_DECAY_HEADS_UP:
+                    mHeadsUpNotificationView.release();
+                    setHeadsUpVisibility(false);
+                    break;
                 case MSG_HIDE_HEADS_UP:
+                    mHeadsUpNotificationView.release();
                     setHeadsUpVisibility(false);
                     break;
                 case MSG_ESCALATE_HEADS_UP:
@@ -1603,8 +1630,9 @@
 
     /**  if the interrupting notification had a fullscreen intent, fire it now.  */
     private void escalateHeadsUp() {
-        if (mInterruptingNotificationEntry != null) {
-            final StatusBarNotification sbn = mInterruptingNotificationEntry.notification;
+        if (mHeadsUpNotificationView.getEntry() != null) {
+            final StatusBarNotification sbn = mHeadsUpNotificationView.getEntry().notification;
+            mHeadsUpNotificationView.release();
             final Notification notification = sbn.getNotification();
             if (notification.fullScreenIntent != null) {
                 if (DEBUG)
@@ -2259,7 +2287,7 @@
         pw.print("  mUseHeadsUp=");
         pw.println(mUseHeadsUp);
         pw.print("  interrupting package: ");
-        pw.println(hunStateToString(mInterruptingNotificationEntry));
+        pw.println(hunStateToString(mHeadsUpNotificationView.getEntry()));
         dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
         if (mNavigationBarView != null) {
             pw.print("  mNavigationBarWindowState=");
@@ -2533,26 +2561,10 @@
         if (!ENABLE_HEADS_UP) return;
         if (DEBUG) Log.v(TAG, (vis ? "showing" : "hiding") + " heads up window");
         mHeadsUpNotificationView.setVisibility(vis ? View.VISIBLE : View.GONE);
-        if (!vis) {
-            if (DEBUG) Log.d(TAG, "setting heads up entry to null");
-            mInterruptingNotificationEntry = null;
-        }
     }
 
     public void onHeadsUpDismissed() {
-        if (mInterruptingNotificationEntry == null) return;
-        mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
-        if (mHeadsUpNotificationView.isClearable()) {
-            try {
-                mBarService.onNotificationClear(
-                        mInterruptingNotificationEntry.notification.getPackageName(),
-                        mInterruptingNotificationEntry.notification.getTag(),
-                        mInterruptingNotificationEntry.notification.getId(),
-                        mInterruptingNotificationEntry.notification.getUserId());
-            } catch (android.os.RemoteException ex) {
-                // oh well
-            }
-        }
+        mHeadsUpNotificationView.dismiss();
     }
 
     /**
@@ -2921,7 +2933,6 @@
             mNotificationPanel.setKeyguardShowing(false);
             mScrimController.setKeyguardShowing(false);
         }
-
         updateStackScrollerState();
         updatePublicMode();
         updateNotifications();
@@ -2937,6 +2948,11 @@
                 ? View.INVISIBLE : View.VISIBLE);
         mStackScroller.setScrollingEnabled(!onKeyguard);
         mStackScroller.setExpandingEnabled(!onKeyguard);
+        ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
+        mStackScroller.setActivatedChild(null);
+        if (activatedChild != null) {
+            activatedChild.makeInactive(false /* animate */);
+        }
     }
 
     public void userActivity() {
@@ -2980,9 +2996,13 @@
     }
 
     @Override
-    public void onActivated(View view) {
+    public void onActivated(ActivatableNotificationView view) {
         userActivity();
         mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
+        ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
+        if (previousView != null) {
+            previousView.makeInactive(true /* animate */);
+        }
         mStackScroller.setActivatedChild(view);
     }
 
@@ -2995,7 +3015,7 @@
     }
 
     @Override
-    public void onActivationReset(View view) {
+    public void onActivationReset(ActivatableNotificationView view) {
         if (view == mStackScroller.getActivatedChild()) {
             mKeyguardIndicationController.hideTransientIndication();
             mStackScroller.setActivatedChild(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index df01c12..d778ccb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -33,9 +33,9 @@
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
-import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
 
 public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.Callback, ExpandHelper.Callback,
         ViewTreeObserver.OnComputeInternalInsetsListener {
@@ -51,7 +51,7 @@
     private SwipeHelper mSwipeHelper;
     private EdgeSwipeHelper mEdgeSwipeHelper;
 
-    private BaseStatusBar mBar;
+    private PhoneStatusBar mBar;
     private ExpandHelper mExpandHelper;
 
     private long mStartTouchTime;
@@ -69,7 +69,7 @@
         if (DEBUG) Log.v(TAG, "create() " + mTouchSensitivityDelay);
     }
 
-    public void setBar(BaseStatusBar bar) {
+    public void setBar(PhoneStatusBar bar) {
         mBar = bar;
     }
 
@@ -77,7 +77,10 @@
         return mContentHolder;
     }
 
-    public boolean setNotification(NotificationData.Entry headsUp) {
+    public boolean showNotification(NotificationData.Entry headsUp) {
+        // bump any previous heads up back to the shade
+        release();
+
         mHeadsUp = headsUp;
         if (mContentHolder != null) {
             mContentHolder.removeAllViews();
@@ -97,10 +100,46 @@
 
             mSwipeHelper.snapChild(mContentHolder, 1f);
             mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
+
+            // 2. Animate mHeadsUpNotificationView in
+            mBar.scheduleHeadsUpOpen();
+
+            // 3. Set alarm to age the notification off
+            mBar.resetHeadsUpDecayTimer();
         }
         return true;
     }
 
+    /** Discard the Heads Up notification. */
+    public void clear() {
+        mHeadsUp = null;
+        mBar.scheduleHeadsUpClose();
+    }
+
+    /** Respond to dismissal of the Heads Up window. */
+    public void dismiss() {
+        if (mHeadsUp == null) return;
+        if (mHeadsUp.notification.isClearable()) {
+            mBar.onNotificationClear(mHeadsUp.notification);
+        } else {
+            release();
+        }
+        mHeadsUp = null;
+        mBar.scheduleHeadsUpClose();
+    }
+
+    /** Push any current Heads Up notification down into the shade. */
+    public void release() {
+        if (mHeadsUp != null) {
+            mBar.displayNotificationFromHeadsUp(mHeadsUp.notification);
+        }
+        mHeadsUp = null;
+    }
+
+    public NotificationData.Entry getEntry() {
+        return mHeadsUp;
+    }
+
     public boolean isClearable() {
         return mHeadsUp == null || mHeadsUp.notification.isClearable();
     }
@@ -125,7 +164,7 @@
 
         if (mHeadsUp != null) {
             // whoops, we're on already!
-            setNotification(mHeadsUp);
+            showNotification(mHeadsUp);
         }
 
         getViewTreeObserver().addOnComputeInternalInsetsListener(this);
@@ -282,6 +321,10 @@
                 mTmpTwoArray[1] + mContentHolder.getHeight());
     }
 
+    public void escalate() {
+        mBar.scheduleHeadsUpEscalation();
+    }
+
     private class EdgeSwipeHelper implements Gefingerpoken {
         private static final boolean DEBUG_EDGE_SWIPE = false;
         private final float mTouchSlop;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index dc8f315..1f68860 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -30,7 +30,7 @@
         void onMobileDataSignalChanged(boolean enabled, int mobileSignalIconId,
                 String mobileSignalContentDescriptionId, int dataTypeIconId,
                 boolean activityIn, boolean activityOut,
-                String dataTypeContentDescriptionId, String description);
+                String dataTypeContentDescriptionId, String description, boolean noSim);
         void onAirplaneModeChanged(boolean enabled);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 56402a5..254a0e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -87,6 +87,7 @@
     int mQSDataTypeIconId;
     int mAirplaneIconId;
     boolean mDataActive;
+    boolean mNoSim;
     int mLastSignalLevel;
     boolean mShowPhoneRSSIForData = false;
     boolean mShowAtLeastThreeGees = false;
@@ -349,18 +350,18 @@
         if (isEmergencyOnly()) {
             cb.onMobileDataSignalChanged(false, mQSPhoneSignalIconId,
                     mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                    mContentDescriptionDataType, null);
+                    mContentDescriptionDataType, null, mNoSim);
         } else {
             if (mIsWimaxEnabled && mWimaxConnected) {
                 // Wimax is special
                 cb.onMobileDataSignalChanged(true, mQSPhoneSignalIconId,
                         mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                        mContentDescriptionDataType, mNetworkName);
+                        mContentDescriptionDataType, mNetworkName, mNoSim);
             } else {
                 // Normal mobile data
                 cb.onMobileDataSignalChanged(mHasMobileDataFeature, mQSPhoneSignalIconId,
                         mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
-                        mContentDescriptionDataType, mNetworkName);
+                        mContentDescriptionDataType, mNetworkName, mNoSim);
             }
         }
         cb.onAirplaneModeChanged(mAirplaneMode);
@@ -736,6 +737,7 @@
             // GSM case, we have to check also the sim state
             if (mSimState == IccCardConstants.State.READY ||
                     mSimState == IccCardConstants.State.UNKNOWN) {
+                mNoSim = false;
                 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
                     switch (mDataActivity) {
                         case TelephonyManager.DATA_ACTIVITY_IN:
@@ -758,6 +760,7 @@
                 }
             } else {
                 iconId = R.drawable.stat_sys_no_sim;
+                mNoSim = true;
                 visible = false; // no SIM? no data
             }
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index b21e12c..6d92b05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.stack;
 
 import android.view.View;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 
 import java.util.ArrayList;
 
@@ -27,7 +28,7 @@
     private ArrayList<View> mDraggedViews = new ArrayList<View>();
     private int mScrollY;
     private boolean mDimmed;
-    private View mActivatedChild;
+    private ActivatableNotificationView mActivatedChild;
     private float mOverScrollTopAmount;
     private float mOverScrollBottomAmount;
     private int mSpeedBumpIndex = -1;
@@ -64,7 +65,7 @@
      * In dimmed mode, a child can be activated, which happens on the first tap of the double-tap
      * interaction. This child is then scaled normally and its background is fully opaque.
      */
-    public void setActivatedChild(View activatedChild) {
+    public void setActivatedChild(ActivatableNotificationView activatedChild) {
         mActivatedChild = activatedChild;
     }
 
@@ -72,7 +73,7 @@
         return mDimmed;
     }
 
-    public View getActivatedChild() {
+    public ActivatableNotificationView getActivatedChild() {
         return mActivatedChild;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 5ace89f..94472a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -33,6 +33,7 @@
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.SpeedBumpView;
@@ -1722,7 +1723,6 @@
         mStackScrollAlgorithm.setIsExpanded(isExpanded);
         if (!isExpanded) {
             mOwnScrollY = 0;
-            mSpeedBumpView.collapse();
         }
     }
 
@@ -1760,7 +1760,7 @@
     /**
      * See {@link AmbientState#setActivatedChild}.
      */
-    public void setActivatedChild(View activatedChild) {
+    public void setActivatedChild(ActivatableNotificationView activatedChild) {
         mAmbientState.setActivatedChild(activatedChild);
         if (mAnimationsEnabled) {
             mActivateNeedsAnimation = true;
@@ -1769,7 +1769,7 @@
         requestChildrenUpdate();
     }
 
-    public View getActivatedChild() {
+    public ActivatableNotificationView getActivatedChild() {
         return mAmbientState.getActivatedChild();
     }
 
@@ -1791,7 +1791,6 @@
             int newVisibility = visible ? VISIBLE : GONE;
             mSpeedBumpView.setVisibility(newVisibility);
             if (visible) {
-                mSpeedBumpView.collapse();
                 // Make invisible to ensure that the appear animation is played.
                 mSpeedBumpView.setInvisible();
                 if (!mIsExpansionChanging) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index 94cb16d..1ad4acc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -160,9 +160,8 @@
                 }
 
                 if(child instanceof SpeedBumpView) {
-                    float speedBumpEnd = newYTranslation + newHeight;
-                    performSpeedBumpAnimation(i, (SpeedBumpView) child, speedBumpEnd,
-                            newYTranslation);
+                    float lineEnd = newYTranslation + newHeight / 2;
+                    performSpeedBumpAnimation(i, (SpeedBumpView) child, lineEnd);
                 }
             }
         }
@@ -183,20 +182,12 @@
         child.setClipBounds(mClipRect);
     }
 
-    private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd,
-            float speedBumpStart) {
+    private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd) {
         View nextChild = getNextChildNotGone(i);
         if (nextChild != null) {
             ViewState nextState = getViewStateForView(nextChild);
-            boolean startIsAboveNext = nextState.yTranslation > speedBumpStart;
+            boolean startIsAboveNext = nextState.yTranslation > speedBumpEnd;
             speedBump.animateDivider(startIsAboveNext, null /* onFinishedRunnable */);
-
-            // handle expanded case
-            if (speedBump.isExpanded()) {
-                boolean endIsAboveNext = nextState.yTranslation > speedBumpEnd;
-                speedBump.animateExplanationText(endIsAboveNext);
-            }
-
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index faea8de..9260aac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -17,14 +17,14 @@
 package com.android.systemui.statusbar.tv;
 
 import android.os.IBinder;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.BaseStatusBar;
 
 /*
@@ -51,11 +51,11 @@
     }
 
     @Override
-    public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+    public void addNotificationInternal(StatusBarNotification notification, RankingMap ranking) {
     }
 
     @Override
-    protected void updateRankingInternal(Ranking ranking) {
+    protected void updateRankingInternal(RankingMap ranking) {
     }
 
     @Override
@@ -63,7 +63,7 @@
     }
 
     @Override
-    public void removeNotificationInternal(String key, Ranking ranking) {
+    public void removeNotificationInternal(String key, RankingMap ranking) {
     }
 
     @Override
@@ -147,6 +147,18 @@
     }
 
     @Override
+    public void scheduleHeadsUpOpen() {
+    }
+
+    @Override
+    public void scheduleHeadsUpEscalation() {
+    }
+
+    @Override
+    public void scheduleHeadsUpClose() {
+    }
+
+    @Override
     protected int getMaxKeyguardNotifications() {
         return 0;
     }
@@ -164,10 +176,10 @@
     }
 
     @Override
-    public void onActivated(View view) {
+    public void onActivated(ActivatableNotificationView view) {
     }
 
     @Override
-    public void onActivationReset(View view) {
+    public void onActivationReset(ActivatableNotificationView view) {
     }
 }
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index fe5c2ef..aeb195f 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.database.ContentObserver;
 import android.os.BatteryStats;
 import com.android.internal.app.IBatteryStats;
 import com.android.server.am.BatteryStatsService;
@@ -149,8 +150,8 @@
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
         mLowBatteryWarningLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_lowBatteryWarningLevel);
-        mLowBatteryCloseWarningLevel = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);
+        mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
         mShutdownBatteryTemperature = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_shutdownBatteryTemperature);
 
@@ -173,11 +174,39 @@
     void systemReady() {
         // check our power situation now that it is safe to display the shutdown dialog.
         synchronized (mLock) {
-            shutdownIfNoPowerLocked();
-            shutdownIfOverTempLocked();
+            ContentObserver obs = new ContentObserver(mHandler) {
+                @Override
+                public void onChange(boolean selfChange) {
+                    synchronized (mLock) {
+                        updateBatteryWarningLevelLocked();
+                    }
+                }
+            };
+            final ContentResolver resolver = mContext.getContentResolver();
+            resolver.registerContentObserver(Settings.Global.getUriFor(
+                    Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
+                    false, obs, UserHandle.USER_ALL);
+            updateBatteryWarningLevelLocked();
         }
     }
 
+    void updateBatteryWarningLevelLocked() {
+        final ContentResolver resolver = mContext.getContentResolver();
+        int defWarnLevel = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_lowBatteryWarningLevel);
+        mLowBatteryWarningLevel = Settings.Global.getInt(resolver,
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);
+        if (mLowBatteryWarningLevel == 0) {
+            mLowBatteryWarningLevel = defWarnLevel;
+        }
+        if (mLowBatteryWarningLevel < mCriticalBatteryLevel) {
+            mLowBatteryWarningLevel = mCriticalBatteryLevel;
+        }
+        mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
+        processValuesLocked(true);
+    }
+
     /**
      * Returns true if the device is plugged into any of the specified plug types.
      */
@@ -232,7 +261,7 @@
         }
     }
 
-    public boolean isBatteryLowLocked() {
+    public boolean shouldSendBatteryLowLocked() {
         final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE;
         final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE;
 
@@ -299,14 +328,14 @@
             if (!mUpdatesStopped) {
                 mBatteryProps = props;
                 // Process the new values.
-                processValuesLocked();
+                processValuesLocked(false);
             } else {
                 mLastBatteryProps.set(props);
             }
         }
     }
 
-    private void processValuesLocked() {
+    private void processValuesLocked(boolean force) {
         boolean logOutlier = false;
         long dischargeDuration = 0;
 
@@ -349,14 +378,14 @@
         shutdownIfNoPowerLocked();
         shutdownIfOverTempLocked();
 
-        if (mBatteryProps.batteryStatus != mLastBatteryStatus ||
+        if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus ||
                 mBatteryProps.batteryHealth != mLastBatteryHealth ||
                 mBatteryProps.batteryPresent != mLastBatteryPresent ||
                 mBatteryProps.batteryLevel != mLastBatteryLevel ||
                 mPlugType != mLastPlugType ||
                 mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
                 mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
-                mInvalidCharger != mLastInvalidCharger) {
+                mInvalidCharger != mLastInvalidCharger)) {
 
             if (mPlugType != mLastPlugType) {
                 if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -400,7 +429,24 @@
                 logOutlier = true;
             }
 
-            mBatteryLevelLow = isBatteryLowLocked();
+            if (!mBatteryLevelLow) {
+                // Should we now switch in to low battery mode?
+                if (mPlugType == BATTERY_PLUGGED_NONE
+                        && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel) {
+                    mBatteryLevelLow = true;
+                }
+            } else {
+                // Should we now switch out of low battery mode?
+                if (mPlugType != BATTERY_PLUGGED_NONE) {
+                    mBatteryLevelLow = false;
+                } else if (mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel)  {
+                    mBatteryLevelLow = false;
+                } else if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) {
+                    // If being forced, the previous state doesn't matter, we will just
+                    // absolutely check to see if we are now above the warning level.
+                    mBatteryLevelLow = false;
+                }
+            }
 
             sendIntentLocked();
 
@@ -428,7 +474,7 @@
                 });
             }
 
-            if (mBatteryLevelLow) {
+            if (shouldSendBatteryLowLocked()) {
                 mSentLowBatteryBroadcast = true;
                 mHandler.post(new Runnable() {
                     @Override
@@ -650,7 +696,7 @@
                         long ident = Binder.clearCallingIdentity();
                         try {
                             mUpdatesStopped = true;
-                            processValuesLocked();
+                            processValuesLocked(false);
                         } finally {
                             Binder.restoreCallingIdentity(ident);
                         }
@@ -664,7 +710,7 @@
                     if (mUpdatesStopped) {
                         mUpdatesStopped = false;
                         mBatteryProps.set(mLastBatteryProps);
-                        processValuesLocked();
+                        processValuesLocked(false);
                     }
                 } finally {
                     Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index bd45761..f66f7ac 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -630,8 +630,8 @@
         if (DBG) log("ConnectivityService starting up");
 
         NetworkCapabilities netCap = new NetworkCapabilities();
-        netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
         mDefaultRequest = new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId());
         NetworkRequestInfo nri = new NetworkRequestInfo(null, mDefaultRequest, new Binder(),
                 NetworkRequestInfo.REQUEST);
@@ -1669,7 +1669,7 @@
                         continue;
                     }
 
-                    int prefix = destination.getNetworkPrefixLength();
+                    int prefix = destination.getPrefixLength();
                     InetAddress addrMasked = NetworkUtils.getNetworkPart(address, prefix);
                     InetAddress destMasked = NetworkUtils.getNetworkPart(destination.getAddress(),
                             prefix);
@@ -1871,7 +1871,7 @@
                             mNetd.addRoute(netId, r);
                         }
                         if (exempt) {
-                            LinkAddress dest = r.getDestination();
+                            LinkAddress dest = r.getDestinationLinkAddress();
                             if (!mExemptAddresses.contains(dest)) {
                                 mNetd.setHostExemption(dest);
                                 mExemptAddresses.add(dest);
@@ -1904,7 +1904,7 @@
                             } else {
                                 mNetd.removeRoute(netId, r);
                             }
-                            LinkAddress dest = r.getDestination();
+                            LinkAddress dest = r.getDestinationLinkAddress();
                             if (mExemptAddresses.contains(dest)) {
                                 mNetd.clearHostExemption(dest);
                                 mExemptAddresses.remove(dest);
@@ -2691,7 +2691,7 @@
             dnsDiff = curLp.compareDnses(newLp);
         } else if (newLp != null) {
             routeDiff.added = newLp.getAllRoutes();
-            dnsDiff.added = newLp.getDnses();
+            dnsDiff.added = newLp.getDnsServers();
         }
 
         boolean routesChanged = (routeDiff.removed.size() != 0 || routeDiff.added.size() != 0);
@@ -2915,7 +2915,7 @@
         if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) {
             LinkProperties p = nt.getLinkProperties();
             if (p == null) return;
-            Collection<InetAddress> dnses = p.getDnses();
+            Collection<InetAddress> dnses = p.getDnsServers();
             int netId = nt.getNetwork().netId;
             if (mNetConfigs[netType].isDefault()) {
                 String network = nt.getNetworkInfo().getTypeName();
@@ -5625,7 +5625,7 @@
     }
     private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
         if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
-            Collection<InetAddress> dnses = newLp.getDnses();
+            Collection<InetAddress> dnses = newLp.getDnsServers();
             if (dnses.size() == 0 && mDefaultDns != null) {
                 dnses = new ArrayList();
                 dnses.add(mDefaultDns);
@@ -5790,7 +5790,8 @@
                         isNewDefault = true;
                         updateActiveDefaultNetwork(newNetwork);
                         if (newNetwork.linkProperties != null) {
-                            setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnses());
+                            setDefaultDnsSystemProperties(
+                                    newNetwork.linkProperties.getDnsServers());
                         } else {
                             setDefaultDnsSystemProperties(new ArrayList<InetAddress>());
                         }
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index eefe8da..362061e 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -795,7 +795,7 @@
 
         final Command cmd = new Command("interface", "setcfg", iface,
                 linkAddr.getAddress().getHostAddress(),
-                linkAddr.getNetworkPrefixLength());
+                linkAddr.getPrefixLength());
         for (String flag : cfg.getFlags()) {
             cmd.appendArg(flag);
         }
@@ -882,9 +882,9 @@
         final Command cmd = new Command("network", "route", action, netId);
 
         // create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
-        final LinkAddress la = route.getDestination();
+        final LinkAddress la = route.getDestinationLinkAddress();
         cmd.appendArg(route.getInterface());
-        cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getNetworkPrefixLength());
+        cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getPrefixLength());
         if (route.hasGateway()) {
             cmd.appendArg(route.getGateway().getHostAddress());
         }
@@ -1697,9 +1697,9 @@
     public void setMarkedForwardingRoute(String iface, RouteInfo route) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            LinkAddress dest = route.getDestination();
+            LinkAddress dest = route.getDestinationLinkAddress();
             mConnector.execute("interface", "fwmark", "route", "add", iface,
-                    dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
+                    dest.getAddress().getHostAddress(), dest.getPrefixLength());
         } catch (NativeDaemonConnectorException e) {
             throw e.rethrowAsParcelableException();
         }
@@ -1709,9 +1709,9 @@
     public void clearMarkedForwardingRoute(String iface, RouteInfo route) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            LinkAddress dest = route.getDestination();
+            LinkAddress dest = route.getDestinationLinkAddress();
             mConnector.execute("interface", "fwmark", "route", "remove", iface,
-                    dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
+                    dest.getAddress().getHostAddress(), dest.getPrefixLength());
         } catch (NativeDaemonConnectorException e) {
             throw e.rethrowAsParcelableException();
         }
@@ -1998,9 +1998,9 @@
         final Command cmd = new Command("network", "route", "legacy", uid, action, netId);
 
         // create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
-        final LinkAddress la = routeInfo.getDestination();
+        final LinkAddress la = routeInfo.getDestinationLinkAddress();
         cmd.appendArg(routeInfo.getInterface());
-        cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getNetworkPrefixLength());
+        cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getPrefixLength());
         if (routeInfo.hasGateway()) {
             cmd.appendArg(routeInfo.getGateway().getHostAddress());
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 70327a6..bd1baac 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6030,6 +6030,9 @@
             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
+        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
+            return false;
+        }
 
         if (pi.applicationInfo.uid == uid) {
             return true;
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index b429b93..fe49371 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -906,6 +906,9 @@
             }
             startTime = 0;
             finishLaunchTickingLocked();
+            if (task != null) {
+                task.hasBeenVisible = true;
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 35f8f31..196e860 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -45,6 +45,7 @@
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.IActivityManager.WaitResult;
 import android.app.ResultInfo;
+import android.app.StatusBarManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.IIntentSender;
@@ -73,6 +74,7 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.service.voice.IVoiceInteractionSession;
@@ -88,11 +90,13 @@
 import com.android.internal.app.HeavyWeightSwitcherActivity;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.os.TransferPipe;
+import com.android.internal.statusbar.IStatusBarService;
 import com.android.server.LocalServices;
 import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
 import com.android.server.am.ActivityStack.ActivityState;
 import com.android.server.wm.WindowManagerService;
 
+
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -128,9 +132,15 @@
     static final int HANDLE_DISPLAY_CHANGED = FIRST_SUPERVISOR_STACK_MSG + 6;
     static final int HANDLE_DISPLAY_REMOVED = FIRST_SUPERVISOR_STACK_MSG + 7;
     static final int CONTAINER_CALLBACK_VISIBILITY = FIRST_SUPERVISOR_STACK_MSG + 8;
+    static final int LOCK_TASK_START_MSG = FIRST_SUPERVISOR_STACK_MSG + 9;
+    static final int LOCK_TASK_END_MSG = FIRST_SUPERVISOR_STACK_MSG + 10;
 
     private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
 
+    /** Status Bar Service **/
+    private IBinder mToken = new Binder();
+    private IStatusBarService mStatusBarService;
+
     // For debugging to make sure the caller when acquiring/releasing our
     // wake lock is the system process.
     static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
@@ -253,6 +263,21 @@
         mLaunchingActivity.setReferenceCounted(false);
     }
 
+    // This function returns a IStatusBarService. The value is from ServiceManager.
+    // getService and is cached.
+    private IStatusBarService getStatusBarService() {
+        synchronized (mService) {
+            if (mStatusBarService == null) {
+                mStatusBarService = IStatusBarService.Stub.asInterface(
+                    ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
+                if (mStatusBarService == null) {
+                    Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
+                }
+            }
+            return mStatusBarService;
+        }
+    }
+
     void setWindowManager(WindowManagerService wm) {
         synchronized (mService) {
             mWindowManager = wm;
@@ -2953,9 +2978,12 @@
     }
 
     void setLockTaskModeLocked(TaskRecord task) {
+        final Message lockTaskMsg = Message.obtain();
         if (task == null) {
             // Take out of lock task mode.
             mLockTaskModeTask = null;
+            lockTaskMsg.what = LOCK_TASK_END_MSG;
+            mHandler.sendMessage(lockTaskMsg);
             return;
         }
         if (isLockTaskModeViolation(task)) {
@@ -2965,6 +2993,8 @@
         mLockTaskModeTask = task;
         findTaskToMoveToFrontLocked(task, 0, null);
         resumeTopActivitiesLocked();
+        lockTaskMsg.what = LOCK_TASK_START_MSG;
+        mHandler.sendMessage(lockTaskMsg);
     }
 
     boolean isLockTaskModeViolation(TaskRecord task) {
@@ -3061,6 +3091,32 @@
                     } catch (RemoteException e) {
                     }
                 }
+                case LOCK_TASK_START_MSG: {
+                    // When lock task starts, we disable the status bars.
+                    try {
+                        if (getStatusBarService() != null) {
+                            getStatusBarService().disable
+                                (StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK,
+                                mToken, mService.mContext.getPackageName());
+                        }
+                    } catch (RemoteException ex) {
+                        throw new RuntimeException(ex);
+                    }
+                    break;
+                }
+                case LOCK_TASK_END_MSG: {
+                    // When lock task ends, we enable the status bars.
+                    try {
+                       if (getStatusBarService() != null) {
+                           getStatusBarService().disable
+                               (StatusBarManager.DISABLE_NONE,
+                               mToken, mService.mContext.getPackageName());
+                       }
+                    } catch (RemoteException ex) {
+                        throw new RuntimeException(ex);
+                    }
+                    break;
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 79e2d9d..81a0b36 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -73,6 +73,7 @@
     boolean rootWasReset;   // True if the intent at the root of the task had
                             // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
     boolean askedCompatMode;// Have asked the user about compat mode for this task.
+    boolean hasBeenVisible; // Set if any activities in the task have been visible to the user.
 
     String stringName;      // caching of toString() result.
     int userId;             // user for which this task was created
@@ -328,8 +329,12 @@
     }
 
     boolean autoRemoveFromRecents() {
-        return intent != null &&
-                (intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) != 0;
+        // We will automatically remove the task either if it has explicitly asked for
+        // this, or it is empty and has never contained an activity that got shown to
+        // the user.
+        return (intent != null &&
+                (intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS) != 0) ||
+                (mActivities.isEmpty() && !hasBeenVisible);
     }
 
     /**
@@ -800,7 +805,8 @@
         }
         pw.print(prefix); pw.print("lastThumbnail="); pw.print(lastThumbnail);
                 pw.print(" lastDescription="); pw.println(lastDescription);
-        pw.print(prefix); pw.print("lastActiveTime="); pw.print(lastActiveTime);
+        pw.print(prefix); pw.print("hasBeenVisible="); pw.print(hasBeenVisible);
+                pw.print(" lastActiveTime="); pw.print(lastActiveTime);
                 pw.print(" (inactive for ");
                 pw.print((getInactiveDuration()/1000)); pw.println("s)");
     }
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 92b5f52..bdf4708 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -1344,7 +1344,7 @@
 
                     if (iface != null) {
                         String[] dnsServers = mDefaultDnsServers;
-                        Collection<InetAddress> dnses = linkProperties.getDnses();
+                        Collection<InetAddress> dnses = linkProperties.getDnsServers();
                         if (dnses != null) {
                             // we currently only handle IPv4
                             ArrayList<InetAddress> v4Dnses =
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 835b094..9ae8aed 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -949,6 +949,11 @@
         }
 
         @Override
+        public long getFlags() {
+            return mFlags;
+        }
+
+        @Override
         public void play() throws RemoteException {
             mSessionCb.play();
         }
diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java
index aee7679..907eeb2 100644
--- a/services/core/java/com/android/server/net/IpConfigStore.java
+++ b/services/core/java/com/android/server/net/IpConfigStore.java
@@ -81,15 +81,15 @@
                     for (LinkAddress linkAddr : linkProperties.getLinkAddresses()) {
                         out.writeUTF(LINK_ADDRESS_KEY);
                         out.writeUTF(linkAddr.getAddress().getHostAddress());
-                        out.writeInt(linkAddr.getNetworkPrefixLength());
+                        out.writeInt(linkAddr.getPrefixLength());
                     }
                     for (RouteInfo route : linkProperties.getRoutes()) {
                         out.writeUTF(GATEWAY_KEY);
-                        LinkAddress dest = route.getDestination();
+                        LinkAddress dest = route.getDestinationLinkAddress();
                         if (dest != null) {
                             out.writeInt(1);
                             out.writeUTF(dest.getAddress().getHostAddress());
-                            out.writeInt(dest.getNetworkPrefixLength());
+                            out.writeInt(dest.getPrefixLength());
                         } else {
                             out.writeInt(0);
                         }
@@ -100,7 +100,7 @@
                             out.writeInt(0);
                         }
                     }
-                    for (InetAddress inetAddr : linkProperties.getDnses()) {
+                    for (InetAddress inetAddr : linkProperties.getDnsServers()) {
                         out.writeUTF(DNS_KEY);
                         out.writeUTF(inetAddr.getHostAddress());
                     }
@@ -232,7 +232,7 @@
                             }
                             linkProperties.addRoute(new RouteInfo(dest, gateway));
                         } else if (key.equals(DNS_KEY)) {
-                            linkProperties.addDns(
+                            linkProperties.addDnsServer(
                                     NetworkUtils.numericToInetAddress(in.readUTF()));
                         } else if (key.equals(PROXY_SETTINGS_KEY)) {
                             proxySettings = ProxySettings.valueOf(in.readUTF());
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 50a32c4..b95db9c 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -18,6 +18,7 @@
 
 import android.app.AlarmManager;
 import android.app.AppOpsManager;
+import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -88,6 +89,10 @@
     private static final Set<String> ALARM_PACKAGES = new HashSet<String>(Arrays.asList(
             "com.google.android.deskclock"
             ));
+    private static final Set<String> SYSTEM_PACKAGES = new HashSet<String>(Arrays.asList(
+            "android",
+            "com.android.systemui"
+            ));
 
     public ZenModeHelper(Context context, Handler handler) {
         mContext = context;
@@ -130,6 +135,9 @@
                 // notifications never transition from not intercepted to intercepted
                 return false;
             }
+            if (isSystem(record)) {
+                return false;
+            }
             if (isAlarm(record)) {
                 return false;
             }
@@ -239,6 +247,11 @@
         }
     }
 
+    private boolean isSystem(NotificationRecord record) {
+        return SYSTEM_PACKAGES.contains(record.sbn.getPackageName())
+                && Notification.CATEGORY_SYSTEM.equals(record.getNotification().category);
+    }
+
     private boolean isAlarm(NotificationRecord record) {
         return ALARM_PACKAGES.contains(record.sbn.getPackageName());
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0c094e8..407ecb8 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4988,6 +4988,7 @@
                     mResolveActivity.packageName = mAndroidApplication.packageName;
                     mResolveActivity.processName = "system:ui";
                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+                    mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
                     mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
                     mResolveActivity.exported = true;
@@ -10203,7 +10204,7 @@
         synchronized (mPackages) {
             // Check whether the newly-scanned package wants to define an already-defined perm
             int N = pkg.permissions.size();
-            for (int i = 0; i < N; i++) {
+            for (int i = N-1; i >= 0; i--) {
                 PackageParser.Permission perm = pkg.permissions.get(i);
                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
                 if (bp != null) {
@@ -10211,13 +10212,23 @@
                     // also includes the "updating the same package" case, of course.
                     if (compareSignatures(bp.packageSetting.signatures.mSignatures,
                             pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
-                        Slog.w(TAG, "Package " + pkg.packageName
-                                + " attempting to redeclare permission " + perm.info.name
-                                + " already owned by " + bp.sourcePackage);
-                        res.returnCode = PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
-                        res.origPermission = perm.info.name;
-                        res.origPackage = bp.sourcePackage;
-                        return;
+                        // If the owning package is the system itself, we log but allow
+                        // install to proceed; we fail the install on all other permission
+                        // redefinitions.
+                        if (!bp.sourcePackage.equals("android")) {
+                            Slog.w(TAG, "Package " + pkg.packageName
+                                    + " attempting to redeclare permission " + perm.info.name
+                                    + " already owned by " + bp.sourcePackage);
+                            res.returnCode = PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
+                            res.origPermission = perm.info.name;
+                            res.origPackage = bp.sourcePackage;
+                            return;
+                        } else {
+                            Slog.w(TAG, "Package " + pkg.packageName
+                                    + " attempting to redeclare system permission "
+                                    + perm.info.name + "; ignoring new declaration");
+                            pkg.permissions.remove(i);
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index d8671d9..fb4b8f0 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -409,6 +409,9 @@
     // Current state of the low power mode setting.
     private boolean mLowPowerModeSetting;
 
+    // Current state of whether the settings are allowing auto low power mode.
+    private boolean mAutoLowPowerModeEnabled;
+
     // True if the battery level is currently considered low.
     private boolean mBatteryLevelLow;
 
@@ -558,6 +561,9 @@
             resolver.registerContentObserver(Settings.Global.getUriFor(
                     Settings.Global.LOW_POWER_MODE),
                     false, mSettingsObserver, UserHandle.USER_ALL);
+            resolver.registerContentObserver(Settings.Global.getUriFor(
+                    Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
+                    false, mSettingsObserver, UserHandle.USER_ALL);
             // Go.
             readConfigurationLocked();
             updateSettingsLocked();
@@ -645,8 +651,12 @@
 
         final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
                 Settings.Global.LOW_POWER_MODE, 0) != 0;
-        if (lowPowerModeEnabled != mLowPowerModeSetting) {
+        final boolean autoLowPowerModeEnabled = Settings.Global.getInt(resolver,
+                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 15) != 0;
+        if (lowPowerModeEnabled != mLowPowerModeSetting
+                || autoLowPowerModeEnabled != mAutoLowPowerModeEnabled) {
             mLowPowerModeSetting = lowPowerModeEnabled;
+            mAutoLowPowerModeEnabled = autoLowPowerModeEnabled;
             updateLowPowerModeLocked();
         }
 
@@ -654,7 +664,8 @@
     }
 
     void updateLowPowerModeLocked() {
-        final boolean lowPowerModeEnabled = mLowPowerModeSetting || mBatteryLevelLow;
+        final boolean lowPowerModeEnabled = !mIsPowered
+                && (mLowPowerModeSetting || (mAutoLowPowerModeEnabled && mBatteryLevelLow));
         if (mLowPowerModeEnabled != lowPowerModeEnabled) {
             mLowPowerModeEnabled = lowPowerModeEnabled;
             powerHintInternal(POWER_HINT_LOW_POWER_MODE, lowPowerModeEnabled ? 1 : 0);
@@ -1197,7 +1208,7 @@
                 }
             }
 
-            if (oldLevelLow != mBatteryLevelLow) {
+            if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) {
                 updateLowPowerModeLocked();
             }
         }
@@ -2168,6 +2179,8 @@
             pw.println("  mRequestWaitForNegativeProximity=" + mRequestWaitForNegativeProximity);
             pw.println("  mSandmanScheduled=" + mSandmanScheduled);
             pw.println("  mSandmanSummoned=" + mSandmanSummoned);
+            pw.println("  mLowPowerModeEnabled=" + mLowPowerModeEnabled);
+            pw.println("  mBatteryLevelLow=" + mBatteryLevelLow);
             pw.println("  mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
             pw.println("  mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
             pw.println("  mLastUserActivityTime=" + TimeUtils.formatUptime(mLastUserActivityTime));
@@ -2204,6 +2217,8 @@
             pw.println("  mDreamsEnabledSetting=" + mDreamsEnabledSetting);
             pw.println("  mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
             pw.println("  mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
+            pw.println("  mLowPowerModeSetting=" + mLowPowerModeSetting);
+            pw.println("  mAutoLowPowerModeEnabled=" + mAutoLowPowerModeEnabled);
             pw.println("  mMinimumScreenOffTimeoutConfig=" + mMinimumScreenOffTimeoutConfig);
             pw.println("  mMaximumScreenDimDurationConfig=" + mMaximumScreenDimDurationConfig);
             pw.println("  mMaximumScreenDimRatioConfig=" + mMaximumScreenDimRatioConfig);